summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/IPO/ArgumentPromotion.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/ArgumentPromotion.cpp136
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 =