[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