diff options
Diffstat (limited to 'lib/Transforms/IPO/InlineSimple.cpp')
-rw-r--r-- | lib/Transforms/IPO/InlineSimple.cpp | 87 |
1 files changed, 42 insertions, 45 deletions
diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp index 51cde2e799..d720c3c2cc 100644 --- a/lib/Transforms/IPO/InlineSimple.cpp +++ b/lib/Transforms/IPO/InlineSimple.cpp @@ -1,26 +1,23 @@ -//===- MethodInlining.cpp - Code to perform method inlining ---------------===// +//===- FunctionInlining.cpp - Code to perform function inlining -----------===// // -// This file implements inlining of methods. +// This file implements inlining of functions. // // Specifically, this: -// * Exports functionality to inline any method call -// * Inlines methods that consist of a single basic block -// * Is able to inline ANY method call -// . Has a smart heuristic for when to inline a method +// * Exports functionality to inline any function call +// * Inlines functions that consist of a single basic block +// * Is able to inline ANY function call +// . Has a smart heuristic for when to inline a function // // Notice that: // * This pass opens up a lot of opportunities for constant propogation. It // is a good idea to to run a constant propogation pass, then a DCE pass // sometime after running this pass. // -// TODO: Currently this throws away all of the symbol names in the method being -// inlined. This shouldn't happen. -// //===----------------------------------------------------------------------===// #include "llvm/Transforms/MethodInlining.h" #include "llvm/Module.h" -#include "llvm/Method.h" +#include "llvm/Function.h" #include "llvm/Pass.h" #include "llvm/iTerminators.h" #include "llvm/iPHINode.h" @@ -53,7 +50,7 @@ static inline void RemapInstruction(Instruction *I, } } -// InlineMethod - This function forcibly inlines the called method into the +// InlineMethod - This function forcibly inlines the called function into the // basic block of the caller. This returns false if it is not possible to // inline this call. The program is still in a well defined state if this // occurs though. @@ -61,16 +58,16 @@ static inline void RemapInstruction(Instruction *I, // Note that this only does one level of inlining. For example, if the // instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now // exists in the instruction stream. Similiarly this will inline a recursive -// method by one level. +// function by one level. // bool InlineMethod(BasicBlock::iterator CIIt) { assert(isa<CallInst>(*CIIt) && "InlineMethod only works on CallInst nodes!"); assert((*CIIt)->getParent() && "Instruction not embedded in basic block!"); - assert((*CIIt)->getParent()->getParent() && "Instruction not in method!"); + assert((*CIIt)->getParent()->getParent() && "Instruction not in function!"); CallInst *CI = cast<CallInst>(*CIIt); const Function *CalledMeth = CI->getCalledFunction(); - if (CalledMeth == 0 || // Can't inline external method or indirect call! + if (CalledMeth == 0 || // Can't inline external function or indirect call! CalledMeth->isExternal()) return false; //cerr << "Inlining " << CalledMeth->getName() << " into " @@ -90,7 +87,7 @@ bool InlineMethod(BasicBlock::iterator CIIt) { // If we have a return value generated by this call, convert it into a PHI // node that gets values from each of the old RET instructions in the original - // method. + // function. // PHINode *PHI = 0; if (CalledMeth->getReturnType() != Type::VoidTy) { @@ -107,26 +104,26 @@ bool InlineMethod(BasicBlock::iterator CIIt) { CI->replaceAllUsesWith(PHI); } - // Keep a mapping between the original method's values and the new duplicated - // code's values. This includes all of: Method arguments, instruction values, - // constant pool entries, and basic blocks. + // Keep a mapping between the original function's values and the new + // duplicated code's values. This includes all of: Function arguments, + // instruction values, constant pool entries, and basic blocks. // std::map<const Value *, Value*> ValueMap; - // Add the method arguments to the mapping: (start counting at 1 to skip the - // method reference itself) + // Add the function arguments to the mapping: (start counting at 1 to skip the + // function reference itself) // - Method::ArgumentListType::const_iterator PTI = + Function::ArgumentListType::const_iterator PTI = CalledMeth->getArgumentList().begin(); for (unsigned a = 1, E = CI->getNumOperands(); a != E; ++a, ++PTI) ValueMap[*PTI] = CI->getOperand(a); ValueMap[NewBB] = NewBB; // Returns get converted to reference NewBB - // Loop over all of the basic blocks in the method, inlining them as - // appropriate. Keep track of the first basic block of the method... + // Loop over all of the basic blocks in the function, inlining them as + // appropriate. Keep track of the first basic block of the function... // - for (Method::const_iterator BI = CalledMeth->begin(); + for (Function::const_iterator BI = CalledMeth->begin(); BI != CalledMeth->end(); ++BI) { const BasicBlock *BB = *BI; assert(BB->getTerminator() && "BasicBlock doesn't have terminator!?!?"); @@ -161,7 +158,7 @@ bool InlineMethod(BasicBlock::iterator CIIt) { if (PHI) { // The PHI node should include this value! assert(RI->getReturnValue() && "Ret should have value!"); assert(RI->getReturnValue()->getType() == PHI->getType() && - "Ret value not consistent in method!"); + "Ret value not consistent in function!"); PHI->addIncoming((Value*)RI->getReturnValue(), cast<BasicBlock>(BB)); } @@ -174,16 +171,16 @@ bool InlineMethod(BasicBlock::iterator CIIt) { break; default: - cerr << "MethodInlining: Don't know how to handle terminator: " << TI; + cerr << "FunctionInlining: Don't know how to handle terminator: " << TI; abort(); } } - // Loop over all of the instructions in the method, fixing up operand + // Loop over all of the instructions in the function, fixing up operand // references as we go. This uses ValueMap to do all the hard work. // - for (Method::const_iterator BI = CalledMeth->begin(); + for (Function::const_iterator BI = CalledMeth->begin(); BI != CalledMeth->end(); ++BI) { const BasicBlock *BB = *BI; BasicBlock *NBB = (BasicBlock*)ValueMap[BB]; @@ -197,7 +194,7 @@ bool InlineMethod(BasicBlock::iterator CIIt) { if (PHI) RemapInstruction(PHI, ValueMap); // Fix the PHI node also... // Change the branch that used to go to NewBB to branch to the first basic - // block of the inlined method. + // block of the inlined function. // TerminatorInst *Br = OrigBB->getTerminator(); assert(Br && Br->getOpcode() == Instruction::Br && @@ -220,15 +217,15 @@ bool InlineMethod(CallInst *CI) { return InlineMethod(CallIt); } -static inline bool ShouldInlineMethod(const CallInst *CI, const Method *M) { +static inline bool ShouldInlineFunction(const CallInst *CI, const Function *F) { assert(CI->getParent() && CI->getParent()->getParent() && "Call not embedded into a method!"); // Don't inline a recursive call. - if (CI->getParent()->getParent() == M) return false; + if (CI->getParent()->getParent() == F) return false; // Don't inline something too big. This is a really crappy heuristic - if (M->size() > 3) return false; + if (F->size() > 3) return false; // Don't inline into something too big. This is a **really** crappy heuristic if (CI->getParent()->getParent()->size() > 10) return false; @@ -238,30 +235,30 @@ static inline bool ShouldInlineMethod(const CallInst *CI, const Method *M) { } -static inline bool DoMethodInlining(BasicBlock *BB) { +static inline bool DoFunctionInlining(BasicBlock *BB) { for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { if (CallInst *CI = dyn_cast<CallInst>(*I)) { - // Check to see if we should inline this method - Method *F = CI->getCalledFunction(); - if (F && ShouldInlineMethod(CI, F)) + // Check to see if we should inline this function + Function *F = CI->getCalledFunction(); + if (F && ShouldInlineFunction(CI, F)) return InlineMethod(I); } } return false; } -// doMethodInlining - Use a heuristic based approach to inline methods that +// doFunctionInlining - Use a heuristic based approach to inline functions that // seem to look good. // -static bool doMethodInlining(Method *M) { +static bool doFunctionInlining(Function *F) { bool Changed = false; // Loop through now and inline instructions a basic block at a time... - for (Method::iterator I = M->begin(); I != M->end(); ) - if (DoMethodInlining(*I)) { + for (Function::iterator I = F->begin(); I != F->end(); ) + if (DoFunctionInlining(*I)) { Changed = true; // Iterator is now invalidated by new basic blocks inserted - I = M->begin(); + I = F->begin(); } else { ++I; } @@ -270,11 +267,11 @@ static bool doMethodInlining(Method *M) { } namespace { - struct MethodInlining : public MethodPass { - virtual bool runOnMethod(Method *M) { - return doMethodInlining(M); + struct FunctionInlining : public MethodPass { + virtual bool runOnMethod(Function *F) { + return doFunctionInlining(F); } }; } -Pass *createMethodInliningPass() { return new MethodInlining(); } +Pass *createMethodInliningPass() { return new FunctionInlining(); } |