diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO/ArgumentPromotion.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 136 |
1 files changed, 66 insertions, 70 deletions
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index cdf8a2eb598ee..ad0d7eb51507a 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -36,7 +36,6 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" @@ -53,7 +52,6 @@ #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" @@ -74,6 +72,7 @@ #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO.h" #include <algorithm> @@ -105,7 +104,7 @@ using IndicesVector = std::vector<uint64_t>; static Function * doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, SmallPtrSetImpl<Argument *> &ByValArgsToTransform, - Optional<function_ref<void(CallSite OldCS, CallSite NewCS)>> + Optional<function_ref<void(CallBase &OldCS, CallBase &NewCS)>> ReplaceCallSite) { // Start by computing a new prototype for the function, which is the same as // the old function, but has modified arguments. @@ -197,7 +196,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, for (const auto &ArgIndex : ArgIndices) { // not allowed to dereference ->begin() if size() is 0 Params.push_back(GetElementPtrInst::getIndexedType( - cast<PointerType>(I->getType()->getScalarType())->getElementType(), + cast<PointerType>(I->getType())->getElementType(), ArgIndex.second)); ArgAttrVec.push_back(AttributeSet()); assert(Params.back()); @@ -241,15 +240,14 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, // SmallVector<Value *, 16> Args; while (!F->use_empty()) { - CallSite CS(F->user_back()); - assert(CS.getCalledFunction() == F); - Instruction *Call = CS.getInstruction(); - const AttributeList &CallPAL = CS.getAttributes(); - IRBuilder<NoFolder> IRB(Call); + CallBase &CB = cast<CallBase>(*F->user_back()); + assert(CB.getCalledFunction() == F); + const AttributeList &CallPAL = CB.getAttributes(); + IRBuilder<NoFolder> IRB(&CB); // Loop over the operands, inserting GEP and loads in the caller as // appropriate. - CallSite::arg_iterator AI = CS.arg_begin(); + auto AI = CB.arg_begin(); ArgNo = 0; for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I, ++AI, ++ArgNo) @@ -295,7 +293,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, if (auto *ElPTy = dyn_cast<PointerType>(ElTy)) ElTy = ElPTy->getElementType(); else - ElTy = cast<CompositeType>(ElTy)->getTypeAtIndex(II); + ElTy = GetElementPtrInst::getTypeAtIndex(ElTy, II); } // And create a GEP to extract those indices. V = IRB.CreateGEP(ArgIndex.first, V, Ops, V->getName() + ".idx"); @@ -305,7 +303,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, // of the previous load. LoadInst *newLoad = IRB.CreateLoad(OrigLoad->getType(), V, V->getName() + ".val"); - newLoad->setAlignment(MaybeAlign(OrigLoad->getAlignment())); + newLoad->setAlignment(OrigLoad->getAlign()); // Transfer the AA info too. AAMDNodes AAInfo; OrigLoad->getAAMetadata(AAInfo); @@ -317,46 +315,43 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, } // Push any varargs arguments on the list. - for (; AI != CS.arg_end(); ++AI, ++ArgNo) { + for (; AI != CB.arg_end(); ++AI, ++ArgNo) { Args.push_back(*AI); ArgAttrVec.push_back(CallPAL.getParamAttributes(ArgNo)); } SmallVector<OperandBundleDef, 1> OpBundles; - CS.getOperandBundlesAsDefs(OpBundles); + CB.getOperandBundlesAsDefs(OpBundles); - CallSite NewCS; - if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) { + CallBase *NewCS = nullptr; + if (InvokeInst *II = dyn_cast<InvokeInst>(&CB)) { NewCS = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), - Args, OpBundles, "", Call); + Args, OpBundles, "", &CB); } else { - auto *NewCall = CallInst::Create(NF, Args, OpBundles, "", Call); - NewCall->setTailCallKind(cast<CallInst>(Call)->getTailCallKind()); + auto *NewCall = CallInst::Create(NF, Args, OpBundles, "", &CB); + NewCall->setTailCallKind(cast<CallInst>(&CB)->getTailCallKind()); NewCS = NewCall; } - NewCS.setCallingConv(CS.getCallingConv()); - NewCS.setAttributes( + NewCS->setCallingConv(CB.getCallingConv()); + NewCS->setAttributes( AttributeList::get(F->getContext(), CallPAL.getFnAttributes(), CallPAL.getRetAttributes(), ArgAttrVec)); - NewCS->setDebugLoc(Call->getDebugLoc()); - uint64_t W; - if (Call->extractProfTotalWeight(W)) - NewCS->setProfWeight(W); + NewCS->copyMetadata(CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg}); Args.clear(); ArgAttrVec.clear(); // Update the callgraph to know that the callsite has been transformed. if (ReplaceCallSite) - (*ReplaceCallSite)(CS, NewCS); + (*ReplaceCallSite)(CB, *NewCS); - if (!Call->use_empty()) { - Call->replaceAllUsesWith(NewCS.getInstruction()); - NewCS->takeName(Call); + if (!CB.use_empty()) { + CB.replaceAllUsesWith(NewCS); + NewCS->takeName(&CB); } // Finally, remove the old call from the program, reducing the use-count of // F. - Call->eraseFromParent(); + CB.eraseFromParent(); } const DataLayout &DL = F->getParent()->getDataLayout(); @@ -387,9 +382,10 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, // Just add all the struct element types. Type *AgTy = cast<PointerType>(I->getType())->getElementType(); - Value *TheAlloca = - new AllocaInst(AgTy, DL.getAllocaAddrSpace(), nullptr, - MaybeAlign(I->getParamAlignment()), "", InsertPt); + Value *TheAlloca = new AllocaInst( + AgTy, DL.getAllocaAddrSpace(), nullptr, + I->getParamAlign().getValueOr(DL.getPrefTypeAlign(AgTy)), "", + InsertPt); StructType *STy = cast<StructType>(AgTy); Value *Idxs[2] = {ConstantInt::get(Type::getInt32Ty(F->getContext()), 0), nullptr}; @@ -453,12 +449,8 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote, assert(It != ArgIndices.end() && "GEP not handled??"); } - std::string NewName = I->getName(); - for (unsigned i = 0, e = Operands.size(); i != e; ++i) { - NewName += "." + utostr(Operands[i]); - } - NewName += ".val"; - TheArg->setName(NewName); + TheArg->setName(formatv("{0}.{1:$[.]}.val", I->getName(), + make_range(Operands.begin(), Operands.end()))); LLVM_DEBUG(dbgs() << "*** Promoted agg argument '" << TheArg->getName() << "' of function '" << NF->getName() << "'\n"); @@ -492,10 +484,9 @@ static bool allCallersPassValidPointerForArgument(Argument *Arg, Type *Ty) { // Look at all call sites of the function. At this point we know we only have // direct callees. for (User *U : Callee->users()) { - CallSite CS(U); - assert(CS && "Should only have direct calls!"); + CallBase &CB = cast<CallBase>(*U); - if (!isDereferenceablePointer(CS.getArgument(ArgNo), Ty, DL)) + if (!isDereferenceablePointer(CB.getArgOperand(ArgNo), Ty, DL)) return false; } return true; @@ -774,8 +765,7 @@ static bool isSafeToPromoteArgument(Argument *Arg, Type *ByValTy, AAResults &AAR return true; } -/// Checks if a type could have padding bytes. -static bool isDenselyPacked(Type *type, const DataLayout &DL) { +bool ArgumentPromotionPass::isDenselyPacked(Type *type, const DataLayout &DL) { // There is no size information, so be conservative. if (!type->isSized()) return false; @@ -785,13 +775,18 @@ static bool isDenselyPacked(Type *type, const DataLayout &DL) { if (DL.getTypeSizeInBits(type) != DL.getTypeAllocSizeInBits(type)) return false; - if (!isa<CompositeType>(type)) - return true; + // FIXME: This isn't the right way to check for padding in vectors with + // non-byte-size elements. + if (VectorType *seqTy = dyn_cast<VectorType>(type)) + return isDenselyPacked(seqTy->getElementType(), DL); - // For homogenous sequential types, check for padding within members. - if (SequentialType *seqTy = dyn_cast<SequentialType>(type)) + // For array types, check for padding within members. + if (ArrayType *seqTy = dyn_cast<ArrayType>(type)) return isDenselyPacked(seqTy->getElementType(), DL); + if (!isa<StructType>(type)) + return true; + // Check for padding within and between elements of a struct. StructType *StructTy = cast<StructType>(type); const StructLayout *Layout = DL.getStructLayout(StructTy); @@ -844,14 +839,16 @@ static bool canPaddingBeAccessed(Argument *arg) { return false; } -static bool areFunctionArgsABICompatible( +bool ArgumentPromotionPass::areFunctionArgsABICompatible( const Function &F, const TargetTransformInfo &TTI, SmallPtrSetImpl<Argument *> &ArgsToPromote, SmallPtrSetImpl<Argument *> &ByValArgsToTransform) { for (const Use &U : F.uses()) { - CallSite CS(U.getUser()); - const Function *Caller = CS.getCaller(); - const Function *Callee = CS.getCalledFunction(); + CallBase *CB = dyn_cast<CallBase>(U.getUser()); + if (!CB) + return false; + const Function *Caller = CB->getCaller(); + const Function *Callee = CB->getCalledFunction(); if (!TTI.areFunctionArgsABICompatible(Caller, Callee, ArgsToPromote) || !TTI.areFunctionArgsABICompatible(Caller, Callee, ByValArgsToTransform)) return false; @@ -866,7 +863,7 @@ static bool areFunctionArgsABICompatible( static Function * promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter, unsigned MaxElements, - Optional<function_ref<void(CallSite OldCS, CallSite NewCS)>> + Optional<function_ref<void(CallBase &OldCS, CallBase &NewCS)>> ReplaceCallSite, const TargetTransformInfo &TTI) { // Don't perform argument promotion for naked functions; otherwise we can end @@ -905,16 +902,16 @@ promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter, // is self-recursive and check that target features are compatible. bool isSelfRecursive = false; for (Use &U : F->uses()) { - CallSite CS(U.getUser()); + CallBase *CB = dyn_cast<CallBase>(U.getUser()); // Must be a direct call. - if (CS.getInstruction() == nullptr || !CS.isCallee(&U)) + if (CB == nullptr || !CB->isCallee(&U)) return nullptr; // Can't change signature of musttail callee - if (CS.isMustTailCall()) + if (CB->isMustTailCall()) return nullptr; - if (CS.getInstruction()->getParent()->getParent() == F) + if (CB->getParent()->getParent() == F) isSelfRecursive = true; } @@ -942,18 +939,18 @@ promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter, F->removeParamAttr(ArgNo, Attribute::StructRet); F->addParamAttr(ArgNo, Attribute::NoAlias); for (Use &U : F->uses()) { - CallSite CS(U.getUser()); - CS.removeParamAttr(ArgNo, Attribute::StructRet); - CS.addParamAttr(ArgNo, Attribute::NoAlias); + CallBase &CB = cast<CallBase>(*U.getUser()); + CB.removeParamAttr(ArgNo, Attribute::StructRet); + CB.addParamAttr(ArgNo, Attribute::NoAlias); } } // If this is a byval argument, and if the aggregate type is small, just // pass the elements, which is always safe, if the passed value is densely // packed or if we can prove the padding bytes are never accessed. - bool isSafeToPromote = - PtrArg->hasByValAttr() && - (isDenselyPacked(AgTy, DL) || !canPaddingBeAccessed(PtrArg)); + bool isSafeToPromote = PtrArg->hasByValAttr() && + (ArgumentPromotionPass::isDenselyPacked(AgTy, DL) || + !canPaddingBeAccessed(PtrArg)); if (isSafeToPromote) { if (StructType *STy = dyn_cast<StructType>(AgTy)) { if (MaxElements > 0 && STy->getNumElements() > MaxElements) { @@ -1011,8 +1008,8 @@ promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter, if (ArgsToPromote.empty() && ByValArgsToTransform.empty()) return nullptr; - if (!areFunctionArgsABICompatible(*F, TTI, ArgsToPromote, - ByValArgsToTransform)) + if (!ArgumentPromotionPass::areFunctionArgsABICompatible( + *F, TTI, ArgsToPromote, ByValArgsToTransform)) return nullptr; return doPromotion(F, ArgsToPromote, ByValArgsToTransform, ReplaceCallSite); @@ -1135,14 +1132,13 @@ bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) { if (!OldF) continue; - auto ReplaceCallSite = [&](CallSite OldCS, CallSite NewCS) { - Function *Caller = OldCS.getInstruction()->getParent()->getParent(); + auto ReplaceCallSite = [&](CallBase &OldCS, CallBase &NewCS) { + Function *Caller = OldCS.getParent()->getParent(); CallGraphNode *NewCalleeNode = CG.getOrInsertFunction(NewCS.getCalledFunction()); CallGraphNode *CallerNode = CG[Caller]; - CallerNode->replaceCallEdge(*cast<CallBase>(OldCS.getInstruction()), - *cast<CallBase>(NewCS.getInstruction()), - NewCalleeNode); + CallerNode->replaceCallEdge(cast<CallBase>(OldCS), + cast<CallBase>(NewCS), NewCalleeNode); }; const TargetTransformInfo &TTI = |