X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FDeadArgumentElimination.cpp;h=088269d816d52040ad3d76ac7615b06b5945320c;hb=41e2397b720bc5d917ef614a7a6c257e8a3c8e42;hp=d83f3e027dd2b840e3078ee602b87abd70bfcdf0;hpb=b10308e440c80dd6ffb4b478f741ff7e5f30cb48;p=oota-llvm.git diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index d83f3e027dd..088269d816d 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -26,9 +26,11 @@ #include "llvm/IntrinsicInst.h" #include "llvm/Module.h" #include "llvm/Pass.h" +#include "llvm/ParamAttrsList.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/Compiler.h" #include using namespace llvm; @@ -38,7 +40,7 @@ STATISTIC(NumRetValsEliminated , "Number of unused return values removed"); namespace { /// DAE - The dead argument elimination pass. /// - class DAE : public ModulePass { + class VISIBILITY_HIDDEN DAE : public ModulePass { /// Liveness enum - During our initial pass over the program, we determine /// that things are either definately alive, definately dead, or in need of /// interprocedural analysis (MaybeLive). @@ -75,6 +77,8 @@ namespace { std::multimap CallSites; public: + static char ID; // Pass identification, replacement for typeid + DAE() : ModulePass((intptr_t)&ID) {} bool runOnModule(Module &M); virtual bool ShouldHackArguments() const { return false; } @@ -92,14 +96,17 @@ namespace { void RemoveDeadArgumentsFromFunction(Function *F); }; + char DAE::ID = 0; RegisterPass X("deadargelim", "Dead Argument Elimination"); /// DAH - DeadArgumentHacking pass - Same as dead argument elimination, but /// deletes arguments to functions which are external. This is only for use /// by bugpoint. struct DAH : public DAE { + static char ID; virtual bool ShouldHackArguments() const { return true; } }; + char DAH::ID = 0; RegisterPass Y("deadarghaX0r", "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)"); } @@ -114,19 +121,19 @@ ModulePass *llvm::createDeadArgHackingPass() { return new DAH(); } /// llvm.vastart is never called, the varargs list is dead for the function. bool DAE::DeleteDeadVarargs(Function &Fn) { assert(Fn.getFunctionType()->isVarArg() && "Function isn't varargs!"); - if (Fn.isExternal() || !Fn.hasInternalLinkage()) return false; - + if (Fn.isDeclaration() || !Fn.hasInternalLinkage()) return false; + // Ensure that the function is only directly called. for (Value::use_iterator I = Fn.use_begin(), E = Fn.use_end(); I != E; ++I) { // If this use is anything other than a call site, give up. CallSite CS = CallSite::get(*I); Instruction *TheCall = CS.getInstruction(); if (!TheCall) return false; // Not a direct call site? - + // The addr of this function is passed to the call. if (I.getOperandNo() != 0) return false; } - + // Okay, we know we can transform this function if safe. Scan its body // looking for calls to llvm.vastart. for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) { @@ -137,22 +144,26 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { } } } - + // If we get here, there are no calls to llvm.vastart in the function body, // remove the "..." and adjust all the calls. - + // Start by computing a new prototype for the function, which is the same as // the old function, but has fewer arguments. const FunctionType *FTy = Fn.getFunctionType(); std::vector Params(FTy->param_begin(), FTy->param_end()); FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, false); unsigned NumArgs = Params.size(); - + // Create the new function body and insert it into the module... - Function *NF = new Function(NFTy, Fn.getLinkage(), Fn.getName()); + Function *NF = new Function(NFTy, Fn.getLinkage()); NF->setCallingConv(Fn.getCallingConv()); + NF->setParamAttrs(Fn.getParamAttrs()); + if (Fn.hasCollector()) + NF->setCollector(Fn.getCollector()); Fn.getParent()->getFunctionList().insert(&Fn, NF); - + NF->takeName(&Fn); + // Loop over all of the callers of the function, transforming the call sites // to pass in a smaller number of arguments into the new function. // @@ -160,42 +171,53 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { while (!Fn.use_empty()) { CallSite CS = CallSite::get(Fn.use_back()); Instruction *Call = CS.getInstruction(); - - // Loop over the operands, dropping extraneous ones at the end of the list. + + // Pass all the same arguments. Args.assign(CS.arg_begin(), CS.arg_begin()+NumArgs); - + + // Drop any attributes that were on the vararg arguments. + const ParamAttrsList *PAL = CS.getParamAttrs(); + if (PAL && PAL->getParamIndex(PAL->size() - 1) > NumArgs) { + ParamAttrsVector ParamAttrsVec; + for (unsigned i = 0; PAL->getParamIndex(i) <= NumArgs; ++i) { + ParamAttrsWithIndex PAWI; + PAWI = ParamAttrsWithIndex::get(PAL->getParamIndex(i), + PAL->getParamAttrsAtIndex(i)); + ParamAttrsVec.push_back(PAWI); + } + PAL = ParamAttrsList::get(ParamAttrsVec); + } + Instruction *New; if (InvokeInst *II = dyn_cast(Call)) { New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(), - Args, "", Call); + Args.begin(), Args.end(), "", Call); cast(New)->setCallingConv(CS.getCallingConv()); + cast(New)->setParamAttrs(PAL); } else { - New = new CallInst(NF, Args, "", Call); + New = new CallInst(NF, Args.begin(), Args.end(), "", Call); cast(New)->setCallingConv(CS.getCallingConv()); + cast(New)->setParamAttrs(PAL); if (cast(Call)->isTailCall()) cast(New)->setTailCall(); } Args.clear(); - + if (!Call->use_empty()) - Call->replaceAllUsesWith(Constant::getNullValue(Call->getType())); - - if (Call->hasName()) { - std::string Name = Call->getName(); - Call->setName(""); - New->setName(Name); - } - + Call->replaceAllUsesWith(New); + + New->takeName(Call); + // Finally, remove the old call from the program, reducing the use-count of // F. - Call->getParent()->getInstList().erase(Call); + Call->eraseFromParent(); } - + // Since we have now created the new function, splice the body of the old // function right into the new function, leaving the old rotting hulk of the // function empty. NF->getBasicBlockList().splice(NF->begin(), Fn.getBasicBlockList()); - + // Loop over the argument list, transfering uses of the old arguments over to // the new arguments, also transfering over the names as well. While we're at // it, remove the dead arguments from the DeadArguments list. @@ -204,9 +226,9 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { I2 = NF->arg_begin(); I != E; ++I, ++I2) { // Move the name and users over to the new version. I->replaceAllUsesWith(I2); - I2->setName(I->getName()); + I2->takeName(I); } - + // Finally, nuke the old function. Fn.eraseFromParent(); return true; @@ -230,10 +252,10 @@ static inline bool CallPassesValueThoughVararg(Instruction *Call, // (used in a computation), MaybeLive (only passed as an argument to a call), or // Dead (not used). DAE::Liveness DAE::getArgumentLiveness(const Argument &A) { - const FunctionType *FTy = A.getParent()->getFunctionType(); + const Function *F = A.getParent(); // If this is the return value of a struct function, it's not really dead. - if (FTy->isStructReturn() && &*A.getParent()->arg_begin() == &A) + if (F->hasStructRetAttr() && &*(F->arg_begin()) == &A) return Live; if (A.use_empty()) // First check, directly dead? @@ -277,7 +299,7 @@ void DAE::SurveyFunction(Function &F) { Liveness RetValLiveness = F.getReturnType() == Type::VoidTy ? Live : Dead; if (!F.hasInternalLinkage() && - (!ShouldHackArguments() || F.getIntrinsicID())) + (!ShouldHackArguments() || F.isIntrinsic())) FunctionIntrinsicallyLive = true; else for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) { @@ -485,16 +507,40 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) { const FunctionType *FTy = F->getFunctionType(); std::vector Params; - for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) - if (!DeadArguments.count(I)) - Params.push_back(I->getType()); + // Set up to build a new list of parameter attributes + ParamAttrsVector ParamAttrsVec; + const ParamAttrsList *PAL = F->getParamAttrs(); + // The existing function return attributes. + ParameterAttributes RAttrs = PAL ? PAL->getParamAttrs(0) : ParamAttr::None; + + // Make the function return void if the return value is dead. const Type *RetTy = FTy->getReturnType(); if (DeadRetVal.count(F)) { RetTy = Type::VoidTy; + RAttrs &= ~ParamAttr::typeIncompatible(RetTy); DeadRetVal.erase(F); } + if (RAttrs) + ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, RAttrs)); + + // Construct the new parameter list from non-dead arguments. Also construct + // a new set of parameter attributes to correspond. + unsigned index = 1; + for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; + ++I, ++index) + if (!DeadArguments.count(I)) { + Params.push_back(I->getType()); + ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(index) : + ParamAttr::None; + if (Attrs) + ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Params.size(), Attrs)); + } + + // Reconstruct the ParamAttrsList based on the vector we constructed. + PAL = ParamAttrsList::get(ParamAttrsVec); + // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which // have zero fixed arguments. // @@ -504,12 +550,17 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) { Params.push_back(Type::Int32Ty); } + // Create the new function type based on the recomputed parameters. FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg()); // Create the new function body and insert it into the module... - Function *NF = new Function(NFTy, F->getLinkage(), F->getName()); + Function *NF = new Function(NFTy, F->getLinkage()); NF->setCallingConv(F->getCallingConv()); + NF->setParamAttrs(PAL); + if (F->hasCollector()) + NF->setCollector(F->getCollector()); F->getParent()->getFunctionList().insert(F, NF); + NF->takeName(F); // Loop over all of the callers of the function, transforming the call sites // to pass in a smaller number of arguments into the new function. @@ -518,29 +569,54 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) { while (!F->use_empty()) { CallSite CS = CallSite::get(F->use_back()); Instruction *Call = CS.getInstruction(); + ParamAttrsVec.clear(); + PAL = CS.getParamAttrs(); + + // The call return attributes. + ParameterAttributes RAttrs = PAL ? PAL->getParamAttrs(0) : ParamAttr::None; + // Adjust in case the function was changed to return void. + RAttrs &= ~ParamAttr::typeIncompatible(NF->getReturnType()); + if (RAttrs) + ParamAttrsVec.push_back(ParamAttrsWithIndex::get(0, RAttrs)); // Loop over the operands, deleting dead ones... CallSite::arg_iterator AI = CS.arg_begin(); + index = 1; for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); - I != E; ++I, ++AI) - if (!DeadArguments.count(I)) // Remove operands for dead arguments + I != E; ++I, ++AI, ++index) + if (!DeadArguments.count(I)) { // Remove operands for dead arguments Args.push_back(*AI); + ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(index) : + ParamAttr::None; + if (Attrs) + ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Args.size(), Attrs)); + } if (ExtraArgHack) Args.push_back(UndefValue::get(Type::Int32Ty)); - // Push any varargs arguments on the list - for (; AI != CS.arg_end(); ++AI) + // Push any varargs arguments on the list. Don't forget their attributes. + for (; AI != CS.arg_end(); ++AI) { Args.push_back(*AI); + ParameterAttributes Attrs = PAL ? PAL->getParamAttrs(index++) : + ParamAttr::None; + if (Attrs) + ParamAttrsVec.push_back(ParamAttrsWithIndex::get(Args.size(), Attrs)); + } + + // Reconstruct the ParamAttrsList based on the vector we constructed. + PAL = ParamAttrsList::get(ParamAttrsVec); Instruction *New; if (InvokeInst *II = dyn_cast(Call)) { New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(), - Args, "", Call); + Args.begin(), Args.end(), "", Call); cast(New)->setCallingConv(CS.getCallingConv()); + cast(New)->setParamAttrs(PAL); } else { - New = new CallInst(NF, Args, "", Call); + New = new CallInst(NF, Args.begin(), Args.end(), "", Call); cast(New)->setCallingConv(CS.getCallingConv()); + cast(New)->setParamAttrs(PAL); if (cast(Call)->isTailCall()) cast(New)->setTailCall(); } @@ -551,9 +627,7 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) { Call->replaceAllUsesWith(Constant::getNullValue(Call->getType())); else { Call->replaceAllUsesWith(New); - std::string Name = Call->getName(); - Call->setName(""); - New->setName(Name); + New->takeName(Call); } } @@ -578,7 +652,7 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) { // If this is a live argument, move the name and users over to the new // version. I->replaceAllUsesWith(I2); - I2->setName(I->getName()); + I2->takeName(I); ++I2; } else { // If this argument is dead, replace any uses of it with null constants @@ -602,23 +676,28 @@ void DAE::RemoveDeadArgumentsFromFunction(Function *F) { } bool DAE::runOnModule(Module &M) { - // First phase: loop through the module, determining which arguments are live. - // We assume all arguments are dead unless proven otherwise (allowing us to - // determine that dead arguments passed into recursive functions are dead). - // - DOUT << "DAE - Determining liveness\n"; + bool Changed = false; + // First pass: Do a simple check to see if any functions can have their "..." + // removed. We can do this if they never call va_start. This loop cannot be + // fused with the next loop, because deleting a function invalidates + // information computed while surveying other functions. + DOUT << "DAE - Deleting dead varargs\n"; for (Module::iterator I = M.begin(), E = M.end(); I != E; ) { Function &F = *I++; if (F.getFunctionType()->isVarArg()) - if (DeleteDeadVarargs(F)) - continue; - - SurveyFunction(F); + Changed |= DeleteDeadVarargs(F); } + + // Second phase:loop through the module, determining which arguments are live. + // We assume all arguments are dead unless proven otherwise (allowing us to + // determine that dead arguments passed into recursive functions are dead). + // + DOUT << "DAE - Determining liveness\n"; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + SurveyFunction(*I); // Loop over the instructions to inspect, propagating liveness among arguments // and return values which are MaybeLive. - while (!InstructionsToInspect.empty()) { Instruction *I = InstructionsToInspect.back(); InstructionsToInspect.pop_back(); @@ -678,7 +757,7 @@ bool DAE::runOnModule(Module &M) { // to do. if (MaybeLiveArguments.empty() && DeadArguments.empty() && MaybeLiveRetVal.empty() && DeadRetVal.empty()) - return false; + return Changed; // Otherwise, compact into one set, and start eliminating the arguments from // the functions.