54 #define DEBUG_TYPE "deadargelim" 56 STATISTIC(NumArgumentsEliminated,
"Number of unread args removed");
57 STATISTIC(NumRetValsEliminated ,
"Number of unused return values removed");
59 "Number of unread args replaced with undef");
76 bool runOnModule(
Module &M)
override {
85 virtual bool ShouldHackArguments()
const {
return false; }
92 INITIALIZE_PASS(DAE,
"deadargelim",
"Dead Argument Elimination",
false,
false)
99 struct DAH :
public DAE {
104 bool ShouldHackArguments()
const override {
return true; }
112 "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)",
123 bool DeadArgumentEliminationPass::DeleteDeadVarargs(
Function &Fn) {
164 unsigned NumArgs = Params.size();
170 Fn.getParent()->getFunctionList().insert(Fn.getIterator(), NF);
176 std::vector<Value *>
Args;
190 for (
unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo)
200 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
202 Args, OpBundles,
"", Call);
206 ->setTailCallKind(cast<CallInst>(Call)->getTailCallKind());
213 NewCS->setProfWeight(W);
220 NewCS->takeName(Call);
238 I->replaceAllUsesWith(&*I2);
244 Fn.getAllMetadata(MDs);
254 Fn.eraseFromParent();
261 bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(
Function &Fn) {
291 bool Changed =
false;
303 if (UnusedArgs.
empty())
308 if (!CS || !CS.isCallee(&U))
312 for (
unsigned I = 0,
E = UnusedArgs.
size();
I !=
E; ++
I) {
313 unsigned ArgNo = UnusedArgs[
I];
317 ++NumArgumentsReplacedWithUndef;
332 else if (
StructType *STy = dyn_cast<StructType>(RetTy))
333 return STy->getNumElements();
334 else if (
ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
335 return ATy->getNumElements();
347 if (
StructType *STy = dyn_cast<StructType>(RetTy))
348 return STy->getElementType(Idx);
349 else if (
ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
350 return ATy->getElementType();
359 DeadArgumentEliminationPass::MarkIfNotLive(RetOrArg
Use,
360 UseVector &MaybeLiveUses) {
362 if (LiveFunctions.count(Use.F) || LiveValues.count(Use))
367 MaybeLiveUses.push_back(Use);
379 DeadArgumentEliminationPass::SurveyUse(
const Use *U, UseVector &MaybeLiveUses,
380 unsigned RetValNum) {
381 const User *V = U->getUser();
382 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(V)) {
387 const Function *
F = RI->getParent()->getParent();
388 if (RetValNum != -1U) {
389 RetOrArg Use = CreateRet(F, RetValNum);
391 return MarkIfNotLive(Use, MaybeLiveUses);
394 for (
unsigned i = 0; i <
NumRetVals(F); ++i) {
395 RetOrArg Use = CreateRet(F, i);
400 MarkIfNotLive(Use, MaybeLiveUses);
413 RetValNum = *IV->idx_begin();
418 Liveness Result = MaybeLive;
419 for (
const Use &UU : IV->uses()) {
420 Result = SurveyUse(&UU, MaybeLiveUses, RetValNum);
428 const Function *
F = CS.getCalledFunction();
433 if (CS.isBundleOperand(U))
440 unsigned ArgNo = CS.getArgumentNo(U);
446 assert(CS.getArgument(ArgNo)
447 == CS->getOperand(U->getOperandNo())
448 &&
"Argument is not where we expected it");
452 RetOrArg Use = CreateArg(F, ArgNo);
453 return MarkIfNotLive(Use, MaybeLiveUses);
467 DeadArgumentEliminationPass::SurveyUses(
const Value *V,
468 UseVector &MaybeLiveUses) {
470 Liveness Result = MaybeLive;
472 for (
const Use &U : V->
uses()) {
473 Result = SurveyUse(&U, MaybeLiveUses);
487 void DeadArgumentEliminationPass::SurveyFunction(
const Function &
F) {
508 RetVals RetValLiveness(RetCount, MaybeLive);
515 RetUses MaybeLiveRetUses(RetCount);
517 bool HasMustTailCalls =
false;
520 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
521 if (RI->getNumOperands() != 0 && RI->getOperand(0)->getType()
531 if (BB->getTerminatingMustTailCall() !=
nullptr)
532 HasMustTailCalls =
true;
535 if (HasMustTailCalls) {
537 <<
" has musttail calls\n");
546 dbgs() <<
"DeadArgumentEliminationPass - Inspecting callers for fn: " 550 unsigned NumLiveRetVals = 0;
552 bool HasMustTailCallers =
false;
555 for (
const Use &U : F.
uses()) {
559 if (!CS || !CS.isCallee(&U)) {
566 if (CS.isMustTailCall())
567 HasMustTailCallers =
true;
580 if (NumLiveRetVals == RetCount)
584 for (
const Use &U : TheCall->
uses()) {
588 unsigned Idx = *
Ext->idx_begin();
589 if (RetValLiveness[Idx] != Live) {
590 RetValLiveness[Idx] = SurveyUses(
Ext, MaybeLiveRetUses[Idx]);
591 if (RetValLiveness[Idx] == Live)
597 UseVector MaybeLiveAggregateUses;
598 if (SurveyUse(&U, MaybeLiveAggregateUses) == Live) {
599 NumLiveRetVals = RetCount;
600 RetValLiveness.assign(RetCount, Live);
603 for (
unsigned i = 0; i != RetCount; ++i) {
604 if (RetValLiveness[i] != Live)
605 MaybeLiveRetUses[i].append(MaybeLiveAggregateUses.begin(),
606 MaybeLiveAggregateUses.end());
613 if (HasMustTailCallers) {
615 <<
" has musttail callers\n");
619 for (
unsigned i = 0; i != RetCount; ++i)
620 MarkValue(CreateRet(&F, i), RetValLiveness[i], MaybeLiveRetUses[i]);
622 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Inspecting args for fn: " 627 UseVector MaybeLiveArgUses;
648 Result = SurveyUses(&*AI, MaybeLiveArgUses);
652 MarkValue(CreateArg(&F, i), Result, MaybeLiveArgUses);
654 MaybeLiveArgUses.clear();
662 void DeadArgumentEliminationPass::MarkValue(
const RetOrArg &
RA, Liveness L,
663 const UseVector &MaybeLiveUses) {
671 for (
const auto &MaybeLiveUse : MaybeLiveUses)
672 Uses.insert(std::make_pair(MaybeLiveUse, RA));
681 void DeadArgumentEliminationPass::MarkLive(
const Function &F) {
682 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Intrinsically live fn: " 685 LiveFunctions.insert(&F);
687 for (
unsigned i = 0, e = F.
arg_size(); i != e; ++i)
688 PropagateLiveness(CreateArg(&F, i));
690 for (
unsigned i = 0, e =
NumRetVals(&F); i != e; ++i)
691 PropagateLiveness(CreateRet(&F, i));
697 void DeadArgumentEliminationPass::MarkLive(
const RetOrArg &RA) {
698 if (LiveFunctions.count(RA.F))
701 if (!LiveValues.insert(RA).second)
705 << RA.getDescription() <<
" live\n");
706 PropagateLiveness(RA);
711 void DeadArgumentEliminationPass::PropagateLiveness(
const RetOrArg &RA) {
715 UseMap::iterator Begin = Uses.lower_bound(RA);
716 UseMap::iterator
E = Uses.end();
718 for (I = Begin; I != E && I->first ==
RA; ++
I)
723 Uses.erase(Begin, I);
730 bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(
Function *F) {
732 if (LiveFunctions.count(F))
738 std::vector<Type*> Params;
741 bool HasLiveReturnedArg =
false;
755 RetOrArg
Arg = CreateArg(F, i);
756 if (LiveValues.erase(Arg)) {
757 Params.push_back(
I->getType());
762 ++NumArgumentsEliminated;
763 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Removing argument " 764 << i <<
" (" <<
I->getName() <<
") from " 771 Type *NRetTy =
nullptr;
776 std::vector<Type*> RetTypes;
797 if (RetTy->isVoidTy() || HasLiveReturnedArg) {
801 for (
unsigned i = 0; i != RetCount; ++i) {
802 RetOrArg
Ret = CreateRet(F, i);
803 if (LiveValues.erase(Ret)) {
805 NewRetIdxs[i] = RetTypes.
size() - 1;
807 ++NumRetValsEliminated;
809 dbgs() <<
"DeadArgumentEliminationPass - Removing return value " 810 << i <<
" from " << F->
getName() <<
"\n");
813 if (RetTypes.size() > 1) {
815 if (
StructType *STy = dyn_cast<StructType>(RetTy)) {
818 NRetTy =
StructType::get(STy->getContext(), RetTypes, STy->isPacked());
820 assert(isa<ArrayType>(RetTy) &&
"unexpected multi-value return");
823 }
else if (RetTypes.size() == 1)
826 NRetTy = RetTypes.front();
827 else if (RetTypes.empty())
832 assert(NRetTy &&
"No new return type found?");
845 "Return attributes no longer compatible?");
877 std::vector<Value*>
Args;
932 F->
getContext(), FnAttrs, RetAttrs, ArgAttrVec);
935 CS.getOperandBundlesAsDefs(OpBundles);
938 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
940 Args, OpBundles,
"", Call->getParent());
944 ->setTailCallKind(cast<CallInst>(Call)->getTailCallKind());
948 NewCS->setDebugLoc(Call->getDebugLoc());
950 if (Call->extractProfTotalWeight(W))
951 NewCS->setProfWeight(W);
956 if (!Call->use_empty() || Call->isUsedByMetadata()) {
957 if (New->
getType() == Call->getType()) {
964 if (!Call->getType()->isX86_MMXTy())
967 assert((RetTy->isStructTy() || RetTy->isArrayTy()) &&
968 "Return type changed, but not into a void. The old return type" 969 " must have been a struct or an array!");
971 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
982 for (
unsigned i = 0; i != RetCount; ++i)
983 if (NewRetIdxs[i] != -1) {
985 if (RetTypes.size() > 1)
998 Call->replaceAllUsesWith(RetVal);
1005 Call->eraseFromParent();
1021 I->replaceAllUsesWith(&*I2);
1027 if (!
I->getType()->isX86_MMXTy())
1035 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
1038 if (NFTy->getReturnType()->isVoidTy()) {
1041 assert(RetTy->isStructTy() || RetTy->isArrayTy());
1047 Value *OldRet = RI->getOperand(0);
1050 for (
unsigned i = 0; i != RetCount; ++i)
1051 if (NewRetIdxs[i] != -1) {
1054 if (RetTypes.size() > 1) {
1070 BB.getInstList().erase(RI);
1077 NF->addMetadata(MD.first, *MD.second);
1087 bool Changed =
false;
1093 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Deleting dead varargs\n");
1097 Changed |= DeleteDeadVarargs(F);
1104 LLVM_DEBUG(
dbgs() <<
"DeadArgumentEliminationPass - Determining liveness\n");
1114 Changed |= RemoveDeadStuffFromFunction(F);
1120 Changed |= RemoveDeadArgumentsFromCallers(F);
Return a value (possibly void), from a function.
User::op_iterator arg_iterator
The type of iterator to use when looping over actual arguments at this call site. ...
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
iterator_range< use_iterator > uses()
bool hasLocalLinkage() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents an incoming formal argument to a Function.
Eliminate dead arguments (and return values) from functions.
CallingConv::ID getCallingConv() const
Get the calling convention of the call.
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
void push_back(const T &Elt)
This class represents a function call, abstracting a target machine's calling convention.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
param_iterator param_end() const
This defines the Use class.
void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode *>> &MDs) const
Appends all attachments for the global to MDs, sorting by attachment ID.
bool isMustTailCall() const
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Split the edge connecting specified block.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
SI optimize exec mask operations pre RA
Class to represent struct types.
ModulePass * createDeadArgHackingPass()
DeadArgHacking pass - Same as DAE, but delete arguments of external functions as well.
A Use represents the edge between a Value definition and its users.
This file contains the simple types necessary to represent the attributes associated with functions a...
AttributeSet getRetAttributes() const
The attributes for the ret value are returned.
InstrTy * getInstruction() const
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Class to represent function types.
Type * getType() const
All values are typed, get the type of this value.
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...
Class to represent array types.
AttributeSet getParamAttributes(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
void setComdat(Comdat *C)
AttrBuilder & remove(const AttrBuilder &B)
Remove the attributes from the builder.
AttributeList getAttributes() const
Return the attribute list for this Function.
bool extractProfTotalWeight(uint64_t &TotalVal) const
Retrieve total raw weight values of a branch.
LinkageTypes getLinkage() const
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
void takeName(Value *V)
Transfer the name from V to this value.
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool isVoidTy() const
Return true if this is 'void'.
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
void setAttributes(AttributeList PAL)
Set the parameter attributes of the call.
Type * getReturnType() const
Returns the type of the ret val.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
A set of analyses that are preserved following a run of a transformation pass.
static AttributeSet get(LLVMContext &C, const AttrBuilder &B)
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
bool areAllPreserved() const
Test whether all analyses are preserved (and none are abandoned).
static unsigned getAggregateOperandIndex()
const FunctionListType & getFunctionList() const
Get the Module's list of functions (constant).
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ModulePass * createDeadArgEliminationPass()
createDeadArgEliminationPass - This pass removes arguments from functions which are not used by the b...
LLVM_NODISCARD AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Remove the specified attribute from this set.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
void initializeDAEPass(PassRegistry &)
param_iterator param_begin() const
static Type * getVoidTy(LLVMContext &C)
void splice(iterator where, iplist_impl &L2)
unsigned getAddressSpace() const
void setCallingConv(CallingConv::ID CC)
Set the calling convention of the call.
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
self_iterator getIterator()
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static unsigned NumRetVals(const Function *F)
Convenience function that returns the number of return values.
Iterator for intrusive lists based on ilist_node.
bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const
Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind).
AttrBuilder & removeAttribute(Attribute::AttrKind Val)
Remove an attribute from the builder.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
static Type * getRetComponentType(const Function *F, unsigned Idx)
Returns the sub-type a function will return at a given Idx.
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
Type * getReturnType() const
void setAttributes(AttributeList Attrs)
Set the attribute list for this Function.
bool isUsedByMetadata() const
Return true if there is metadata referencing this value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionType * getFunctionType() const
Returns the FunctionType for me.
amdgpu Simplify well known AMD library false Value Value * Arg
const Comdat * getComdat() const
iterator insert(iterator where, pointer New)
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_NODISCARD bool empty() const
void getOperandBundlesAsDefs(SmallVectorImpl< OperandBundleDef > &Defs) const
static InvokeInst * Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value *> Args, const Twine &NameStr, Instruction *InsertBefore=nullptr)
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
StringRef getName() const
Return a constant reference to the value's name.
bool hasExactDefinition() const
Return true if this global has an exact defintion.
Establish a view to a call site for examination.
user_iterator_impl< User > user_iterator
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const BasicBlockListType & getBasicBlockList() const
Get the underlying elements of the Function...
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool hasAddressTaken(const User **=nullptr) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Liveness
Liveness enum - During our initial pass over the program, we determine that things are either alive o...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
AttrBuilder typeIncompatible(Type *Ty)
Which attributes cannot be applied to a type.
AttributeSet getFnAttributes() const
The function attributes are returned.
A container for analyses that lazily runs them and caches their results.
AttributeList getAttributes() const
Get the parameter attributes of the call.
This header defines various interfaces for pass management in LLVM.
bool isEmpty() const
Return true if there are no attributes.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
PointerType * getType() const
Global values are always pointers.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute >> Attrs)
Create an AttributeList with the specified parameters in it.
iterator_range< arg_iterator > args()
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
This instruction inserts a struct field of array element value into an aggregate value.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)