Go to the documentation of this file.
53 #define DEBUG_TYPE "deadargelim"
55 STATISTIC(NumArgumentsEliminated,
"Number of unread args removed");
56 STATISTIC(NumRetValsEliminated ,
"Number of unused return values removed");
58 "Number of unread args replaced with undef");
75 bool runOnModule(
Module &M)
override {
84 virtual bool ShouldHackArguments()
const {
return false; }
91 INITIALIZE_PASS(DAE,
"deadargelim",
"Dead Argument Elimination",
false,
false)
98 struct DAH :
public DAE {
103 bool ShouldHackArguments()
const override {
return true; }
111 "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)",
122 bool DeadArgumentEliminationPass::DeleteDeadVarargs(
Function &Fn) {
147 if (II->getIntrinsicID() == Intrinsic::vastart)
163 unsigned NumArgs = Params.size();
169 Fn.getParent()->getFunctionList().insert(Fn.getIterator(), NF);
175 std::vector<Value *>
Args;
177 CallBase *CB = dyn_cast<CallBase>(U);
188 for (
unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo)
198 if (
InvokeInst *II = dyn_cast<InvokeInst>(CB)) {
200 Args, OpBundles,
"", CB);
203 cast<CallInst>(NewCB)->setTailCallKind(
204 cast<CallInst>(CB)->getTailCallKind());
208 NewCB->
copyMetadata(*CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
233 I->replaceAllUsesWith(&*I2);
239 Fn.getAllMetadata(MDs);
249 Fn.eraseFromParent();
256 bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(
Function &Fn) {
289 bool Changed =
false;
294 if (!
Arg.hasSwiftErrorAttr() &&
Arg.use_empty() &&
295 !
Arg.hasPassPointeeByValueCopyAttr()) {
296 if (
Arg.isUsedByMetadata()) {
300 UnusedArgs.push_back(
Arg.getArgNo());
305 if (UnusedArgs.empty())
309 CallBase *CB = dyn_cast<CallBase>(U.getUser());
315 for (
unsigned I = 0,
E = UnusedArgs.size();
I !=
E; ++
I) {
316 unsigned ArgNo = UnusedArgs[
I];
322 ++NumArgumentsReplacedWithUndef;
334 Type *RetTy =
F->getReturnType();
337 else if (
StructType *STy = dyn_cast<StructType>(RetTy))
338 return STy->getNumElements();
339 else if (
ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
340 return ATy->getNumElements();
349 Type *RetTy =
F->getReturnType();
352 if (
StructType *STy = dyn_cast<StructType>(RetTy))
353 return STy->getElementType(Idx);
354 else if (
ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
355 return ATy->getElementType();
364 DeadArgumentEliminationPass::MarkIfNotLive(RetOrArg
Use,
365 UseVector &MaybeLiveUses) {
372 MaybeLiveUses.push_back(
Use);
384 DeadArgumentEliminationPass::SurveyUse(
const Use *U, UseVector &MaybeLiveUses,
385 unsigned RetValNum) {
386 const User *V = U->getUser();
387 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(V)) {
392 const Function *
F = RI->getParent()->getParent();
393 if (RetValNum != -1U) {
396 return MarkIfNotLive(
Use, MaybeLiveUses);
405 MarkIfNotLive(
Use, MaybeLiveUses);
418 RetValNum = *
IV->idx_begin();
424 for (
const Use &UU :
IV->uses()) {
425 Result = SurveyUse(&UU, MaybeLiveUses, RetValNum);
432 if (
const auto *CB = dyn_cast<CallBase>(V)) {
447 if (ArgNo >=
F->getFunctionType()->getNumParams())
452 "Argument is not where we expected it");
457 return MarkIfNotLive(
Use, MaybeLiveUses);
471 DeadArgumentEliminationPass::SurveyUses(
const Value *V,
472 UseVector &MaybeLiveUses) {
476 for (
const Use &U : V->
uses()) {
477 Result = SurveyUse(&U, MaybeLiveUses);
491 void DeadArgumentEliminationPass::SurveyFunction(
const Function &
F) {
494 if (
F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) ||
495 F.getAttributes().hasAttrSomewhere(Attribute::Preallocated)) {
503 if (
F.hasFnAttribute(Attribute::Naked)) {
513 RetVals RetValLiveness(RetCount,
MaybeLive);
520 RetUses MaybeLiveRetUses(RetCount);
522 bool HasMustTailCalls =
false;
525 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(
BB->getTerminator())) {
526 if (RI->getNumOperands() != 0 && RI->getOperand(0)->getType()
527 !=
F.getFunctionType()->getReturnType()) {
536 if (
BB->getTerminatingMustTailCall() !=
nullptr)
537 HasMustTailCalls =
true;
540 if (HasMustTailCalls) {
542 <<
" has musttail calls\n");
551 dbgs() <<
"DeadArgumentEliminationPass - Inspecting callers for fn: "
552 <<
F.getName() <<
"\n");
555 unsigned NumLiveRetVals = 0;
557 bool HasMustTailCallers =
false;
560 for (
const Use &U :
F.uses()) {
563 const auto *CB = dyn_cast<CallBase>(U.
getUser());
573 HasMustTailCallers =
true;
579 if (NumLiveRetVals == RetCount)
583 for (
const Use &U : CB->
uses()) {
587 unsigned Idx = *
Ext->idx_begin();
588 if (RetValLiveness[Idx] !=
Live) {
589 RetValLiveness[Idx] = SurveyUses(
Ext, MaybeLiveRetUses[Idx]);
590 if (RetValLiveness[Idx] ==
Live)
597 if (SurveyUse(&U, MaybeLiveAggregateUses) ==
Live) {
598 NumLiveRetVals = RetCount;
599 RetValLiveness.assign(RetCount,
Live);
602 for (
unsigned Ri = 0; Ri != RetCount; ++Ri) {
603 if (RetValLiveness[Ri] !=
Live)
604 MaybeLiveRetUses[Ri].append(MaybeLiveAggregateUses.begin(),
605 MaybeLiveAggregateUses.end());
612 if (HasMustTailCallers) {
614 <<
" has musttail callers\n");
618 for (
unsigned Ri = 0; Ri != RetCount; ++Ri)
619 MarkValue(
CreateRet(&
F, Ri), RetValLiveness[Ri], MaybeLiveRetUses[Ri]);
621 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Inspecting args for fn: "
622 <<
F.getName() <<
"\n");
628 AI !=
E; ++AI, ++ArgI) {
630 if (
F.getFunctionType()->isVarArg() || HasMustTailCallers ||
647 Result = SurveyUses(&*AI, MaybeLiveArgUses);
651 MarkValue(
CreateArg(&
F, ArgI), Result, MaybeLiveArgUses);
653 MaybeLiveArgUses.clear();
661 void DeadArgumentEliminationPass::MarkValue(
const RetOrArg &RA, Liveness L,
662 const UseVector &MaybeLiveUses) {
668 assert(!IsLive(RA) &&
"Use is already live!");
669 for (
const auto &MaybeLiveUse : MaybeLiveUses) {
670 if (IsLive(MaybeLiveUse)) {
677 Uses.insert(std::make_pair(MaybeLiveUse, RA));
688 void DeadArgumentEliminationPass::MarkLive(
const Function &
F) {
689 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Intrinsically live fn: "
690 <<
F.getName() <<
"\n");
694 for (
unsigned ArgI = 0,
E =
F.arg_size(); ArgI !=
E; ++ArgI)
704 void DeadArgumentEliminationPass::MarkLive(
const RetOrArg &RA) {
711 <<
RA.getDescription() <<
" live\n");
712 PropagateLiveness(RA);
715 bool DeadArgumentEliminationPass::IsLive(
const RetOrArg &RA) {
721 void DeadArgumentEliminationPass::PropagateLiveness(
const RetOrArg &RA) {
725 UseMap::iterator Begin =
Uses.lower_bound(RA);
726 UseMap::iterator
E =
Uses.end();
728 for (
I = Begin;
I !=
E &&
I->first ==
RA; ++
I)
733 Uses.erase(Begin,
I);
740 bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(
Function *
F) {
748 std::vector<Type*> Params;
751 bool HasLiveReturnedArg =
false;
767 Params.push_back(
I->getType());
768 ArgAlive[ArgI] =
true;
770 HasLiveReturnedArg |= PAL.
hasParamAttr(ArgI, Attribute::Returned);
772 ++NumArgumentsEliminated;
773 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Removing argument "
774 << ArgI <<
" (" <<
I->getName() <<
") from "
775 <<
F->getName() <<
"\n");
781 Type *NRetTy =
nullptr;
786 std::vector<Type*> RetTypes;
807 if (RetTy->
isVoidTy() || HasLiveReturnedArg) {
811 for (
unsigned Ri = 0; Ri != RetCount; ++Ri) {
815 NewRetIdxs[Ri] = RetTypes.size() - 1;
817 ++NumRetValsEliminated;
819 dbgs() <<
"DeadArgumentEliminationPass - Removing return value "
820 << Ri <<
" from " <<
F->getName() <<
"\n");
823 if (RetTypes.size() > 1) {
825 if (
StructType *STy = dyn_cast<StructType>(RetTy)) {
828 NRetTy =
StructType::get(STy->getContext(), RetTypes, STy->isPacked());
830 assert(isa<ArrayType>(RetTy) &&
"unexpected multi-value return");
833 }
else if (RetTypes.size() == 1)
836 NRetTy = RetTypes.front();
837 else if (RetTypes.empty())
842 assert(NRetTy &&
"No new return type found?");
855 "Return attributes no longer compatible?");
864 assert(ArgAttrVec.size() == Params.size());
882 F->getParent()->getFunctionList().insert(
F->getIterator(), NF);
887 std::vector<Value*>
Args;
888 while (!
F->use_empty()) {
889 CallBase &CB = cast<CallBase>(*
F->user_back());
911 if (NRetTy != RetTy &&
Attrs.hasAttribute(Attribute::Returned)) {
922 ArgAttrVec.push_back(
Attrs);
938 F->getContext(), Attribute::AllocSize);
941 F->getContext(), FnAttrs, RetAttrs, ArgAttrVec);
947 if (
InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
952 cast<CallInst>(NewCB)->setTailCallKind(
953 cast<CallInst>(&CB)->getTailCallKind());
957 NewCB->
copyMetadata(CB, {LLVMContext::MD_prof, LLVMContext::MD_dbg});
973 "Return type changed, but not into a void. The old return type"
974 " must have been a struct or an array!");
976 if (
InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
988 for (
unsigned Ri = 0; Ri != RetCount; ++Ri)
989 if (NewRetIdxs[Ri] != -1) {
992 if (RetTypes.size() > 1)
995 V = IRB.CreateExtractValue(NewCB, NewRetIdxs[Ri],
"newret");
1000 RetVal = IRB.CreateInsertValue(RetVal, V, Ri,
"oldret");
1024 I !=
E; ++
I, ++ArgI)
1025 if (ArgAlive[ArgI]) {
1028 I->replaceAllUsesWith(&*I2);
1034 if (!
I->getType()->isX86_MMXTy())
1042 if (
ReturnInst *RI = dyn_cast<ReturnInst>(
BB.getTerminator())) {
1044 Value *RetVal =
nullptr;
1053 Value *OldRet = RI->getOperand(0);
1056 for (
unsigned RetI = 0; RetI != RetCount; ++RetI)
1057 if (NewRetIdxs[RetI] != -1) {
1058 Value *EV = IRB.CreateExtractValue(OldRet, RetI,
"oldret");
1060 if (RetTypes.size() > 1) {
1064 RetVal = IRB.CreateInsertValue(RetVal, EV, NewRetIdxs[RetI],
1076 NewRet->setDebugLoc(RI->getDebugLoc());
1077 BB.getInstList().erase(RI);
1082 F->getAllMetadata(MDs);
1084 NF->addMetadata(MD.first, *MD.second);
1087 F->eraseFromParent();
1094 bool Changed =
false;
1100 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Deleting dead varargs\n");
1102 if (
F.getFunctionType()->isVarArg())
1103 Changed |= DeleteDeadVarargs(
F);
1109 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Determining liveness\n");
1117 Changed |= RemoveDeadStuffFromFunction(&
F);
1122 Changed |= RemoveDeadArgumentsFromCallers(
F);
A set of analyses that are preserved following a run of a transformation pass.
This class represents an incoming formal argument to a Function.
void setComdat(Comdat *C)
This is an optimization pass for GlobalISel generic memory operations.
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
Return the list of operand bundles attached to this instruction as a vector of OperandBundleDefs.
static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr, Instruction *InsertBefore=nullptr)
iterator_range< arg_iterator > args()
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Return a value (possibly void), from a function.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
UseMap Uses
This maps a return value or argument to any MaybeLive return values or arguments it uses.
bool isX86_MMXTy() const
Return true if this is X86 MMX.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
const BasicBlockListType & getBasicBlockList() const
Get the underlying elements of the Function...
RetOrArg CreateRet(const Function *F, unsigned Idx)
Convenience wrapper.
void removeParamAttrs(unsigned ArgNo, const AttributeMask &AttrsToRemove)
Removes the attributes from the given argument.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
AttributeMask getUBImplyingAttributes()
Get param/return attributes which imply immediate undefined behavior if an invalid value is passed.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute >> Attrs)
Create an AttributeList with the specified parameters in it.
ModulePass * createDeadArgEliminationPass()
createDeadArgEliminationPass - This pass removes arguments from functions which are not used by the b...
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
The instances of the Type class are immutable: once they are created, they are never changed.
AttributeList getAttributes() const
Return the parameter attributes for this call.
FunctionType * getFunctionType() const
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
AttributeSet getFnAttrs() const
The function attributes are returned.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Class to represent array types.
AttrBuilder & removeAttribute(Attribute::AttrKind Val)
Remove an attribute from the builder.
LLVM Basic Block Representation.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
bool isArrayTy() const
True if this is an instance of ArrayType.
bool hasExactDefinition() const
Return true if this global has an exact defintion.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
param_iterator param_end() const
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
iterator_range< use_iterator > uses()
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
RetOrArg CreateArg(const Function *F, unsigned Idx)
Convenience wrapper.
param_iterator param_begin() const
Liveness
Liveness enum - During our initial pass over the program, we determine that things are either alive o...
STATISTIC(NumFunctions, "Total number of functions")
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
LiveSet LiveValues
This set contains all values that have been determined to be live.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
ModulePass * createDeadArgHackingPass()
DeadArgHacking pass - Same as DAE, but delete arguments of external functions as well.
User * getUser() const
Returns the User that contains this Use.
SmallVector< RetOrArg, 5 > UseVector
CallingConv::ID getCallingConv() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static unsigned NumRetVals(const Function *F)
Convenience function that returns the number of return values.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
INITIALIZE_PASS(DAH, "deadarghaX0r", "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)", false, false) ModulePass *llvm
createDeadArgEliminationPass - This pass removes arguments from functions which are not used by the b...
AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Type * getReturnType() const
Returns the type of the ret val.
static Type * getRetComponentType(const Function *F, unsigned Idx)
Returns the sub-type a function will return at a given Idx.
static AttributeSet get(LLVMContext &C, const AttrBuilder &B)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Eliminate dead arguments (and return values) from functions.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasLocalLinkage() const
LiveFuncSet LiveFunctions
This set contains all values that are cannot be changed in any way.
bool isVoidTy() const
Return true if this is 'void'.
LLVM_NODISCARD AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Remove the specified attribute from this set.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
A Module instance is used to store all the information related to an LLVM module.
SI optimize exec mask operations pre RA
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
bool ShouldHackArguments
This allows this pass to do double-duty as the dead arg hacking pass (used only by bugpoint).
Class to represent struct types.
bool areAllPreserved() const
Test whether all analyses are preserved (and none are abandoned).
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
bool isMustTailCall() const
bool hasAddressTaken(const User **=nullptr, bool IgnoreCallbackUses=false, bool IgnoreAssumeLikeCalls=true, bool IngoreLLVMUsed=false, bool IgnoreARCAttachedCall=false) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
void setArgOperand(unsigned i, Value *v)
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
bool isBundleOperand(unsigned Idx) const
Return true if the operand at index Idx is a bundle operand.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
A wrapper class for inspecting calls to intrinsic functions.
void removeParamAttrs(unsigned ArgNo, const AttributeMask &Attrs)
removes the attribute from the list of attributes.
static Type * getVoidTy(LLVMContext &C)
bool isStructTy() const
True if this is an instance of StructType.
bool isUsedByMetadata() const
Return true if there is metadata referencing this value.
Value * getArgOperand(unsigned i) const
const BasicBlock * getParent() const
static const uint32_t IV[8]
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
static unsigned getAggregateOperandIndex()
A container for analyses that lazily runs them and caches their results.
This class represents a function call, abstracting a target machine's calling convention.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
void takeName(Value *V)
Transfer the name from V to this value.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Value * getOperand(unsigned i) const
void initializeDAEPass(PassRegistry &)
bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return true if the attribute exists for the given argument.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
This instruction inserts a struct field of array element value into an aggregate value.
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
Type * getReturnType() const
LLVM Value Representation.
bool isEmpty() const
Return true if there are no attributes.
BasicBlockListType::const_iterator const_iterator
void setCallingConv(CallingConv::ID CC)
Class to represent function types.
A Use represents the edge between a Value definition and its users.