From 08a8f5df9be6f73f4af6b818646138a4789a8c19 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Sun, 4 Nov 2012 14:25:50 +0100 Subject: [PATCH] Fixed LLVM function attribute handling. Previously, set_param_attrs would overwrite any pre-existing attributes, which is problematic, as per-function attributes are also stored in a slot in that attribute list. This for example lead to "noinline" being dropped for functions with inline asm. --- gen/functions.cpp | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/gen/functions.cpp b/gen/functions.cpp index 40d74746..269fd87f 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -426,7 +426,6 @@ void DtoResolveFunction(FuncDeclaration* fdecl) static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl) { LLSmallVector attrs; - llvm::AttributeWithIndex PAWI; int idx = 0; @@ -434,9 +433,7 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati #define ADD_PA(X) \ if (f->fty.X) { \ if (HAS_ATTRIBUTES(f->fty.X->attrs)) { \ - PAWI.Index = idx; \ - PAWI.Attrs = f->fty.X->attrs; \ - attrs.push_back(PAWI); \ + attrs.push_back(llvm::AttributeWithIndex::get(idx, f->fty.X->attrs)); \ } \ idx++; \ } @@ -477,9 +474,29 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati { if (HAS_ATTRIBUTES(attrptr[i])) { - PAWI.Index = idx+i; - PAWI.Attrs = attrptr[i]; - attrs.push_back(PAWI); + attrs.push_back(llvm::AttributeWithIndex::get(idx + i, attrptr[i])); + } + } + + // Merge in any old attributes (attributes for the function itself are + // also stored in a list slot). + const size_t newSize = attrs.size(); + llvm::AttrListPtr oldAttrs = func->getAttributes(); + for (size_t i = 0; i < oldAttrs.getNumSlots(); ++i) { + llvm::AttributeWithIndex curr = oldAttrs.getSlot(i); + + bool found = false; + for (size_t j = 0; j < newSize; ++j) { + if (attrs[j].Index == curr.Index) { + // TODO: LLVM 3.2. + attrs[j].Attrs |= curr.Attrs; + found = true; + break; + } + } + + if (!found) { + attrs.push_back(curr); } }