//===- InlineSimple.cpp - Code to perform simple function inlining --------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements bottom-up inlining of functions into callees.
//
//===----------------------------------------------------------------------===//
-#include "Inliner.h"
+#define DEBUG_TYPE "inline"
+#include "llvm/CallingConv.h"
#include "llvm/Instructions.h"
-#include "llvm/Function.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
#include "llvm/Type.h"
+#include "llvm/Analysis/CallGraph.h"
#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/InlinerPass.h"
+#include <set>
+
using namespace llvm;
namespace {
- struct ArgInfo {
+ struct VISIBILITY_HIDDEN ArgInfo {
unsigned ConstantWeight;
unsigned AllocaWeight;
// FunctionInfo - For each function, calculate the size of it in blocks and
// instructions.
- struct FunctionInfo {
- // HasAllocas - Keep track of whether or not a function contains an alloca
- // instruction that is not in the entry block of the function. Inlining
- // this call could cause us to blow out the stack, because the stack memory
- // would never be released.
- //
- // FIXME: LLVM needs a way of dealloca'ing memory, which would make this
- // irrelevant!
- //
- bool HasAllocas;
-
+ struct VISIBILITY_HIDDEN FunctionInfo {
// NumInsts, NumBlocks - Keep track of how large each function is, which is
// used to estimate the code size cost of inlining it.
unsigned NumInsts, NumBlocks;
// entry here.
std::vector<ArgInfo> ArgumentWeights;
- FunctionInfo() : HasAllocas(false), NumInsts(0), NumBlocks(0) {}
+ FunctionInfo() : NumInsts(0), NumBlocks(0) {}
/// analyzeFunction - Fill in the current structure with information gleaned
/// from the specified function.
void analyzeFunction(Function *F);
};
- class SimpleInliner : public Inliner {
+ class VISIBILITY_HIDDEN SimpleInliner : public Inliner {
std::map<const Function*, FunctionInfo> CachedFunctionInfo;
+ std::set<const Function*> NeverInline; // Functions that are never inlined
public:
+ SimpleInliner() : Inliner(&ID) {}
+ static char ID; // Pass identification, replacement for typeid
int getInlineCost(CallSite CS);
+ virtual bool doInitialization(CallGraph &CG);
};
- RegisterOpt<SimpleInliner> X("inline", "Function Integration/Inlining");
+ char SimpleInliner::ID = 0;
+ RegisterPass<SimpleInliner> X("inline", "Function Integration/Inlining");
}
-ModulePass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
+Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
// CountCodeReductionForConstant - Figure out an approximation for how many
// instructions will be constant folded if the specified value is constant.
if (AllOperandsConstant) {
// We will get to remove this instruction...
Reduction += 7;
-
+
// And any other instructions that use it which become constants
// themselves.
Reduction += CountCodeReductionForConstant(&Inst);
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
II != E; ++II) {
- ++NumInsts;
-
- // If there is an alloca in the body of the function, we cannot currently
- // inline the function without the risk of exploding the stack.
- if (isa<AllocaInst>(II) && BB != F->begin()) {
- HasAllocas = true;
- this->NumBlocks = this->NumInsts = 1;
- return;
+ if (isa<DbgInfoIntrinsic>(II)) continue; // Debug intrinsics don't count.
+
+ // Noop casts, including ptr <-> int, don't count.
+ if (const CastInst *CI = dyn_cast<CastInst>(II)) {
+ if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) ||
+ isa<PtrToIntInst>(CI))
+ continue;
+ } else if (const GetElementPtrInst *GEPI =
+ dyn_cast<GetElementPtrInst>(II)) {
+ // If a GEP has all constant indices, it will probably be folded with
+ // a load/store.
+ bool AllConstant = true;
+ for (unsigned i = 1, e = GEPI->getNumOperands(); i != e; ++i)
+ if (!isa<ConstantInt>(GEPI->getOperand(i))) {
+ AllConstant = false;
+ break;
+ }
+ if (AllConstant) continue;
}
+
+ ++NumInsts;
}
++NumBlocks;
// Check out all of the arguments to the function, figuring out how much
// code can be eliminated if one of the arguments is a constant.
- for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
ArgumentWeights.push_back(ArgInfo(CountCodeReductionForConstant(I),
CountCodeReductionForAlloca(I)));
}
// Don't inline a directly recursive call.
if (Caller == Callee) return 2000000000;
+ // Don't inline functions marked noinline
+ if (NeverInline.count(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.
if (Callee->hasInternalLinkage() && Callee->hasOneUse())
InlineCost -= 30000;
+ // If this function uses the coldcc calling convention, prefer not to inline
+ // it.
+ if (Callee->getCallingConv() == CallingConv::Cold)
+ InlineCost += 2000;
+
+ // If the instruction after the call, or if the normal destination of the
+ // invoke is an unreachable instruction, the function is noreturn. As such,
+ // there is little point in inlining this.
+ if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
+ if (isa<UnreachableInst>(II->getNormalDest()->begin()))
+ InlineCost += 10000;
+ } else if (isa<UnreachableInst>(++BasicBlock::iterator(TheCall)))
+ InlineCost += 10000;
+
// Get information about the callee...
FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
if (CalleeFI.NumBlocks == 0)
CalleeFI.analyzeFunction(Callee);
- // Don't inline calls to functions with allocas that are not in the entry
- // block of the function.
- if (CalleeFI.HasAllocas)
- return 2000000000;
-
// Add to the inline quality for properties that make the call valuable to
// inline. This includes factors that indicate that the result of inlining
// the function will be optimizable. Currently this just looks at arguments
// significant future optimization possibilities (like scalar promotion, and
// scalarization), so encourage the inlining of the function.
//
- else if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
+ else if (isa<AllocaInst>(I)) {
if (ArgNo < CalleeFI.ArgumentWeights.size())
InlineCost -= CalleeFI.ArgumentWeights[ArgNo].AllocaWeight;
return InlineCost;
}
+// doInitialization - Initializes the vector of functions that have been
+// annotated with the noinline attribute.
+bool SimpleInliner::doInitialization(CallGraph &CG) {
+
+ Module &M = CG.getModule();
+
+ // Get llvm.noinline
+ GlobalVariable *GV = M.getNamedGlobal("llvm.noinline");
+
+ if (GV == 0)
+ return false;
+
+ const ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+
+ if (InitList == 0)
+ return false;
+
+ // Iterate over each element and add to the NeverInline set
+ for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+
+ // Get Source
+ const Constant *Elt = InitList->getOperand(i);
+
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Elt))
+ if (CE->getOpcode() == Instruction::BitCast)
+ Elt = CE->getOperand(0);
+
+ // Insert into set of functions to never inline
+ if (const Function *F = dyn_cast<Function>(Elt))
+ NeverInline.insert(F);
+ }
+
+ return false;
+}