Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 1 | //===- InlineSimple.cpp - Code to perform simple 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 | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 7 | #include "Inliner.h" |
| 8 | #include "llvm/Function.h" |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 9 | #include "llvm/iMemory.h" |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 10 | #include "llvm/Support/CallSite.h" |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 11 | #include "llvm/Transforms/IPO.h" |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 12 | |
| 13 | namespace { |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 14 | struct SimpleInliner : public Inliner { |
| 15 | int getInlineCost(CallSite CS); |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 16 | }; |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 17 | RegisterOpt<SimpleInliner> X("inline", "Function Integration/Inlining"); |
Chris Lattner | 04805fa | 2002-02-26 21:46:54 +0000 | [diff] [blame] | 18 | } |
| 19 | |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 20 | Pass *createFunctionInliningPass() { return new SimpleInliner(); } |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 21 | |
| 22 | |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 23 | // getInlineCost - The heuristic used to determine if we should inline the |
| 24 | // function call or not. |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 25 | // |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 26 | int SimpleInliner::getInlineCost(CallSite CS) { |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 27 | Instruction *TheCall = CS.getInstruction(); |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 28 | const Function *Callee = CS.getCalledFunction(); |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 29 | const Function *Caller = TheCall->getParent()->getParent(); |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 30 | |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 31 | // Don't inline a directly recursive call. |
| 32 | if (Caller == Callee) return 2000000000; |
| 33 | |
| 34 | // InlineCost - This value measures how good of an inline candidate this call |
| 35 | // site is to inline. A lower inline cost make is more likely for the call to |
| 36 | // be inlined. This value may go negative. |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 37 | // |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 38 | int InlineCost = 0; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 39 | |
| 40 | // If there is only one call of the function, and it has internal linkage, |
| 41 | // make it almost guaranteed to be inlined. |
| 42 | // |
| 43 | if (Callee->use_size() == 1 && Callee->hasInternalLinkage()) |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 44 | InlineCost -= 30000; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 45 | |
| 46 | // Add to the inline quality for properties that make the call valueable to |
| 47 | // inline. This includes factors that indicate that the result of inlining |
| 48 | // the function will be optimizable. Currently this just looks at arguments |
| 49 | // passed into the function. |
| 50 | // |
Chris Lattner | d367d05 | 2003-08-24 06:59:28 +0000 | [diff] [blame] | 51 | for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); |
| 52 | I != E; ++I) { |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 53 | // Each argument passed in has a cost at both the caller and the callee |
| 54 | // sides. This favors functions that take many arguments over functions |
| 55 | // that take few arguments. |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 56 | InlineCost -= 20; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 57 | |
| 58 | // If this is a function being passed in, it is very likely that we will be |
| 59 | // able to turn an indirect function call into a direct function call. |
| 60 | if (isa<Function>(I)) |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 61 | InlineCost -= 100; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 62 | |
| 63 | // If a constant, global variable or alloca is passed in, inlining this |
| 64 | // function is likely to allow significant future optimization possibilities |
| 65 | // (constant propagation, scalar promotion, and scalarization), so encourage |
| 66 | // the inlining of the function. |
| 67 | // |
| 68 | else if (isa<Constant>(I) || isa<GlobalVariable>(I) || isa<AllocaInst>(I)) |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 69 | InlineCost -= 60; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 70 | } |
| 71 | |
| 72 | // Now that we have considered all of the factors that make the call site more |
| 73 | // likely to be inlined, look at factors that make us not want to inline it. |
| 74 | // As soon as the inline quality gets negative, bail out. |
| 75 | |
| 76 | // Look at the size of the callee. Each basic block counts as 20 units, and |
| 77 | // each instruction counts as 10. |
| 78 | for (Function::const_iterator BB = Callee->begin(), E = Callee->end(); |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 79 | BB != E; ++BB) |
| 80 | InlineCost += BB->size()*10 + 20; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 81 | |
| 82 | // Don't inline into something too big, which would make it bigger. Here, we |
| 83 | // count each basic block as a single unit. |
| 84 | for (Function::const_iterator BB = Caller->begin(), E = Caller->end(); |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 85 | BB != E; ++BB) |
| 86 | InlineCost++; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 87 | |
Chris Lattner | d075cc2 | 2003-08-31 19:10:30 +0000 | [diff] [blame^] | 88 | return InlineCost; |
Chris Lattner | 530d4bf | 2003-05-29 15:11:31 +0000 | [diff] [blame] | 89 | } |