43 #define DEBUG_TYPE "deadargelim"
45 STATISTIC(NumArgumentsEliminated,
"Number of unread args removed");
46 STATISTIC(NumRetValsEliminated ,
"Number of unused return values removed");
48 "Number of unread args replaced with undef");
59 RetOrArg(
const Function *
F,
unsigned Idx,
bool IsArg) : F(F), Idx(Idx),
67 return std::tie(
F, Idx, IsArg) < std::tie(O.F, O.Idx, O.IsArg);
72 return F == O.F && Idx == O.Idx && IsArg == O.IsArg;
75 std::string getDescription()
const {
76 return (
Twine(IsArg ?
"Argument #" :
"Return value #") +
utostr(Idx) +
77 " of function " +
F->getName()).str();
86 enum Liveness { Live, MaybeLive };
89 RetOrArg CreateRet(
const Function *
F,
unsigned Idx) {
90 return RetOrArg(F, Idx,
false);
93 RetOrArg CreateArg(
const Function *
F,
unsigned Idx) {
94 return RetOrArg(F, Idx,
true);
97 typedef std::multimap<RetOrArg, RetOrArg> UseMap;
114 typedef std::set<RetOrArg> LiveSet;
115 typedef std::set<const Function*> LiveFuncSet;
120 LiveFuncSet LiveFunctions;
142 bool runOnModule(
Module &M)
override;
144 virtual bool ShouldHackArguments()
const {
return false; }
147 Liveness MarkIfNotLive(RetOrArg
Use, UseVector &MaybeLiveUses);
148 Liveness SurveyUse(
const Use *U, UseVector &MaybeLiveUses,
149 unsigned RetValNum = -1U);
150 Liveness SurveyUses(
const Value *V, UseVector &MaybeLiveUses);
153 void MarkValue(
const RetOrArg &RA, Liveness L,
154 const UseVector &MaybeLiveUses);
155 void MarkLive(
const RetOrArg &RA);
157 void PropagateLiveness(
const RetOrArg &RA);
158 bool RemoveDeadStuffFromFunction(
Function *
F);
159 bool DeleteDeadVarargs(
Function &Fn);
160 bool RemoveDeadArgumentsFromCallers(
Function &Fn);
166 INITIALIZE_PASS(DAE,
"deadargelim",
"Dead Argument Elimination",
false,
false)
172 struct DAH :
public DAE {
176 bool ShouldHackArguments()
const override {
return true; }
182 "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)",
193 bool DAE::DeleteDeadVarargs(
Function &Fn) {
211 if (II->getIntrinsicID() == Intrinsic::vastart)
227 unsigned NumArgs = Params.size();
238 std::vector<Value*> Args;
246 Args.assign(
CS.arg_begin(),
CS.arg_begin() + NumArgs);
252 for (
unsigned i = 0; PAL.
getSlotIndex(i) <= NumArgs; ++i)
257 PAL = AttributeSet::get(Fn.
getContext(), AttributesVec);
261 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
264 cast<InvokeInst>(New)->setCallingConv(
CS.getCallingConv());
265 cast<InvokeInst>(New)->setAttributes(PAL);
268 cast<CallInst>(New)->setCallingConv(
CS.getCallingConv());
269 cast<CallInst>(New)->setAttributes(PAL);
270 if (cast<CallInst>(Call)->isTailCall())
271 cast<CallInst>(New)->setTailCall();
299 I->replaceAllUsesWith(I2);
304 auto DI = FunctionDIs.find(&Fn);
305 if (DI != FunctionDIs.end()) {
310 FunctionDIs.erase(DI);
311 FunctionDIs[NF] = SP;
327 bool DAE::RemoveDeadArgumentsFromCallers(
Function &Fn)
360 if (UnusedArgs.
empty())
363 bool Changed =
false;
367 if (!CS || !
CS.isCallee(&U))
371 for (
unsigned I = 0, E = UnusedArgs.
size();
I != E; ++
I) {
372 unsigned ArgNo = UnusedArgs[
I];
374 Value *Arg =
CS.getArgument(ArgNo);
376 ++NumArgumentsReplacedWithUndef;
391 else if (
StructType *STy = dyn_cast<StructType>(RetTy))
392 return STy->getNumElements();
393 else if (
ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
394 return ATy->getNumElements();
404 assert(!RetTy->
isVoidTy() &&
"void type has no subtype");
406 if (
StructType *STy = dyn_cast<StructType>(RetTy))
407 return STy->getElementType(Idx);
408 else if (
ArrayType *ATy = dyn_cast<ArrayType>(RetTy))
409 return ATy->getElementType();
417 DAE::Liveness DAE::MarkIfNotLive(RetOrArg
Use, UseVector &MaybeLiveUses) {
419 if (LiveFunctions.count(Use.F) || LiveValues.count(Use))
424 MaybeLiveUses.push_back(Use);
436 DAE::Liveness DAE::SurveyUse(
const Use *U,
437 UseVector &MaybeLiveUses,
unsigned RetValNum) {
438 const User *V = U->getUser();
439 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(V)) {
444 const Function *
F = RI->getParent()->getParent();
445 if (RetValNum != -1U) {
446 RetOrArg Use = CreateRet(F, RetValNum);
448 return MarkIfNotLive(Use, MaybeLiveUses);
450 DAE::Liveness Result = MaybeLive;
451 for (
unsigned i = 0; i <
NumRetVals(F); ++i) {
452 RetOrArg Use = CreateRet(F, i);
456 DAE::Liveness SubResult = MarkIfNotLive(Use, MaybeLiveUses);
469 RetValNum = *IV->idx_begin();
474 Liveness Result = MaybeLive;
475 for (
const Use &UU : IV->uses()) {
476 Result = SurveyUse(&UU, MaybeLiveUses, RetValNum);
492 unsigned ArgNo =
CS.getArgumentNo(U);
498 assert(
CS.getArgument(ArgNo)
499 ==
CS->getOperand(U->getOperandNo())
500 &&
"Argument is not where we expected it");
504 RetOrArg Use = CreateArg(F, ArgNo);
505 return MarkIfNotLive(Use, MaybeLiveUses);
518 DAE::Liveness DAE::SurveyUses(
const Value *V, UseVector &MaybeLiveUses) {
520 Liveness Result = MaybeLive;
522 for (
const Use &U : V->
uses()) {
523 Result = SurveyUse(&U, MaybeLiveUses);
538 void DAE::SurveyFunction(
const Function &F) {
549 RetVals RetValLiveness(RetCount, MaybeLive);
555 RetUses MaybeLiveRetUses(RetCount);
558 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
559 if (RI->getNumOperands() != 0 && RI->getOperand(0)->getType()
571 DEBUG(
dbgs() <<
"DAE - Inspecting callers for fn: " << F.
getName() <<
"\n");
574 unsigned NumLiveRetVals = 0;
576 for (
const Use &U : F.
uses()) {
580 if (!CS || !
CS.isCallee(&U)) {
596 if (NumLiveRetVals == RetCount)
600 for (
const Use &U : TheCall->
uses()) {
604 unsigned Idx = *
Ext->idx_begin();
605 if (RetValLiveness[Idx] != Live) {
606 RetValLiveness[Idx] = SurveyUses(
Ext, MaybeLiveRetUses[Idx]);
607 if (RetValLiveness[Idx] == Live)
613 UseVector MaybeLiveAggregateUses;
614 if (SurveyUse(&U, MaybeLiveAggregateUses) == Live) {
615 NumLiveRetVals = RetCount;
616 RetValLiveness.assign(RetCount, Live);
619 for (
unsigned i = 0; i != RetCount; ++i) {
620 if (RetValLiveness[i] != Live)
621 MaybeLiveRetUses[i].append(MaybeLiveAggregateUses.begin(),
622 MaybeLiveAggregateUses.end());
630 for (
unsigned i = 0; i != RetCount; ++i)
631 MarkValue(CreateRet(&F, i), RetValLiveness[i], MaybeLiveRetUses[i]);
637 UseVector MaybeLiveArgUses;
639 E = F.
arg_end(); AI != E; ++AI, ++i) {
651 Result = SurveyUses(AI, MaybeLiveArgUses);
655 MarkValue(CreateArg(&F, i), Result, MaybeLiveArgUses);
657 MaybeLiveArgUses.clear();
665 void DAE::MarkValue(
const RetOrArg &RA, Liveness L,
666 const UseVector &MaybeLiveUses) {
668 case Live: MarkLive(RA);
break;
673 for (UseVector::const_iterator UI = MaybeLiveUses.begin(),
674 UE = MaybeLiveUses.end(); UI != UE; ++UI)
675 Uses.insert(std::make_pair(*UI, RA));
685 void DAE::MarkLive(
const Function &F) {
688 LiveFunctions.insert(&F);
690 for (
unsigned i = 0, e = F.
arg_size(); i != e; ++i)
691 PropagateLiveness(CreateArg(&F, i));
693 for (
unsigned i = 0, e =
NumRetVals(&F); i != e; ++i)
694 PropagateLiveness(CreateRet(&F, i));
700 void DAE::MarkLive(
const RetOrArg &RA) {
701 if (LiveFunctions.count(RA.F))
704 if (!LiveValues.insert(RA).second)
707 DEBUG(
dbgs() <<
"DAE - Marking " << RA.getDescription() <<
" live\n");
708 PropagateLiveness(RA);
713 void DAE::PropagateLiveness(
const RetOrArg &RA) {
717 UseMap::iterator Begin = Uses.lower_bound(RA);
718 UseMap::iterator E = Uses.end();
720 for (I = Begin; I != E && I->first == RA; ++
I)
725 Uses.erase(Begin, I);
732 bool DAE::RemoveDeadStuffFromFunction(
Function *F) {
734 if (LiveFunctions.count(F))
740 std::vector<Type*> Params;
743 bool HasLiveReturnedArg =
false;
757 RetOrArg Arg = CreateArg(F, i);
758 if (LiveValues.erase(Arg)) {
759 Params.push_back(I->getType());
767 HasLiveReturnedArg =
true;
769 push_back(AttributeSet::get(F->
getContext(), Params.size(), B));
772 ++NumArgumentsEliminated;
773 DEBUG(
dbgs() <<
"DAE - Removing argument " << i <<
" (" << I->getName()
774 <<
") from " << F->
getName() <<
"\n");
780 Type *NRetTy =
nullptr;
785 std::vector<Type*> RetTypes;
806 if (RetTy->
isVoidTy() || HasLiveReturnedArg) {
810 for (
unsigned i = 0; i != RetCount; ++i) {
811 RetOrArg
Ret = CreateRet(F, i);
812 if (LiveValues.erase(Ret)) {
814 NewRetIdxs[i] = RetTypes.size() - 1;
816 ++NumRetValsEliminated;
817 DEBUG(
dbgs() <<
"DAE - Removing return value " << i <<
" from "
821 if (RetTypes.size() > 1) {
823 if (
StructType *STy = dyn_cast<StructType>(RetTy)) {
826 NRetTy =
StructType::get(STy->getContext(), RetTypes, STy->isPacked());
828 assert(isa<ArrayType>(RetTy) &&
"unexpected multi-value return");
831 }
else if (RetTypes.size() == 1)
834 NRetTy = RetTypes.front();
835 else if (RetTypes.size() == 0)
840 assert(NRetTy &&
"No new return type found?");
856 "Return attributes no longer compatible?");
887 std::vector<Value*> Args;
892 AttributesVec.
clear();
925 push_back(AttributeSet::get(F->
getContext(), Args.size(), B));
935 push_back(AttributeSet::get(F->
getContext(), Args.size(), B));
940 AttributesVec.
push_back(AttributeSet::get(Call->getContext(),
947 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
950 cast<InvokeInst>(New)->setCallingConv(
CS.getCallingConv());
951 cast<InvokeInst>(New)->setAttributes(NewCallPAL);
954 cast<CallInst>(New)->setCallingConv(
CS.getCallingConv());
955 cast<CallInst>(New)->setAttributes(NewCallPAL);
956 if (cast<CallInst>(Call)->isTailCall())
957 cast<CallInst>(New)->setTailCall();
959 New->setDebugLoc(Call->getDebugLoc());
963 if (!Call->use_empty()) {
964 if (New->getType() == Call->getType()) {
966 Call->replaceAllUsesWith(New);
968 }
else if (New->getType()->isVoidTy()) {
971 if (!Call->getType()->isX86_MMXTy())
975 "Return type changed, but not into a void. The old return type"
976 " must have been a struct or an array!");
978 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
980 while (isa<PHINode>(IP)) ++IP;
990 for (
unsigned i = 0; i != RetCount; ++i)
991 if (NewRetIdxs[i] != -1) {
993 if (RetTypes.size() > 1)
1006 Call->replaceAllUsesWith(RetVal);
1007 New->takeName(Call);
1013 Call->eraseFromParent();
1029 I->replaceAllUsesWith(I2);
1035 if (!I->getType()->isX86_MMXTy())
1043 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
1046 if (NFTy->getReturnType()->isVoidTy()) {
1055 Value *OldRet = RI->getOperand(0);
1058 for (
unsigned i = 0; i != RetCount; ++i)
1059 if (NewRetIdxs[i] != -1) {
1062 if (RetTypes.size() > 1) {
1078 BB->getInstList().erase(RI);
1082 auto DI = FunctionDIs.find(F);
1083 if (DI != FunctionDIs.end())
1084 DI->second->replaceFunction(NF);
1092 bool DAE::runOnModule(
Module &M) {
1093 bool Changed =
false;
1102 DEBUG(
dbgs() <<
"DAE - Deleting dead varargs\n");
1106 Changed |= DeleteDeadVarargs(F);
1113 DEBUG(
dbgs() <<
"DAE - Determining liveness\n");
1123 Changed |= RemoveDeadStuffFromFunction(F);
1129 Changed |= RemoveDeadArgumentsFromCallers(F);
ReturnInst - Return a value (possibly void), from a function.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
LinkageTypes getLinkage() const
iterator_range< use_iterator > uses()
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
LLVM Argument representation.
STATISTIC(NumFunctions,"Total number of functions")
A Module instance is used to store all the information related to an LLVM module. ...
unsigned getNumParams() const
getNumParams - Return the number of fixed parameters this function type requires. ...
bool hasByValOrInAllocaAttr() const
Return true if this argument has the byval attribute or inalloca attribute on it in its containing fu...
CallInst - This class represents a function call, abstracting a target machine's calling convention...
Type * getReturnType() const
void replaceFunction(Function *F)
Replace the function.
User::op_iterator arg_iterator
arg_iterator - The type of iterator to use when looping over actual arguments at this call site...
AttributeSet getRetAttributes() const
The attributes for the ret value are returned.
static Constant * getNullValue(Type *Ty)
StringRef getName() const
Return a constant reference to the value's name.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
StructType - 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.
param_iterator param_end() const
bool isMustTailCall() const
bool isStrongDefinitionForLinker() const
Returns true if this global's definition will be the one chosen by the linker.
user_iterator_impl< User > user_iterator
FunctionType - Class to represent function types.
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
ArrayType - Class to represent array types.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
FunctionType::get - This static method is the primary way of constructing a FunctionType.
static std::string utostr(uint64_t X, bool isNeg=false)
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
bool isArrayTy() const
isArrayTy - True if this is an instance of ArrayType.
void takeName(Value *V)
Transfer the name from V to this value.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
unsigned getNumSlots() const
Return the number of slots used in this attribute list.
void setDebugLoc(DebugLoc Loc)
setDebugLoc - Set the debug location information for this instruction.
static unsigned getAggregateOperandIndex()
The instances of the Type class are immutable: once they are created, they are never changed...
AttributeSet getSlotAttributes(unsigned Slot) const
Return the attributes at the given slot.
param_iterator param_begin() const
ModulePass * createDeadArgEliminationPass()
createDeadArgEliminationPass - This pass removes arguments from functions which are not used by the b...
void initializeDAEPass(PassRegistry &)
Return value is always equal to this argument.
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
Pass structure in an alloca.
static Type * getVoidTy(LLVMContext &C)
iterator insert(iterator where, NodeTy *New)
User * getUser() const
Returns the User that contains this Use.
void copyAttributesFrom(const GlobalValue *Src) override
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
static UndefValue * get(Type *T)
get() - Static factory methods - Return an 'undef' object of the specified type.
const FunctionListType & getFunctionList() const
Get the Module's list of functions (constant).
static InvokeInst * Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
static unsigned NumRetVals(const Function *F)
Convenience function that returns the number of return values.
const BasicBlockListType & getBasicBlockList() const
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
StructType::get - This static method is the primary way to create a literal StructType.
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.
Type * getType() const
All values are typed, get the type of this value.
static Type * getRetComponentType(const Function *F, unsigned Idx)
Returns the sub-type a function will return at a given Idx.
void splice(iterator where, iplist &L2)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
AttributeSet getAttributes() const
Return the attribute list for this Function.
AttributeSet removeAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const
Remove the specified attributes at the specified index from this attribute list.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void eraseFromParent() override
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
bool isStructTy() const
isStructTy - True if this is an instance of StructType.
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...
PointerType * getType() const
Global values are always pointers.
bool hasAddressTaken(const User **=nullptr) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool hasAttrSomewhere(Attribute::AttrKind Attr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
unsigned getSlotIndex(unsigned Slot) const
Return the index for the given slot.
bool hasAttributes(unsigned Index) const
Return true if attribute exists at the given index.
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
AttrBuilder typeIncompatible(const Type *Ty)
Which attributes cannot be applied to a type.
ImmutableCallSite - establish a view to a call site for examination.
FunctionType * getFunctionType() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
ArrayType::get - This static method is the primary way to construct an ArrayType. ...
void setAttributes(AttributeSet attrs)
Set the attribute list for this Function.
bool hasLocalLinkage() const
Type * getReturnType() const
user_iterator user_begin()
DenseMap< const Function *, DISubprogram * > makeSubprogramMap(const Module &M)
bool operator<(int64_t V1, const APSInt &V2)
void removeDeadConstantUsers() const
removeDeadConstantUsers - If there are any dead constant users dangling off of this constant...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
InvokeInst - Invoke instruction.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
bool operator==(uint64_t V1, const APInt &V2)
bool isEmpty() const
Return true if there are no attributes.
IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic functions.
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
InsertValueInst - This instruction inserts a struct field of array element value into an aggregate va...
AttributeSet getFnAttributes() const
The function attributes are returned.