blob: 38bf0610b3872e84c2b5792cef96db1b77facc24 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
//===- 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.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "inline"
#include "llvm/CallingConv.h"
#include "llvm/Instructions.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 "llvm/Transforms/Utils/InlineCost.h"
#include "llvm/ADT/SmallPtrSet.h"
using namespace llvm;
namespace {
class VISIBILITY_HIDDEN SimpleInliner : public Inliner {
// Functions that are never inlined
SmallPtrSet<const Function*, 16> NeverInline;
InlineCostAnalyzer CA;
public:
SimpleInliner() : Inliner(&ID) {}
static char ID; // Pass identification, replacement for typeid
int getInlineCost(CallSite CS) {
return CA.getInlineCost(CS, NeverInline);
}
virtual bool doInitialization(CallGraph &CG);
};
char SimpleInliner::ID = 0;
RegisterPass<SimpleInliner> X("inline", "Function Integration/Inlining");
}
Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
// 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;
}
|