#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Compiler.h"
#include <set>
using namespace llvm;
namespace {
/// ArgPromotion - The 'by reference' to 'by value' argument promotion pass.
///
- struct ArgPromotion : public CallGraphSCCPass {
+ struct VISIBILITY_HIDDEN ArgPromotion : public CallGraphSCCPass {
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AliasAnalysis>();
AU.addRequired<TargetData>();
}
virtual bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
+ static char ID; // Pass identification, replacement for typeid
+ ArgPromotion() : CallGraphSCCPass((intptr_t)&ID) {}
+
private:
bool PromoteArguments(CallGraphNode *CGN);
bool isSafeToPromoteArgument(Argument *Arg) const;
Function *DoPromotion(Function *F, std::vector<Argument*> &ArgsToPromote);
};
+ char ArgPromotion::ID = 0;
RegisterPass<ArgPromotion> X("argpromotion",
"Promote 'by reference' arguments to scalars");
}
-ModulePass *llvm::createArgumentPromotionPass() {
+Pass *llvm::createArgumentPromotionPass() {
return new ArgPromotion();
}
static bool AllCalleesPassInValidPointerForArgument(Argument *Arg) {
Function *Callee = Arg->getParent();
- unsigned ArgNo = std::distance(Callee->arg_begin(), Function::arg_iterator(Arg));
+ unsigned ArgNo = std::distance(Callee->arg_begin(),
+ Function::arg_iterator(Arg));
// Look at all call sites of the function. At this pointer we know we only
// have direct callees.
// Add a parameter to the function for each element passed in.
for (ScalarizeTable::iterator SI = ArgIndices.begin(),
E = ArgIndices.end(); SI != E; ++SI)
- Params.push_back(GetElementPtrInst::getIndexedType(I->getType(), *SI));
+ Params.push_back(GetElementPtrInst::getIndexedType(I->getType(),
+ &(*SI)[0],
+ SI->size()));
if (ArgIndices.size() == 1 && ArgIndices.begin()->empty())
++NumArgumentsPromoted;
Value *V = *AI;
LoadInst *OrigLoad = OriginalLoads[*SI];
if (!SI->empty()) {
- V = new GetElementPtrInst(V, *SI, V->getName()+".idx", Call);
+ V = new GetElementPtrInst(V, &(*SI)[0], SI->size(),
+ V->getName()+".idx", Call);
AA.copyValue(OrigLoad->getOperand(0), V);
}
Args.push_back(new LoadInst(V, V->getName()+".val", Call));
Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
- Args, "", Call);
+ Args.begin(), Args.end(), "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
} else {
- New = new CallInst(NF, Args, "", Call);
+ New = new CallInst(NF, Args.begin(), Args.end(), "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall();
if (!Call->use_empty()) {
Call->replaceAllUsesWith(New);
- std::string Name = Call->getName();
- Call->setName("");
- New->setName(Name);
+ New->takeName(Call);
}
// Finally, remove the old call from the program, reducing the use-count of
// Loop over the argument list, transfering uses of the old arguments over to
// the new arguments, also transfering over the names as well.
//
- for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(), I2 = NF->arg_begin();
- I != E; ++I)
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(),
+ I2 = NF->arg_begin(); I != E; ++I)
if (!ArgsToPromote.count(I)) {
// If this is an unmodified argument, move the name and users over to the
// new version.
I->replaceAllUsesWith(I2);
- I2->setName(I->getName());
+ I2->takeName(I);
AA.replaceWithNewValue(I, I2);
++I2;
} else if (I->use_empty()) {
std::string NewName = I->getName();
for (unsigned i = 0, e = Operands.size(); i != e; ++i)
if (ConstantInt *CI = dyn_cast<ConstantInt>(Operands[i]))
- NewName += "."+itostr((int64_t)CI->getZExtValue());
+ NewName += "." + CI->getValue().toStringUnsigned(10);
else
NewName += ".x";
TheArg->setName(NewName+".val");