mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	* Separate the policy decisions into a derived class [InlineSimple]
  * Move the inlining mechanics into a base class [Inliner]
  * Change the inliner to be an SCCPass, making it more structured and
    eventually pipelinable with other SCC passes
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8257 91177308-0d34-0410-b5e6-96231b3b80d8
		
	
		
			
				
	
	
		
			90 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===- InlineSimple.cpp - Code to perform simple function inlining --------===//
 | |
| //
 | |
| // This file implements bottom-up inlining of functions into callees.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "Inliner.h"
 | |
| #include "llvm/Function.h"
 | |
| #include "llvm/iMemory.h"
 | |
| #include "llvm/Support/CallSite.h"
 | |
| #include "llvm/Transforms/IPO.h"
 | |
| 
 | |
| namespace {
 | |
|   struct SimpleInliner : public Inliner {
 | |
|     int getInlineCost(CallSite CS);
 | |
|   };
 | |
|   RegisterOpt<SimpleInliner> X("inline", "Function Integration/Inlining");
 | |
| }
 | |
| 
 | |
| Pass *createFunctionInliningPass() { return new SimpleInliner(); }
 | |
| 
 | |
| 
 | |
| // getInlineCost - The heuristic used to determine if we should inline the
 | |
| // function call or not.
 | |
| //
 | |
| int SimpleInliner::getInlineCost(CallSite CS) {
 | |
|   Instruction *TheCall = CS.getInstruction();
 | |
|   const Function *Callee = CS.getCalledFunction();
 | |
|   const Function *Caller = TheCall->getParent()->getParent();
 | |
| 
 | |
|   // Don't inline a directly recursive call.
 | |
|   if (Caller == Callee) return 2000000000;
 | |
| 
 | |
|   // InlineCost - This value measures how good of an inline candidate this call
 | |
|   // site is to inline.  A lower inline cost make is more likely for the call to
 | |
|   // be inlined.  This value may go negative.
 | |
|   //
 | |
|   int InlineCost = 0;
 | |
| 
 | |
|   // If there is only one call of the function, and it has internal linkage,
 | |
|   // make it almost guaranteed to be inlined.
 | |
|   //
 | |
|   if (Callee->use_size() == 1 && Callee->hasInternalLinkage())
 | |
|     InlineCost -= 30000;
 | |
| 
 | |
|   // Add to the inline quality for properties that make the call valueable to
 | |
|   // inline.  This includes factors that indicate that the result of inlining
 | |
|   // the function will be optimizable.  Currently this just looks at arguments
 | |
|   // passed into the function.
 | |
|   //
 | |
|   for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
 | |
|        I != E; ++I) {
 | |
|     // Each argument passed in has a cost at both the caller and the callee
 | |
|     // sides.  This favors functions that take many arguments over functions
 | |
|     // that take few arguments.
 | |
|     InlineCost -= 20;
 | |
| 
 | |
|     // If this is a function being passed in, it is very likely that we will be
 | |
|     // able to turn an indirect function call into a direct function call.
 | |
|     if (isa<Function>(I))
 | |
|       InlineCost -= 100;
 | |
| 
 | |
|     // If a constant, global variable or alloca is passed in, inlining this
 | |
|     // function is likely to allow significant future optimization possibilities
 | |
|     // (constant propagation, scalar promotion, and scalarization), so encourage
 | |
|     // the inlining of the function.
 | |
|     //
 | |
|     else if (isa<Constant>(I) || isa<GlobalVariable>(I) || isa<AllocaInst>(I))
 | |
|       InlineCost -= 60;
 | |
|   }
 | |
| 
 | |
|   // Now that we have considered all of the factors that make the call site more
 | |
|   // likely to be inlined, look at factors that make us not want to inline it.
 | |
|   // As soon as the inline quality gets negative, bail out.
 | |
| 
 | |
|   // Look at the size of the callee.  Each basic block counts as 20 units, and
 | |
|   // each instruction counts as 10.
 | |
|   for (Function::const_iterator BB = Callee->begin(), E = Callee->end();
 | |
|        BB != E; ++BB)
 | |
|     InlineCost += BB->size()*10 + 20;
 | |
| 
 | |
|   // Don't inline into something too big, which would make it bigger.  Here, we
 | |
|   // count each basic block as a single unit.
 | |
|   for (Function::const_iterator BB = Caller->begin(), E = Caller->end();
 | |
|        BB != E; ++BB)
 | |
|     InlineCost++;
 | |
| 
 | |
|   return InlineCost;
 | |
| }
 |