//===-- DeadArgumentElimination.cpp - Eliminate dead arguments ------------===//
-//
+//
// 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 pass deletes dead arguments from internal functions. Dead argument
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "deadargelim"
#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constant.h"
-#include "llvm/iOther.h"
-#include "llvm/iTerminators.h"
+#include "llvm/Instructions.h"
#include "llvm/Support/CallSite.h"
-#include "Support/Debug.h"
-#include "Support/Statistic.h"
-#include "Support/iterator"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/iterator"
#include <set>
using namespace llvm;
/// DAE - The dead argument elimination pass.
///
- class DAE : public Pass {
+ class 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).
std::multimap<Function*, CallSite> CallSites;
public:
- bool run(Module &M);
+ bool runOnModule(Module &M);
virtual bool ShouldHackArguments() const { return false; }
void MarkArgumentLive(Argument *Arg);
void MarkRetValLive(Function *F);
void MarkReturnInstArgumentLive(ReturnInst *RI);
-
+
void RemoveDeadArgumentsFromFunction(Function *F);
};
RegisterOpt<DAE> X("deadargelim", "Dead Argument Elimination");
/// createDeadArgEliminationPass - This pass removes arguments from functions
/// which are not used by the body of the function.
///
-Pass *llvm::createDeadArgEliminationPass() { return new DAE(); }
-Pass *llvm::createDeadArgHackingPass() { return new DAH(); }
+ModulePass *llvm::createDeadArgEliminationPass() { return new DAE(); }
+ModulePass *llvm::createDeadArgHackingPass() { return new DAH(); }
static inline bool CallPassesValueThoughVararg(Instruction *Call,
const Value *Arg) {
if (!F.hasInternalLinkage() &&
(!ShouldHackArguments() || F.getIntrinsicID()))
FunctionIntrinsicallyLive = true;
- else
+ else
for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) {
// If this use is anything other than a call site, the function is alive.
CallSite CS = CallSite::get(*I);
RetValLiveness = Live;
break;
}
-
+
// If the function is PASSED IN as an argument, its address has been taken
for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
AI != E; ++AI)
if (FunctionIntrinsicallyLive) {
DEBUG(std::cerr << " Intrinsically live fn: " << F.getName() << "\n");
- for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI)
+ for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
+ AI != E; ++AI)
LiveArguments.insert(AI);
LiveRetVal.insert(&F);
return;
// if there are any arguments we assume that are dead.
//
bool AnyMaybeLiveArgs = false;
- for (Function::aiterator AI = F.abegin(), E = F.aend(); AI != E; ++AI)
+ for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
+ AI != E; ++AI)
switch (getArgumentLiveness(*AI)) {
case Live:
DEBUG(std::cerr << " Arg live by use: " << AI->getName() << "\n");
// Loop over all of the arguments (because Arg may be passed into the call
// multiple times) and check to see if any are now alive...
CallSite::arg_iterator CSAI = CS.arg_begin();
- for (Function::aiterator AI = Callee->abegin(), E = Callee->aend();
+ for (Function::arg_iterator AI = Callee->arg_begin(), E = Callee->arg_end();
AI != E; ++AI, ++CSAI)
// If this is the argument we are looking for, check to see if it's alive
if (*CSAI == Arg && LiveArguments.count(AI))
void DAE::MarkArgumentLive(Argument *Arg) {
std::set<Argument*>::iterator It = MaybeLiveArguments.lower_bound(Arg);
if (It == MaybeLiveArguments.end() || *It != Arg) return;
-
+
DEBUG(std::cerr << " MaybeLive argument now live: " << Arg->getName()<<"\n");
MaybeLiveArguments.erase(It);
LiveArguments.insert(Arg);
-
+
// Loop over all of the call sites of the function, making any arguments
// passed in to provide a value for this argument live as necessary.
//
Function *Fn = Arg->getParent();
- unsigned ArgNo = std::distance(Fn->abegin(), Function::aiterator(Arg));
+ unsigned ArgNo = std::distance(Fn->arg_begin(), Function::arg_iterator(Arg));
std::multimap<Function*, CallSite>::iterator I = CallSites.lower_bound(Fn);
for (; I != CallSites.end() && I->first == Fn; ++I) {
const FunctionType *FTy = F->getFunctionType();
std::vector<const Type*> Params;
- for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
if (!DeadArguments.count(I))
Params.push_back(I->getType());
// Create the new function body and insert it into the module...
Function *NF = new Function(NFTy, F->getLinkage(), F->getName());
+ NF->setCallingConv(F->getCallingConv());
F->getParent()->getFunctionList().insert(F, NF);
// Loop over all of the callers of the function, transforming the call sites
// Loop over the operands, deleting dead ones...
CallSite::arg_iterator AI = CS.arg_begin();
- for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I, ++AI)
+ 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
Args.push_back(*AI);
Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
- New = new InvokeInst(NF, II->getNormalDest(), II->getExceptionalDest(),
+ New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
Args, "", Call);
+ cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
} else {
New = new CallInst(NF, Args, "", Call);
+ cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ if (cast<CallInst>(Call)->isTailCall())
+ cast<CallInst>(New)->setTailCall();
}
Args.clear();
New->setName(Name);
}
}
-
+
// Finally, remove the old call from the program, reducing the use-count of
// F.
Call->getParent()->getInstList().erase(Call);
// the new arguments, also transfering over the names as well. While we're at
// it, remove the dead arguments from the DeadArguments list.
//
- for (Function::aiterator I = F->abegin(), E = F->aend(), I2 = NF->abegin();
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(),
+ I2 = NF->arg_begin();
I != E; ++I)
if (!DeadArguments.count(I)) {
// If this is a live argument, move the name and users over to the new
F->getParent()->getFunctionList().erase(F);
}
-bool DAE::run(Module &M) {
+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).
while (!InstructionsToInspect.empty()) {
Instruction *I = InstructionsToInspect.back();
InstructionsToInspect.pop_back();
-
+
if (ReturnInst *RI = dyn_cast<ReturnInst>(I)) {
// For return instructions, we just have to check to see if the return
// value for the current function is known now to be alive. If so, any
assert(CS.getInstruction() && "Unknown instruction for the I2I list!");
Function *Callee = CS.getCalledFunction();
-
+
// If we found a call or invoke instruction on this list, that means that
// an argument of the function is a call instruction. If the argument is
// live, then the return value of the called instruction is now live.
//
CallSite::arg_iterator AI = CS.arg_begin(); // ActualIterator
- for (Function::aiterator FI = Callee->abegin(), E = Callee->aend();
- FI != E; ++AI, ++FI) {
+ for (Function::arg_iterator FI = Callee->arg_begin(),
+ E = Callee->arg_end(); FI != E; ++AI, ++FI) {
// If this argument is another call...
CallSite ArgCS = CallSite::get(*AI);
if (ArgCS.getInstruction() && LiveArguments.count(FI))
if (MaybeLiveArguments.empty() && DeadArguments.empty() &&
MaybeLiveRetVal.empty() && DeadRetVal.empty())
return false;
-
+
// Otherwise, compact into one set, and start eliminating the arguments from
// the functions.
DeadArguments.insert(MaybeLiveArguments.begin(), MaybeLiveArguments.end());