Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 1 | //===- InlineSimple.cpp - Code to perform simple function inlining --------===// |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 2 | // |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 3 | // This file implements bottom-up inlining of functions into callees. |
Chris Lattner | 0154505 | 2002-04-18 18:52:03 +0000 | [diff] [blame] | 4 | // |
Chris Lattner | 0095054 | 2001-06-06 20:29:01 +0000 | [diff] [blame] | 5 | //===----------------------------------------------------------------------===// |
| 6 | |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 7 | #include "Inliner.h" |
| 8 | #include "llvm/Function.h" |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 9 | #include "llvm/iMemory.h" |
Chris Lattner | e544533 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 10 | #include "llvm/Support/CallSite.h" |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 11 | #include "llvm/Transforms/IPO.h" |
Chris Lattner | bd0ef77 | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 12 | |
| 13 | namespace { |
Chris Lattner | 884d6c4 | 2003-10-06 15:52:43 +0000 | [diff] [blame] | 14 | // FunctionInfo - For each function, calculate the size of it in blocks and |
| 15 | // instructions. |
| 16 | struct FunctionInfo { |
| 17 | unsigned NumInsts, NumBlocks; |
| 18 | |
| 19 | FunctionInfo() : NumInsts(0), NumBlocks(0) {} |
| 20 | }; |
| 21 | |
| 22 | class SimpleInliner : public Inliner { |
| 23 | std::map<const Function*, FunctionInfo> CachedFunctionInfo; |
| 24 | public: |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 25 | int getInlineCost(CallSite CS); |
Chris Lattner | bd0ef77 | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 26 | }; |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 27 | RegisterOpt<SimpleInliner> X("inline", "Function Integration/Inlining"); |
Chris Lattner | bd0ef77 | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 28 | } |
| 29 | |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 30 | Pass *createFunctionInliningPass() { return new SimpleInliner(); } |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 31 | |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 32 | // getInlineCost - The heuristic used to determine if we should inline the |
| 33 | // function call or not. |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 34 | // |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 35 | int SimpleInliner::getInlineCost(CallSite CS) { |
Chris Lattner | e544533 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 36 | Instruction *TheCall = CS.getInstruction(); |
Chris Lattner | e544533 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 37 | const Function *Callee = CS.getCalledFunction(); |
Chris Lattner | e544533 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 38 | const Function *Caller = TheCall->getParent()->getParent(); |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 39 | |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 40 | // Don't inline a directly recursive call. |
| 41 | if (Caller == Callee) return 2000000000; |
| 42 | |
| 43 | // InlineCost - This value measures how good of an inline candidate this call |
| 44 | // site is to inline. A lower inline cost make is more likely for the call to |
| 45 | // be inlined. This value may go negative. |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 46 | // |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 47 | int InlineCost = 0; |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 48 | |
| 49 | // If there is only one call of the function, and it has internal linkage, |
| 50 | // make it almost guaranteed to be inlined. |
| 51 | // |
| 52 | if (Callee->use_size() == 1 && Callee->hasInternalLinkage()) |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 53 | InlineCost -= 30000; |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 54 | |
Misha Brukman | cf00c4a | 2003-10-10 17:57:28 +0000 | [diff] [blame^] | 55 | // Add to the inline quality for properties that make the call valuable to |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 56 | // inline. This includes factors that indicate that the result of inlining |
| 57 | // the function will be optimizable. Currently this just looks at arguments |
| 58 | // passed into the function. |
| 59 | // |
Chris Lattner | e544533 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 60 | for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); |
| 61 | I != E; ++I) { |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 62 | // Each argument passed in has a cost at both the caller and the callee |
| 63 | // sides. This favors functions that take many arguments over functions |
| 64 | // that take few arguments. |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 65 | InlineCost -= 20; |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 66 | |
| 67 | // If this is a function being passed in, it is very likely that we will be |
| 68 | // able to turn an indirect function call into a direct function call. |
| 69 | if (isa<Function>(I)) |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 70 | InlineCost -= 100; |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 71 | |
| 72 | // If a constant, global variable or alloca is passed in, inlining this |
| 73 | // function is likely to allow significant future optimization possibilities |
| 74 | // (constant propagation, scalar promotion, and scalarization), so encourage |
| 75 | // the inlining of the function. |
| 76 | // |
| 77 | else if (isa<Constant>(I) || isa<GlobalVariable>(I) || isa<AllocaInst>(I)) |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 78 | InlineCost -= 60; |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | // Now that we have considered all of the factors that make the call site more |
| 82 | // likely to be inlined, look at factors that make us not want to inline it. |
Chris Lattner | 884d6c4 | 2003-10-06 15:52:43 +0000 | [diff] [blame] | 83 | FunctionInfo &CalleeFI = CachedFunctionInfo[Callee]; |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 84 | |
Chris Lattner | 884d6c4 | 2003-10-06 15:52:43 +0000 | [diff] [blame] | 85 | // If we haven't calculated this information yet... |
| 86 | if (CalleeFI.NumBlocks == 0) { |
| 87 | unsigned NumInsts = 0, NumBlocks = 0; |
| 88 | |
| 89 | // Look at the size of the callee. Each basic block counts as 20 units, and |
| 90 | // each instruction counts as 10. |
| 91 | for (Function::const_iterator BB = Callee->begin(), E = Callee->end(); |
| 92 | BB != E; ++BB) { |
| 93 | NumInsts += BB->size(); |
| 94 | NumBlocks++; |
| 95 | } |
| 96 | CalleeFI.NumBlocks = NumBlocks; |
| 97 | CalleeFI.NumInsts = NumInsts; |
| 98 | } |
| 99 | |
Chris Lattner | da78b00 | 2003-10-07 19:33:31 +0000 | [diff] [blame] | 100 | // Don't inline into something too big, which would make it bigger. Here, we |
| 101 | // count each basic block as a single unit. |
| 102 | InlineCost += Caller->size()*2; |
| 103 | |
| 104 | |
| 105 | // Look at the size of the callee. Each basic block counts as 20 units, and |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 106 | // each instruction counts as 10. |
Chris Lattner | 884d6c4 | 2003-10-06 15:52:43 +0000 | [diff] [blame] | 107 | InlineCost += CalleeFI.NumInsts*10 + CalleeFI.NumBlocks*20; |
Chris Lattner | 237ef56 | 2003-08-31 19:10:30 +0000 | [diff] [blame] | 108 | return InlineCost; |
Chris Lattner | ca398dc | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 109 | } |