diff options
author | Reid Kleckner <rnk@google.com> | 2017-04-13 00:58:09 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2017-04-13 00:58:09 +0000 |
commit | 7f72033e1cde7a3a76da8c79634dfb7bf4919b54 (patch) | |
tree | 91cd8b6c041464464cf122c8b204588149e44536 /llvm/lib/Transforms | |
parent | 4104cf8257717c068622383441ee37bacaa1b74a (diff) | |
download | bcm5719-llvm-7f72033e1cde7a3a76da8c79634dfb7bf4919b54.tar.gz bcm5719-llvm-7f72033e1cde7a3a76da8c79634dfb7bf4919b54.zip |
[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.
llvm-svn: 300153
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 67 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp | 35 | ||||
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CloneFunction.cpp | 17 |
4 files changed, 55 insertions, 82 deletions
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index c43557b4e1a..00235d46dc5 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -102,11 +102,8 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, // 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<Argument *> &ArgsToPromote, 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<Argument *> &ArgsToPromote, 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<Argument *> &ArgsToPromote, } } - // 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<Argument *> &ArgsToPromote, // 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<Argument *> &ArgsToPromote, 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<Argument *> &ArgsToPromote, ++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<Argument *> &ArgsToPromote, 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<Argument *> &ArgsToPromote, 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 diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp index 66eb33f246a..2fd0b567705 100644 --- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -685,13 +685,9 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) { 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::RemoveDeadStuffFromFunction(Function *F) { 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::RemoveDeadStuffFromFunction(Function *F) { 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::RemoveDeadStuffFromFunction(Function *F) { 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::RemoveDeadStuffFromFunction(Function *F) { // 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); diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index cdae9571851..814f5933a58 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -4232,16 +4232,13 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS, 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::transformCallThroughTrampoline(CallSite CS, 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::transformCallThroughTrampoline(CallSite CS, // 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::transformCallThroughTrampoline(CallSite CS, 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); diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp index ae58d6133d9..05770268a0a 100644 --- a/llvm/lib/Transforms/Utils/CloneFunction.cpp +++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp @@ -103,23 +103,20 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc, 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); |