20 #define DEBUG_TYPE "deadargelim"
43 STATISTIC(NumArgumentsEliminated,
"Number of unread args removed");
44 STATISTIC(NumRetValsEliminated ,
"Number of unused return values removed");
46 "Number of unread args replaced with undef");
57 RetOrArg(
const Function *
F,
unsigned Idx,
bool IsArg) : F(F), Idx(Idx),
67 else if (Idx != O.Idx)
70 return IsArg < O.IsArg;
75 return F == O.F && Idx == O.Idx && IsArg == O.IsArg;
78 std::string getDescription()
const {
79 return std::string((IsArg ?
"Argument #" :
"Return value #"))
80 +
utostr(Idx) +
" of function " +
F->getName().str();
89 enum Liveness { Live, MaybeLive };
92 RetOrArg CreateRet(
const Function *
F,
unsigned Idx) {
93 return RetOrArg(F, Idx,
false);
96 RetOrArg CreateArg(
const Function *
F,
unsigned Idx) {
97 return RetOrArg(F, Idx,
true);
100 typedef std::multimap<RetOrArg, RetOrArg> UseMap;
117 typedef std::set<RetOrArg> LiveSet;
118 typedef std::set<const Function*> LiveFuncSet;
123 LiveFuncSet LiveFunctions;
134 FunctionDIMap FunctionDIs;
146 bool runOnModule(
Module &M);
148 virtual bool ShouldHackArguments()
const {
return false; }
151 Liveness MarkIfNotLive(RetOrArg
Use, UseVector &MaybeLiveUses);
153 unsigned RetValNum = 0);
154 Liveness SurveyUses(
const Value *V, UseVector &MaybeLiveUses);
156 void CollectFunctionDIs(
Module &M);
158 void MarkValue(
const RetOrArg &RA, Liveness L,
159 const UseVector &MaybeLiveUses);
160 void MarkLive(
const RetOrArg &RA);
162 void PropagateLiveness(
const RetOrArg &RA);
163 bool RemoveDeadStuffFromFunction(
Function *
F);
164 bool DeleteDeadVarargs(
Function &Fn);
165 bool RemoveDeadArgumentsFromCallers(
Function &Fn);
171 INITIALIZE_PASS(DAE,
"deadargelim",
"Dead Argument Elimination",
false,
false)
177 struct DAH :
public DAE {
181 virtual bool ShouldHackArguments()
const {
return true; }
187 "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)",
198 void DAE::CollectFunctionDIs(
Module &M) {
205 MDIndex < MDNum; ++MDIndex) {
210 const DIArray &SPs = CU.getSubprograms();
212 SPIndex < SPNum; ++SPIndex) {
214 assert((!SP || SP.isSubprogram()) &&
215 "A MDNode in subprograms of a CU should be null or a DISubprogram.");
227 bool DAE::DeleteDeadVarargs(
Function &Fn) {
256 unsigned NumArgs = Params.size();
267 std::vector<Value*> Args;
275 Args.assign(CS.arg_begin(), CS.arg_begin() + NumArgs);
281 for (
unsigned i = 0; PAL.
getSlotIndex(i) <= NumArgs; ++i)
286 PAL = AttributeSet::get(Fn.
getContext(), AttributesVec);
290 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
293 cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
294 cast<InvokeInst>(New)->setAttributes(PAL);
297 cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
298 cast<CallInst>(New)->setAttributes(PAL);
299 if (cast<CallInst>(Call)->isTailCall())
300 cast<CallInst>(New)->setTailCall();
328 I->replaceAllUsesWith(I2);
333 FunctionDIMap::iterator DI = FunctionDIs.find(&Fn);
334 if (DI != FunctionDIs.end())
335 DI->second.replaceFunction(NF);
350 bool DAE::RemoveDeadArgumentsFromCallers(
Function &Fn)
385 if (UnusedArgs.
empty())
388 bool Changed =
false;
393 if (!CS || !CS.isCallee(
I))
397 for (
unsigned I = 0, E = UnusedArgs.
size();
I != E; ++
I) {
398 unsigned ArgNo = UnusedArgs[
I];
400 Value *Arg = CS.getArgument(ArgNo);
402 ++NumArgumentsReplacedWithUndef;
417 return STy->getNumElements();
425 DAE::Liveness DAE::MarkIfNotLive(RetOrArg
Use, UseVector &MaybeLiveUses) {
427 if (LiveFunctions.count(Use.F) || LiveValues.count(Use))
432 MaybeLiveUses.push_back(Use);
445 UseVector &MaybeLiveUses,
unsigned RetValNum) {
447 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(V)) {
452 RetOrArg Use = CreateRet(RI->getParent()->getParent(), RetValNum);
454 return MarkIfNotLive(Use, MaybeLiveUses);
462 RetValNum = *IV->idx_begin();
467 Liveness Result = MaybeLive;
470 Result = SurveyUse(
I, MaybeLiveUses, RetValNum);
478 const Function *
F = CS.getCalledFunction();
486 unsigned ArgNo = CS.getArgumentNo(U);
492 assert(CS.getArgument(ArgNo)
494 &&
"Argument is not where we expected it");
498 RetOrArg Use = CreateArg(F, ArgNo);
499 return MarkIfNotLive(Use, MaybeLiveUses);
512 DAE::Liveness DAE::SurveyUses(
const Value *V, UseVector &MaybeLiveUses) {
514 Liveness Result = MaybeLive;
518 Result = SurveyUse(
I, MaybeLiveUses);
533 void DAE::SurveyFunction(
const Function &F) {
537 RetVals RetValLiveness(RetCount, MaybeLive);
543 RetUses MaybeLiveRetUses(RetCount);
546 if (
const ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
547 if (RI->getNumOperands() != 0 && RI->getOperand(0)->getType()
559 DEBUG(
dbgs() <<
"DAE - Inspecting callers for fn: " << F.
getName() <<
"\n");
562 unsigned NumLiveRetVals = 0;
570 if (!CS || !CS.isCallee(
I)) {
586 if (NumLiveRetVals != RetCount) {
596 if (RetValLiveness[Idx] != Live) {
597 RetValLiveness[Idx] = SurveyUses(Ext, MaybeLiveRetUses[Idx]);
598 if (RetValLiveness[Idx] == Live)
604 for (
unsigned i = 0; i != RetCount; ++i )
605 RetValLiveness[i] = Live;
606 NumLiveRetVals = RetCount;
612 RetValLiveness[0] = SurveyUses(TheCall, MaybeLiveRetUses[0]);
613 if (RetValLiveness[0] == Live)
614 NumLiveRetVals = RetCount;
620 for (
unsigned i = 0; i != RetCount; ++i)
621 MarkValue(CreateRet(&F, i), RetValLiveness[i], MaybeLiveRetUses[i]);
627 UseVector MaybeLiveArgUses;
629 E = F.
arg_end(); AI != E; ++AI, ++i) {
641 Result = SurveyUses(AI, MaybeLiveArgUses);
645 MarkValue(CreateArg(&F, i), Result, MaybeLiveArgUses);
647 MaybeLiveArgUses.clear();
655 void DAE::MarkValue(
const RetOrArg &RA, Liveness L,
656 const UseVector &MaybeLiveUses) {
658 case Live: MarkLive(RA);
break;
663 for (UseVector::const_iterator UI = MaybeLiveUses.begin(),
664 UE = MaybeLiveUses.end(); UI != UE; ++UI)
665 Uses.insert(std::make_pair(*UI, RA));
675 void DAE::MarkLive(
const Function &F) {
678 LiveFunctions.insert(&F);
680 for (
unsigned i = 0, e = F.
arg_size(); i != e; ++i)
681 PropagateLiveness(CreateArg(&F, i));
683 for (
unsigned i = 0, e =
NumRetVals(&F); i != e; ++i)
684 PropagateLiveness(CreateRet(&F, i));
690 void DAE::MarkLive(
const RetOrArg &RA) {
691 if (LiveFunctions.count(RA.F))
694 if (!LiveValues.insert(RA).second)
697 DEBUG(
dbgs() <<
"DAE - Marking " << RA.getDescription() <<
" live\n");
698 PropagateLiveness(RA);
703 void DAE::PropagateLiveness(
const RetOrArg &RA) {
707 UseMap::iterator Begin = Uses.lower_bound(RA);
708 UseMap::iterator E = Uses.end();
710 for (I = Begin; I != E && I->first == RA; ++
I)
715 Uses.erase(Begin, I);
722 bool DAE::RemoveDeadStuffFromFunction(
Function *F) {
724 if (LiveFunctions.count(F))
730 std::vector<Type*> Params;
733 bool HasLiveReturnedArg =
false;
747 RetOrArg Arg = CreateArg(F, i);
748 if (LiveValues.erase(Arg)) {
749 Params.push_back(I->getType());
757 HasLiveReturnedArg =
true;
759 push_back(AttributeSet::get(F->
getContext(), Params.size(), B));
762 ++NumArgumentsEliminated;
763 DEBUG(
dbgs() <<
"DAE - Removing argument " << i <<
" (" << I->getName()
764 <<
") from " << F->
getName() <<
"\n");
775 std::vector<Type*> RetTypes;
796 if (RetTy->
isVoidTy() || HasLiveReturnedArg) {
802 for (
unsigned i = 0; i != RetCount; ++i) {
803 RetOrArg
Ret = CreateRet(F, i);
804 if (LiveValues.erase(Ret)) {
806 NewRetIdxs[i] = RetTypes.size() - 1;
808 ++NumRetValsEliminated;
809 DEBUG(
dbgs() <<
"DAE - Removing return value " << i <<
" from "
815 if (LiveValues.erase(CreateRet(F, 0))) {
816 RetTypes.push_back(RetTy);
821 ++NumRetValsEliminated;
823 if (RetTypes.size() > 1)
831 else if (RetTypes.size() == 1)
834 NRetTy = RetTypes.front();
835 else if (RetTypes.size() == 0)
840 assert(NRetTy &&
"No new return type found?");
851 AttributeSet::get(NRetTy->
getContext(), AttributeSet::ReturnIndex,
853 removeAttributes(AttributeFuncs::
855 AttributeSet::ReturnIndex));
857 assert(!
AttrBuilder(RAttrs, AttributeSet::ReturnIndex).
858 hasAttributes(AttributeFuncs::
860 AttributeSet::ReturnIndex) &&
861 "Return attributes no longer compatible?");
892 std::vector<Value*> Args;
897 AttributesVec.
clear();
905 AttributeSet::get(NF->
getContext(), AttributeSet::ReturnIndex,
907 removeAttributes(AttributeFuncs::
909 AttributeSet::ReturnIndex),
910 AttributeSet::ReturnIndex));
934 push_back(AttributeSet::get(F->
getContext(), Args.size(), B));
944 push_back(AttributeSet::get(F->
getContext(), Args.size(), B));
949 AttributesVec.
push_back(AttributeSet::get(Call->getContext(),
956 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
959 cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
960 cast<InvokeInst>(New)->setAttributes(NewCallPAL);
963 cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
964 cast<CallInst>(New)->setAttributes(NewCallPAL);
965 if (cast<CallInst>(Call)->isTailCall())
966 cast<CallInst>(New)->setTailCall();
968 New->setDebugLoc(Call->getDebugLoc());
972 if (!Call->use_empty()) {
973 if (New->getType() == Call->getType()) {
975 Call->replaceAllUsesWith(New);
977 }
else if (New->getType()->isVoidTy()) {
980 if (!Call->getType()->isX86_MMXTy())
984 "Return type changed, but not into a void. The old return type"
985 " must have been a struct!");
987 if (
InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
989 while (isa<PHINode>(IP)) ++IP;
999 for (
unsigned i = 0; i != RetCount; ++i)
1000 if (NewRetIdxs[i] != -1) {
1002 if (RetTypes.size() > 1)
1015 Call->replaceAllUsesWith(RetVal);
1016 New->takeName(Call);
1022 Call->eraseFromParent();
1038 I->replaceAllUsesWith(I2);
1044 if (!I->getType()->isX86_MMXTy())
1052 if (
ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
1055 if (NFTy->getReturnType()->isVoidTy()) {
1064 Value *OldRet = RI->getOperand(0);
1067 for (
unsigned i = 0; i != RetCount; ++i)
1068 if (NewRetIdxs[i] != -1) {
1071 if (RetTypes.size() > 1) {
1087 BB->getInstList().erase(RI);
1091 FunctionDIMap::iterator DI = FunctionDIs.find(F);
1092 if (DI != FunctionDIs.end())
1093 DI->second.replaceFunction(NF);
1101 bool DAE::runOnModule(
Module &M) {
1102 bool Changed =
false;
1105 CollectFunctionDIs(M);
1111 DEBUG(
dbgs() <<
"DAE - Deleting dead varargs\n");
1115 Changed |= DeleteDeadVarargs(F);
1122 DEBUG(
dbgs() <<
"DAE - Determining liveness\n");
1132 Changed |= RemoveDeadStuffFromFunction(F);
1140 Changed |= RemoveDeadArgumentsFromCallers(F);
void push_back(const T &Elt)
LinkageTypes getLinkage() const
static PassRegistry * getPassRegistry()
LLVMContext & getContext() const
LLVM Argument representation.
The main container class for the LLVM Intermediate Representation.
unsigned getNumParams() const
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
named_metadata_iterator named_metadata_end()
void operator<(const Optional< T > &X, const Optional< U > &Y)
Poison comparison between two Optional objects. Clients needs to explicitly compare the underlying va...
Type * getReturnType() const
MDNode - a tuple of other values.
STATISTIC(NumArgumentsEliminated,"Number of unread args removed")
void setDebugLoc(const DebugLoc &Loc)
setDebugLoc - Set the debug location information for this instruction.
AttributeSet getRetAttributes() const
The attributes for the ret value are returned.
static Constant * getNullValue(Type *Ty)
StringRef getName() const
DIArray - This descriptor holds an array of descriptors.
ModulePass * createDeadArgHackingPass()
param_iterator param_end() const
void copyAttributesFrom(const GlobalValue *Src)
ID
LLVM Calling Convention Representation.
AttributeSet typeIncompatible(Type *Ty, uint64_t Index)
Which attributes cannot be applied to a type.
DISubprogram - This is a wrapper for a subprogram (e.g. a function).
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
static std::string utostr(uint64_t X, bool isNeg=false)
void replaceAllUsesWith(Value *V)
bool hasAddressTaken(const User **=0) const
static bool isWeakForLinker(LinkageTypes Linkage)
User::op_iterator arg_iterator
unsigned getNumSlots() const
Return the number of slots used in this attribute list. This is the number of arguments that have an ...
value_use_iterator< User > use_iterator
static unsigned getAggregateOperandIndex()
static bool mayBeOverridden(LinkageTypes Linkage)
AttributeSet getSlotAttributes(unsigned Slot) const
Return the attributes at the given slot.
DIDescriptor getElement(unsigned Idx) const
Type * getElementType(unsigned N) const
param_iterator param_begin() const
ModulePass * createDeadArgEliminationPass()
static InvokeInst * Create(Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=0)
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.
static Type * getVoidTy(LLVMContext &C)
MDNode * getOperand(unsigned i) const
getOperand - Return specified operand.
iterator insert(iterator where, NodeTy *New)
unsigned getNumElements() const
unsigned getOperandNo() const
static UndefValue * get(Type *T)
static CallInst * Create(Value *Func, ArrayRef< Value * > Args, const Twine &NameStr="", Instruction *InsertBefore=0)
bool hasByValAttr() const
Return true if this argument has the byval attribute on it in its containing function.
const FunctionListType & getFunctionList() const
Get the Module's list of functions (constant).
static Constant * getBitCast(Constant *C, Type *Ty)
static unsigned NumRetVals(const Function *F)
const BasicBlockListType & getBasicBlockList() const
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
void splice(iterator where, iplist &L2)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
AttributeSet getAttributes() const
Return the attribute list for this Function.
INITIALIZE_PASS(DAH,"deadarghaX0r","Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)", false, false) ModulePass *llvm
static InsertValueInst * Create(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &NameStr="", Instruction *InsertBefore=0)
PointerType * getType() const
getType - Global values are always pointers.
bool isDeclaration() const
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.
ImmutableCallSite - establish a view to a call site for examination.
FunctionType * getFunctionType() const
virtual void eraseFromParent()
static ReturnInst * Create(LLVMContext &C, Value *retVal=0, Instruction *InsertBefore=0)
void setAttributes(AttributeSet attrs)
Set the attribute list for this Function.
bool hasLocalLinkage() const
NamedMDListType::iterator named_metadata_iterator
The named metadata iterators.
Type * getReturnType() const
void removeDeadConstantUsers() const
LLVM Value Representation.
unsigned getArgNo() const
Return the index of this formal argument in its containing function.
unsigned getNumOperands() const
getNumOperands - Return the number of NamedMDNode operands.
bool operator==(uint64_t V1, const APInt &V2)
DICompileUnit - A wrapper for a compile unit.
bool isEmpty() const
Return true if there are no attributes.
named_metadata_iterator named_metadata_begin()
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=0)
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
AttributeSet getFnAttributes() const
The function attributes are returned.