Chris Lattner | 62b7fd1 | 2002-04-07 20:49:59 +0000 | [diff] [blame] | 1 | //===- FunctionInlining.cpp - Code to perform function inlining -----------===// |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 2 | // |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 3 | // This file implements bottom-up inlining of functions into callees. |
Chris Lattner | 1c8d3f8 | 2002-04-18 18:52:03 +0000 | [diff] [blame] | 4 | // |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 5 | //===----------------------------------------------------------------------===// |
| 6 | |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 7 | #define DEBUG_TYPE "inline" |
Chris Lattner | 1666751 | 2002-11-19 20:59:41 +0000 | [diff] [blame] | 8 | #include "llvm/Transforms/IPO.h" |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 9 | #include "llvm/Module.h" |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 10 | #include "llvm/Pass.h" |
Chris Lattner | 2f7c963 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 11 | #include "llvm/iOther.h" |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 12 | #include "llvm/iMemory.h" |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 13 | #include "llvm/iTerminators.h" |
| 14 | #include "llvm/Support/CallSite.h" |
| 15 | #include "llvm/Transforms/Utils/Cloning.h" |
Chris Lattner | fbfcf01 | 2003-06-28 15:57:04 +0000 | [diff] [blame] | 16 | #include "Support/CommandLine.h" |
Chris Lattner | 8abcd56 | 2003-08-01 22:15:03 +0000 | [diff] [blame] | 17 | #include "Support/Debug.h" |
| 18 | #include "Support/Statistic.h" |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 19 | #include <set> |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 20 | |
| 21 | namespace { |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 22 | Statistic<> NumInlined("inline", "Number of functions inlined"); |
Chris Lattner | 9c5bfd0 | 2003-08-24 05:03:14 +0000 | [diff] [blame] | 23 | Statistic<> NumDeleted("inline", "Number of functions deleted because all callers found"); |
Chris Lattner | fbfcf01 | 2003-06-28 15:57:04 +0000 | [diff] [blame] | 24 | cl::opt<unsigned> // FIXME: 200 is VERY conservative |
| 25 | InlineLimit("inline-threshold", cl::Hidden, cl::init(200), |
| 26 | cl::desc("Control the amount of inlining to perform (default = 200)")); |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 27 | |
| 28 | struct FunctionInlining : public Pass { |
| 29 | virtual bool run(Module &M) { |
| 30 | bool Changed = false; |
| 31 | for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) |
| 32 | Changed |= doInlining(I); |
| 33 | ProcessedFunctions.clear(); |
| 34 | return Changed; |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 35 | } |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 36 | |
| 37 | private: |
| 38 | std::set<Function*> ProcessedFunctions; // Prevent infinite recursion |
| 39 | bool doInlining(Function *F); |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 40 | }; |
Chris Lattner | c8b7092 | 2002-07-26 21:12:46 +0000 | [diff] [blame] | 41 | RegisterOpt<FunctionInlining> X("inline", "Function Integration/Inlining"); |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 42 | } |
| 43 | |
Chris Lattner | c8e6654 | 2002-04-27 06:56:12 +0000 | [diff] [blame] | 44 | Pass *createFunctionInliningPass() { return new FunctionInlining(); } |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 45 | |
| 46 | |
| 47 | // ShouldInlineFunction - The heuristic used to determine if we should inline |
| 48 | // the function call or not. |
| 49 | // |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 50 | static inline bool ShouldInlineFunction(CallSite CS) { |
| 51 | Instruction *TheCall = CS.getInstruction(); |
| 52 | assert(TheCall->getParent() && TheCall->getParent()->getParent() && |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 53 | "Call not embedded into a function!"); |
| 54 | |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 55 | const Function *Callee = CS.getCalledFunction(); |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 56 | if (Callee == 0 || Callee->isExternal()) |
| 57 | return false; // Cannot inline an indirect call... or external function. |
| 58 | |
| 59 | // Don't inline a recursive call. |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 60 | const Function *Caller = TheCall->getParent()->getParent(); |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 61 | if (Caller == Callee) return false; |
| 62 | |
| 63 | // InlineQuality - This value measures how good of an inline candidate this |
| 64 | // call site is to inline. The initial value determines how aggressive the |
| 65 | // inliner is. If this value is negative after the final computation, |
| 66 | // inlining is not performed. |
| 67 | // |
Chris Lattner | fbfcf01 | 2003-06-28 15:57:04 +0000 | [diff] [blame] | 68 | int InlineQuality = InlineLimit; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 69 | |
| 70 | // If there is only one call of the function, and it has internal linkage, |
| 71 | // make it almost guaranteed to be inlined. |
| 72 | // |
| 73 | if (Callee->use_size() == 1 && Callee->hasInternalLinkage()) |
| 74 | InlineQuality += 30000; |
| 75 | |
| 76 | // Add to the inline quality for properties that make the call valueable to |
| 77 | // inline. This includes factors that indicate that the result of inlining |
| 78 | // the function will be optimizable. Currently this just looks at arguments |
| 79 | // passed into the function. |
| 80 | // |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 81 | for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); |
| 82 | I != E; ++I) { |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 83 | // Each argument passed in has a cost at both the caller and the callee |
| 84 | // sides. This favors functions that take many arguments over functions |
| 85 | // that take few arguments. |
| 86 | InlineQuality += 20; |
| 87 | |
| 88 | // If this is a function being passed in, it is very likely that we will be |
| 89 | // able to turn an indirect function call into a direct function call. |
| 90 | if (isa<Function>(I)) |
| 91 | InlineQuality += 100; |
| 92 | |
| 93 | // If a constant, global variable or alloca is passed in, inlining this |
| 94 | // function is likely to allow significant future optimization possibilities |
| 95 | // (constant propagation, scalar promotion, and scalarization), so encourage |
| 96 | // the inlining of the function. |
| 97 | // |
| 98 | else if (isa<Constant>(I) || isa<GlobalVariable>(I) || isa<AllocaInst>(I)) |
| 99 | InlineQuality += 60; |
| 100 | } |
| 101 | |
| 102 | // Now that we have considered all of the factors that make the call site more |
| 103 | // likely to be inlined, look at factors that make us not want to inline it. |
| 104 | // As soon as the inline quality gets negative, bail out. |
| 105 | |
| 106 | // Look at the size of the callee. Each basic block counts as 20 units, and |
| 107 | // each instruction counts as 10. |
| 108 | for (Function::const_iterator BB = Callee->begin(), E = Callee->end(); |
| 109 | BB != E; ++BB) { |
| 110 | InlineQuality -= BB->size()*10 + 20; |
| 111 | if (InlineQuality < 0) return false; |
| 112 | } |
| 113 | |
| 114 | // Don't inline into something too big, which would make it bigger. Here, we |
| 115 | // count each basic block as a single unit. |
| 116 | for (Function::const_iterator BB = Caller->begin(), E = Caller->end(); |
| 117 | BB != E; ++BB) { |
| 118 | --InlineQuality; |
| 119 | if (InlineQuality < 0) return false; |
| 120 | } |
| 121 | |
| 122 | // If we get here, this call site is high enough "quality" to inline. |
| 123 | DEBUG(std::cerr << "Inlining in '" << Caller->getName() |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 124 | << "', quality = " << InlineQuality << ": " << *TheCall); |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 125 | return true; |
| 126 | } |
| 127 | |
| 128 | |
| 129 | // doInlining - Use a heuristic based approach to inline functions that seem to |
| 130 | // look good. |
| 131 | // |
| 132 | bool FunctionInlining::doInlining(Function *F) { |
| 133 | // If we have already processed this function (ie, it is recursive) don't |
| 134 | // revisit. |
| 135 | std::set<Function*>::iterator PFI = ProcessedFunctions.lower_bound(F); |
| 136 | if (PFI != ProcessedFunctions.end() && *PFI == F) return false; |
| 137 | |
| 138 | // Insert the function in the set so it doesn't get revisited. |
| 139 | ProcessedFunctions.insert(PFI, F); |
| 140 | |
| 141 | bool Changed = false; |
| 142 | for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) |
| 143 | for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ) { |
| 144 | bool ShouldInc = true; |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 145 | // Found a call or invoke instruction? |
| 146 | if (isa<CallInst>(I) || isa<InvokeInst>(I)) { |
| 147 | CallSite CS = CallSite::get(I); |
| 148 | if (Function *Callee = CS.getCalledFunction()) { |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 149 | doInlining(Callee); // Inline in callees before callers! |
| 150 | |
Chris Lattner | 9c5bfd0 | 2003-08-24 05:03:14 +0000 | [diff] [blame] | 151 | // Decide whether we should inline this function... |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 152 | if (ShouldInlineFunction(CS)) { |
Chris Lattner | 9c5bfd0 | 2003-08-24 05:03:14 +0000 | [diff] [blame] | 153 | // Save an iterator to the instruction before the call if it exists, |
| 154 | // otherwise get an iterator at the end of the block... because the |
| 155 | // call will be destroyed. |
| 156 | // |
| 157 | BasicBlock::iterator SI; |
| 158 | if (I != BB->begin()) { |
| 159 | SI = I; --SI; // Instruction before the call... |
| 160 | } else { |
| 161 | SI = BB->end(); |
| 162 | } |
| 163 | |
| 164 | // Attempt to inline the function... |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame^] | 165 | if (InlineFunction(CS)) { |
Chris Lattner | 9c5bfd0 | 2003-08-24 05:03:14 +0000 | [diff] [blame] | 166 | ++NumInlined; |
| 167 | Changed = true; |
| 168 | // Move to instruction before the call... |
| 169 | I = (SI == BB->end()) ? BB->begin() : SI; |
| 170 | ShouldInc = false; // Don't increment iterator until next time |
| 171 | |
| 172 | // If we inlined the last possible call site to the function, |
| 173 | // delete the function body now. |
| 174 | if (Callee->use_empty() && |
| 175 | (Callee->hasInternalLinkage()||Callee->hasLinkOnceLinkage())){ |
| 176 | F->getParent()->getFunctionList().erase(Callee); |
| 177 | ++NumDeleted; |
| 178 | if (Callee == F) return true; |
| 179 | } |
| 180 | } |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 181 | } |
| 182 | } |
| 183 | } |
| 184 | if (ShouldInc) ++I; |
| 185 | } |
| 186 | |
| 187 | return Changed; |
| 188 | } |
| 189 | |