diff options
author | Chris Lattner <sabre@nondot.org> | 2002-10-08 22:19:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-10-08 22:19:25 +0000 |
commit | 61b92c02b4d59366fdb97dfdb7ad94d8b1b6baf1 (patch) | |
tree | c2e67bf48d51a02c0fa1410c1ff64b58ffd4a8bf /lib | |
parent | 8576bd6220eccd0c84eb01493c5d225e3c939981 (diff) | |
download | external_llvm-61b92c02b4d59366fdb97dfdb7ad94d8b1b6baf1.zip external_llvm-61b92c02b4d59366fdb97dfdb7ad94d8b1b6baf1.tar.gz external_llvm-61b92c02b4d59366fdb97dfdb7ad94d8b1b6baf1.tar.bz2 |
- Fix bug: LevelRaise/2002-10-08-VarArgCall.ll
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4083 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/LevelRaise.cpp | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp index 4af53be..f246116 100644 --- a/lib/Transforms/LevelRaise.cpp +++ b/lib/Transforms/LevelRaise.cpp @@ -45,6 +45,9 @@ NumCastOfCast("raise", "Number of cast-of-self removed"); static Statistic<> NumDCEorCP("raise", "Number of insts DCEd or constprop'd"); +static Statistic<> +NumVarargCallChanges("raise", "Number of vararg call peepholes"); + #define PRINT_PEEPHOLE(ID, NUM, I) \ DEBUG(std::cerr << "Inst P/H " << ID << "[" << NUM << "] " << I) @@ -253,7 +256,8 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { // source type of the cast... // ConvertedTypes.clear(); - ConvertedTypes[Src] = Src->getType(); // Make sure the source doesn't change type + // Make sure the source doesn't change type + ConvertedTypes[Src] = Src->getType(); if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes)) { PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent()); @@ -454,6 +458,40 @@ static bool PeepholeOptimize(BasicBlock *BB, BasicBlock::iterator &BI) { ++NumGEPInstFormed; return true; } + } else if (CallInst *CI = dyn_cast<CallInst>(I)) { + // If we have a call with all varargs arguments, convert the call to use the + // actual argument types present... + // + const PointerType *PTy = cast<PointerType>(CI->getCalledValue()->getType()); + const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); + + // Is the call to a vararg variable with no real parameters? + if (FTy->isVarArg() && FTy->getNumParams() == 0) { + // If so, insert a new cast instruction, casting it to a function type + // that matches the current arguments... + // + std::vector<const Type *> Params; // Parameter types... + for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i) + Params.push_back(CI->getOperand(i)->getType()); + + FunctionType *NewFT = FunctionType::get(FTy->getReturnType(), + Params, false); + PointerType *NewPFunTy = PointerType::get(NewFT); + + // Create a new cast, inserting it right before the function call... + CastInst *NewCast = new CastInst(CI->getCalledValue(), NewPFunTy, + CI->getCalledValue()->getName(), CI); + + // Create a new call instruction... + CallInst *NewCall = new CallInst(NewCast, + std::vector<Value*>(CI->op_begin()+1, CI->op_end())); + ++BI; + ReplaceInstWithInst(CI, NewCall); + + ++NumVarargCallChanges; + return true; + } + } return false; |