[llvm] r300153 - [IR] Take func, ret, and arg attrs separately in AttributeList::get

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 12 17:58:10 PDT 2017


Author: rnk
Date: Wed Apr 12 19:58:09 2017
New Revision: 300153

URL: http://llvm.org/viewvc/llvm-project?rev=300153&view=rev
Log:
[IR] Take func, ret, and arg attrs separately in AttributeList::get

This seems like a much more natural API, based on Derek Schuff's
comments on r300015. It further hides the implementation detail of
AttributeList that function attributes come last and appear at index
~0U, which is easy for the user to screw up. git diff says it saves code
as well: 97 insertions(+), 137 deletions(-)

This also makes it easier to change the implementation, which I want to
do next.

Modified:
    llvm/trunk/include/llvm/IR/Attributes.h
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/IR/Attributes.cpp
    llvm/trunk/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
    llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
    llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp

Modified: llvm/trunk/include/llvm/IR/Attributes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Attributes.h?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Attributes.h (original)
+++ llvm/trunk/include/llvm/IR/Attributes.h Wed Apr 12 19:58:09 2017
@@ -307,13 +307,11 @@ public:
   static AttributeList
   get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
 
-  /// \brief Create an AttributeList from a vector of AttributeSetNodes. The
-  /// index of each set is implied by its position in the array \p Attrs:
-  ///   0      : Return attributes
-  /// 1 to n-1 : Argument attributes
-  ///   n      : Function attributes
-  /// Any element that has no entries should be left null.
-  static AttributeList get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
+  /// \brief Create an AttributeList from attribute sets for a function, its
+  /// return value, and all of its arguments.
+  static AttributeList get(LLVMContext &C, AttributeSet FnAttrs,
+                           AttributeSet RetAttrs,
+                           ArrayRef<AttributeSet> ArgAttrs);
 
   static AttributeList
   getImpl(LLVMContext &C,

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Wed Apr 12 19:58:09 2017
@@ -4764,16 +4764,14 @@ bool LLParser::ParseFunctionHeader(Funct
   std::vector<Type*> ParamTypeList;
   SmallVector<AttributeSet, 8> Attrs;
 
-  Attrs.push_back(AttributeSet::get(Context, RetAttrs));
-
   for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
     ParamTypeList.push_back(ArgList[i].Ty);
     Attrs.push_back(ArgList[i].Attrs);
   }
 
-  Attrs.push_back(AttributeSet::get(Context, FuncAttrs));
-
-  AttributeList PAL = AttributeList::get(Context, Attrs);
+  AttributeList PAL =
+      AttributeList::get(Context, AttributeSet::get(Context, FuncAttrs),
+                         AttributeSet::get(Context, RetAttrs), Attrs);
 
   if (PAL.hasAttribute(1, Attribute::StructRet) && !RetType->isVoidTy())
     return Error(RetTypeLoc, "functions with 'sret' argument must return void");
@@ -5383,10 +5381,8 @@ bool LLParser::ParseInvoke(Instruction *
     return true;
 
   // Set up the Attribute for the function.
-  SmallVector<AttributeSet, 8> Attrs;
-  Attrs.push_back(AttributeSet::get(Context, RetAttrs));
-
-  SmallVector<Value*, 8> Args;
+  SmallVector<Value *, 8> Args;
+  SmallVector<AttributeSet, 8> ArgAttrs;
 
   // Loop through FunctionType's arguments and ensure they are specified
   // correctly.  Also, gather any parameter attributes.
@@ -5404,7 +5400,7 @@ bool LLParser::ParseInvoke(Instruction *
       return Error(ArgList[i].Loc, "argument is not of expected type '" +
                    getTypeString(ExpectedTy) + "'");
     Args.push_back(ArgList[i].V);
-    Attrs.push_back(ArgList[i].Attrs);
+    ArgAttrs.push_back(ArgList[i].Attrs);
   }
 
   if (I != E)
@@ -5413,10 +5409,10 @@ bool LLParser::ParseInvoke(Instruction *
   if (FnAttrs.hasAlignmentAttr())
     return Error(CallLoc, "invoke instructions may not have an alignment");
 
-  Attrs.push_back(AttributeSet::get(Context, FnAttrs));
-
   // Finish off the Attribute and check them
-  AttributeList PAL = AttributeList::get(Context, Attrs);
+  AttributeList PAL =
+      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs),
+                         AttributeSet::get(Context, RetAttrs), ArgAttrs);
 
   InvokeInst *II =
       InvokeInst::Create(Ty, Callee, NormalBB, UnwindBB, Args, BundleList);
@@ -5978,7 +5974,6 @@ bool LLParser::ParseCall(Instruction *&I
 
   // Set up the Attribute for the function.
   SmallVector<AttributeSet, 8> Attrs;
-  Attrs.push_back(AttributeSet::get(Context, RetAttrs));
 
   SmallVector<Value*, 8> Args;
 
@@ -6007,10 +6002,10 @@ bool LLParser::ParseCall(Instruction *&I
   if (FnAttrs.hasAlignmentAttr())
     return Error(CallLoc, "call instructions may not have an alignment");
 
-  Attrs.push_back(AttributeSet::get(Context, FnAttrs));
-
   // Finish off the Attribute and check them
-  AttributeList PAL = AttributeList::get(Context, Attrs);
+  AttributeList PAL =
+      AttributeList::get(Context, AttributeSet::get(Context, FnAttrs),
+                         AttributeSet::get(Context, RetAttrs), Attrs);
 
   CallInst *CI = CallInst::Create(Ty, Callee, Args, BundleList);
   CI->setTailCallKind(TCK);

Modified: llvm/trunk/lib/IR/Attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Attributes.cpp?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Attributes.cpp (original)
+++ llvm/trunk/lib/IR/Attributes.cpp Wed Apr 12 19:58:09 2017
@@ -778,7 +778,7 @@ AttributeList AttributeList::getImpl(
 #ifndef NDEBUG
   unsigned LastIndex = 0;
   bool IsFirst = true;
-  for (const auto &AttrPair : Attrs) {
+  for (auto &&AttrPair : Attrs) {
     assert((IsFirst || LastIndex < AttrPair.first) &&
            "unsorted or duplicate AttributeList indices");
     assert(AttrPair.second.hasAttributes() && "pointless AttributeList slot");
@@ -855,20 +855,20 @@ AttributeList::get(LLVMContext &C,
   return getImpl(C, Attrs);
 }
 
-AttributeList AttributeList::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
-  assert(Attrs.size() >= 2 &&
-         "should always have function and return attr slots");
+AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
+                                 AttributeSet RetAttrs,
+                                 ArrayRef<AttributeSet> ArgAttrs) {
   SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairs;
-  size_t Index = 0;
-  for (AttributeSet AS : Attrs) {
-    if (AS.hasAttributes()) {
-      // If this is the last AttributeSetNode, it's for the function.
-      if (Index == Attrs.size() - 1)
-        Index = AttributeList::FunctionIndex;
+  if (RetAttrs.hasAttributes())
+    AttrPairs.emplace_back(ReturnIndex, RetAttrs);
+  size_t Index = 1;
+  for (AttributeSet AS : ArgAttrs) {
+    if (AS.hasAttributes())
       AttrPairs.emplace_back(Index, AS);
-    }
     ++Index;
   }
+  if (FnAttrs.hasAttributes())
+    AttrPairs.emplace_back(FunctionIndex, FnAttrs);
   if (AttrPairs.empty())
     return AttributeList();
   return getImpl(C, AttrPairs);

Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyLowerEmscriptenEHSjLj.cpp Wed Apr 12 19:58:09 2017
@@ -435,22 +435,20 @@ Value *WebAssemblyLowerEmscriptenEHSjLj:
 
   // Because we added the pointer to the callee as first argument, all
   // argument attribute indices have to be incremented by one.
-  SmallVector<AttributeSet, 8> AttributesVec;
+  SmallVector<AttributeSet, 8> ArgAttributes;
   const AttributeList &InvokeAL = CI->getAttributes();
 
-  // Add any return attributes.
-  AttributesVec.push_back(InvokeAL.getRetAttributes());
   // No attributes for the callee pointer.
-  AttributesVec.push_back(AttributeSet());
+  ArgAttributes.push_back(AttributeSet());
   // Copy the argument attributes from the original
   for (unsigned i = 1, e = CI->getNumArgOperands(); i <= e; ++i) {
-    AttributesVec.push_back(InvokeAL.getParamAttributes(i));
+    ArgAttributes.push_back(InvokeAL.getParamAttributes(i));
   }
 
-  // Add any function attributes.
-  AttributesVec.push_back(InvokeAL.getFnAttributes());
   // Reconstruct the AttributesList based on the vector we constructed.
-  AttributeList NewCallAL = AttributeList::get(C, AttributesVec);
+  AttributeList NewCallAL =
+      AttributeList::get(C, InvokeAL.getFnAttributes(),
+                         InvokeAL.getRetAttributes(), ArgAttributes);
   NewCall->setAttributes(NewCallAL);
 
   CI->replaceAllUsesWith(NewCall);

Modified: llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ArgumentPromotion.cpp Wed Apr 12 19:58:09 2017
@@ -102,11 +102,8 @@ doPromotion(Function *F, SmallPtrSetImpl
   // Attribute - Keep track of the parameter attributes for the arguments
   // that we are *not* promoting. For the ones that we do promote, the parameter
   // attributes are lost
-  SmallVector<AttributeSet, 8> AttributesVec;
-  const AttributeList &PAL = F->getAttributes();
-
-  // Add any return attributes.
-  AttributesVec.push_back(PAL.getRetAttributes());
+  SmallVector<AttributeSet, 8> ArgAttrVec;
+  AttributeList PAL = F->getAttributes();
 
   // First, determine the new argument list
   unsigned ArgIndex = 1;
@@ -117,13 +114,13 @@ doPromotion(Function *F, SmallPtrSetImpl
       Type *AgTy = cast<PointerType>(I->getType())->getElementType();
       StructType *STy = cast<StructType>(AgTy);
       Params.insert(Params.end(), STy->element_begin(), STy->element_end());
-      AttributesVec.insert(AttributesVec.end(), STy->getNumElements(),
-                           AttributeSet());
+      ArgAttrVec.insert(ArgAttrVec.end(), STy->getNumElements(),
+                        AttributeSet());
       ++NumByValArgsPromoted;
     } else if (!ArgsToPromote.count(&*I)) {
       // Unchanged argument
       Params.push_back(I->getType());
-      AttributesVec.push_back(PAL.getParamAttributes(ArgIndex));
+      ArgAttrVec.push_back(PAL.getParamAttributes(ArgIndex));
     } else if (I->use_empty()) {
       // Dead argument (which are always marked as promotable)
       ++NumArgumentsDead;
@@ -168,7 +165,7 @@ doPromotion(Function *F, SmallPtrSetImpl
         Params.push_back(GetElementPtrInst::getIndexedType(
             cast<PointerType>(I->getType()->getScalarType())->getElementType(),
             ArgIndex.second));
-        AttributesVec.push_back(AttributeSet());
+        ArgAttrVec.push_back(AttributeSet());
         assert(Params.back());
       }
 
@@ -179,9 +176,6 @@ doPromotion(Function *F, SmallPtrSetImpl
     }
   }
 
-  // Add any function attributes.
-  AttributesVec.push_back(PAL.getFnAttributes());
-
   Type *RetTy = FTy->getReturnType();
 
   // Construct the new function type using the new arguments.
@@ -200,8 +194,9 @@ doPromotion(Function *F, SmallPtrSetImpl
 
   // Recompute the parameter attributes list based on the new arguments for
   // the function.
-  NF->setAttributes(AttributeList::get(F->getContext(), AttributesVec));
-  AttributesVec.clear();
+  NF->setAttributes(AttributeList::get(F->getContext(), PAL.getFnAttributes(),
+                                       PAL.getRetAttributes(), ArgAttrVec));
+  ArgAttrVec.clear();
 
   F->getParent()->getFunctionList().insert(F->getIterator(), NF);
   NF->takeName(F);
@@ -216,9 +211,6 @@ doPromotion(Function *F, SmallPtrSetImpl
     Instruction *Call = CS.getInstruction();
     const AttributeList &CallPAL = CS.getAttributes();
 
-    // Add any return attributes.
-    AttributesVec.push_back(CallPAL.getRetAttributes());
-
     // Loop over the operands, inserting GEP and loads in the caller as
     // appropriate.
     CallSite::arg_iterator AI = CS.arg_begin();
@@ -227,7 +219,7 @@ doPromotion(Function *F, SmallPtrSetImpl
          ++I, ++AI, ++ArgIndex)
       if (!ArgsToPromote.count(&*I) && !ByValArgsToTransform.count(&*I)) {
         Args.push_back(*AI); // Unmodified argument
-        AttributesVec.push_back(CallPAL.getAttributes(ArgIndex));
+        ArgAttrVec.push_back(CallPAL.getAttributes(ArgIndex));
       } else if (ByValArgsToTransform.count(&*I)) {
         // Emit a GEP and load for each element of the struct.
         Type *AgTy = cast<PointerType>(I->getType())->getElementType();
@@ -240,7 +232,7 @@ doPromotion(Function *F, SmallPtrSetImpl
               STy, *AI, Idxs, (*AI)->getName() + "." + Twine(i), Call);
           // TODO: Tell AA about the new values?
           Args.push_back(new LoadInst(Idx, Idx->getName() + ".val", Call));
-          AttributesVec.push_back(AttributeSet());
+          ArgAttrVec.push_back(AttributeSet());
         }
       } else if (!I->use_empty()) {
         // Non-dead argument: insert GEPs and loads as appropriate.
@@ -283,48 +275,43 @@ doPromotion(Function *F, SmallPtrSetImpl
           newLoad->setAAMetadata(AAInfo);
 
           Args.push_back(newLoad);
-          AttributesVec.push_back(AttributeSet());
+          ArgAttrVec.push_back(AttributeSet());
         }
       }
 
     // Push any varargs arguments on the list.
     for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
       Args.push_back(*AI);
-      AttributesVec.push_back(CallPAL.getAttributes(ArgIndex));
+      ArgAttrVec.push_back(CallPAL.getAttributes(ArgIndex));
     }
 
-    // Add any function attributes.
-    AttributesVec.push_back(CallPAL.getFnAttributes());
-
     SmallVector<OperandBundleDef, 1> OpBundles;
     CS.getOperandBundlesAsDefs(OpBundles);
 
-    Instruction *New;
+    CallSite NewCS;
     if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
-      New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
+      NewCS = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
                                Args, OpBundles, "", Call);
-      cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
-      cast<InvokeInst>(New)->setAttributes(
-          AttributeList::get(II->getContext(), AttributesVec));
     } else {
-      New = CallInst::Create(NF, Args, OpBundles, "", Call);
-      cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
-      cast<CallInst>(New)->setAttributes(
-          AttributeList::get(New->getContext(), AttributesVec));
-      cast<CallInst>(New)->setTailCallKind(
-          cast<CallInst>(Call)->getTailCallKind());
+      auto *NewCall = CallInst::Create(NF, Args, OpBundles, "", Call);
+      NewCall->setTailCallKind(cast<CallInst>(Call)->getTailCallKind());
+      NewCS = NewCall;
     }
-    New->setDebugLoc(Call->getDebugLoc());
+    NewCS.setCallingConv(CS.getCallingConv());
+    NewCS.setAttributes(
+        AttributeList::get(F->getContext(), CallPAL.getFnAttributes(),
+                           CallPAL.getRetAttributes(), ArgAttrVec));
+    NewCS->setDebugLoc(Call->getDebugLoc());
     Args.clear();
-    AttributesVec.clear();
+    ArgAttrVec.clear();
 
     // Update the callgraph to know that the callsite has been transformed.
     if (ReplaceCallSite)
-      (*ReplaceCallSite)(CS, CallSite(New));
+      (*ReplaceCallSite)(CS, NewCS);
 
     if (!Call->use_empty()) {
-      Call->replaceAllUsesWith(New);
-      New->takeName(Call);
+      Call->replaceAllUsesWith(NewCS.getInstruction());
+      NewCS->takeName(Call);
     }
 
     // Finally, remove the old call from the program, reducing the use-count of

Modified: llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/DeadArgumentElimination.cpp Wed Apr 12 19:58:09 2017
@@ -685,13 +685,9 @@ bool DeadArgumentEliminationPass::Remove
   bool HasLiveReturnedArg = false;
 
   // Set up to build a new list of parameter attributes.
-  SmallVector<AttributeSet, 8> AttributesVec;
+  SmallVector<AttributeSet, 8> ArgAttrVec;
   const AttributeList &PAL = F->getAttributes();
 
-  // Reserve an empty slot for the return value attributes, which we will
-  // compute last.
-  AttributesVec.push_back(AttributeSet());
-
   // Remember which arguments are still alive.
   SmallVector<bool, 10> ArgAlive(FTy->getNumParams(), false);
   // Construct the new parameter list from non-dead arguments. Also construct
@@ -704,7 +700,7 @@ bool DeadArgumentEliminationPass::Remove
     if (LiveValues.erase(Arg)) {
       Params.push_back(I->getType());
       ArgAlive[i] = true;
-      AttributesVec.push_back(PAL.getParamAttributes(i + 1));
+      ArgAttrVec.push_back(PAL.getParamAttributes(i + 1));
       HasLiveReturnedArg |= PAL.hasAttribute(i + 1, Attribute::Returned);
     } else {
       ++NumArgumentsEliminated;
@@ -791,14 +787,12 @@ bool DeadArgumentEliminationPass::Remove
     assert(!RAttrs.overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
            "Return attributes no longer compatible?");
 
-  AttributesVec[0] = AttributeSet::get(F->getContext(), RAttrs);
-
-  // Transfer the function attributes, if any.
-  AttributesVec.push_back(PAL.getFnAttributes());
+  AttributeSet RetAttrs = AttributeSet::get(F->getContext(), RAttrs);
 
   // Reconstruct the AttributesList based on the vector we constructed.
-  assert(AttributesVec.size() == Params.size() + 2);
-  AttributeList NewPAL = AttributeList::get(F->getContext(), AttributesVec);
+  assert(ArgAttrVec.size() == Params.size());
+  AttributeList NewPAL = AttributeList::get(
+      F->getContext(), PAL.getFnAttributes(), RetAttrs, ArgAttrVec);
 
   // Create the new function type based on the recomputed parameters.
   FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg());
@@ -825,14 +819,14 @@ bool DeadArgumentEliminationPass::Remove
     CallSite CS(F->user_back());
     Instruction *Call = CS.getInstruction();
 
-    AttributesVec.clear();
+    ArgAttrVec.clear();
     const AttributeList &CallPAL = CS.getAttributes();
 
     // Adjust the call return attributes in case the function was changed to
     // return void.
     AttrBuilder RAttrs(CallPAL.getRetAttributes());
     RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
-    AttributesVec.push_back(AttributeSet::get(F->getContext(), RAttrs));
+    AttributeSet RetAttrs = AttributeSet::get(F->getContext(), RAttrs);
 
     // Declare these outside of the loops, so we can reuse them for the second
     // loop, which loops the varargs.
@@ -851,26 +845,25 @@ bool DeadArgumentEliminationPass::Remove
           // call sites keep the return value alive just like 'returned'
           // attributes on function declaration but it's less clearly a win and
           // this is not an expected case anyway
-          AttributesVec.push_back(AttributeSet::get(
+          ArgAttrVec.push_back(AttributeSet::get(
               F->getContext(),
               AttrBuilder(Attrs).removeAttribute(Attribute::Returned)));
         } else {
           // Otherwise, use the original attributes.
-          AttributesVec.push_back(Attrs);
+          ArgAttrVec.push_back(Attrs);
         }
       }
 
     // Push any varargs arguments on the list. Don't forget their attributes.
     for (CallSite::arg_iterator E = CS.arg_end(); I != E; ++I, ++i) {
       Args.push_back(*I);
-      AttributesVec.push_back(CallPAL.getParamAttributes(i + 1));
+      ArgAttrVec.push_back(CallPAL.getParamAttributes(i + 1));
     }
 
-    AttributesVec.push_back(CallPAL.getFnAttributes());
-
     // Reconstruct the AttributesList based on the vector we constructed.
-    AttributeList NewCallPAL =
-        AttributeList::get(F->getContext(), AttributesVec);
+    assert(ArgAttrVec.size() == Args.size());
+    AttributeList NewCallPAL = AttributeList::get(
+        F->getContext(), CallPAL.getFnAttributes(), RetAttrs, ArgAttrVec);
 
     SmallVector<OperandBundleDef, 1> OpBundles;
     CS.getOperandBundlesAsDefs(OpBundles);

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Wed Apr 12 19:58:09 2017
@@ -4232,16 +4232,13 @@ InstCombiner::transformCallThroughTrampo
     if (NestTy) {
       Instruction *Caller = CS.getInstruction();
       std::vector<Value*> NewArgs;
-      std::vector<AttributeSet> NewAttrs;
+      std::vector<AttributeSet> NewArgAttrs;
       NewArgs.reserve(CS.arg_size() + 1);
-      NewAttrs.reserve(CS.arg_size() + 2);
+      NewArgAttrs.reserve(CS.arg_size());
 
       // Insert the nest argument into the call argument list, which may
       // mean appending it.  Likewise for attributes.
 
-      // Add any result attributes.
-      NewAttrs.push_back(Attrs.getRetAttributes());
-
       {
         unsigned Idx = 1;
         CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
@@ -4252,7 +4249,7 @@ InstCombiner::transformCallThroughTrampo
             if (NestVal->getType() != NestTy)
               NestVal = Builder->CreateBitCast(NestVal, NestTy, "nest");
             NewArgs.push_back(NestVal);
-            NewAttrs.push_back(NestAttr);
+            NewArgAttrs.push_back(NestAttr);
           }
 
           if (I == E)
@@ -4260,16 +4257,13 @@ InstCombiner::transformCallThroughTrampo
 
           // Add the original argument and attributes.
           NewArgs.push_back(*I);
-          NewAttrs.push_back(Attrs.getParamAttributes(Idx));
+          NewArgAttrs.push_back(Attrs.getParamAttributes(Idx));
 
           ++Idx;
           ++I;
         } while (true);
       }
 
-      // Add any function attributes.
-      NewAttrs.push_back(Attrs.getFnAttributes());
-
       // The trampoline may have been bitcast to a bogus type (FTy).
       // Handle this by synthesizing a new function type, equal to FTy
       // with the chain parameter inserted.
@@ -4308,7 +4302,9 @@ InstCombiner::transformCallThroughTrampo
         NestF->getType() == PointerType::getUnqual(NewFTy) ?
         NestF : ConstantExpr::getBitCast(NestF,
                                          PointerType::getUnqual(NewFTy));
-      AttributeList NewPAL = AttributeList::get(FTy->getContext(), NewAttrs);
+      AttributeList NewPAL =
+          AttributeList::get(FTy->getContext(), Attrs.getFnAttributes(),
+                             Attrs.getRetAttributes(), NewArgAttrs);
 
       SmallVector<OperandBundleDef, 1> OpBundles;
       CS.getOperandBundlesAsDefs(OpBundles);

Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=300153&r1=300152&r2=300153&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Wed Apr 12 19:58:09 2017
@@ -103,23 +103,20 @@ void llvm::CloneFunctionInto(Function *N
                  ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
                  TypeMapper, Materializer));
 
-  SmallVector<AttributeSet, 4> AttrVec(NewFunc->arg_size() + 2);
+  SmallVector<AttributeSet, 4> NewArgAttrs(NewFunc->arg_size());
   AttributeList OldAttrs = OldFunc->getAttributes();
 
-  // Copy the return attributes.
-  AttrVec[0] = OldAttrs.getRetAttributes();
-
   // Clone any argument attributes that are present in the VMap.
-  for (const Argument &OldArg : OldFunc->args())
+  for (const Argument &OldArg : OldFunc->args()) {
     if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
-      AttrVec[NewArg->getArgNo() + 1] =
+      NewArgAttrs[NewArg->getArgNo()] =
           OldAttrs.getParamAttributes(OldArg.getArgNo() + 1);
     }
+  }
 
-  // Copy any function attributes.
-  AttrVec.back() = OldAttrs.getFnAttributes();
-
-  NewFunc->setAttributes(AttributeList::get(NewFunc->getContext(), AttrVec));
+  NewFunc->setAttributes(
+      AttributeList::get(NewFunc->getContext(), OldAttrs.getFnAttributes(),
+                         OldAttrs.getRetAttributes(), NewArgAttrs));
 
   SmallVector<std::pair<unsigned, MDNode *>, 1> MDs;
   OldFunc->getAllMetadata(MDs);




More information about the llvm-commits mailing list