Mercurial > hg > CbC > CbC_llvm
comparison lib/Transforms/IPO/InlineAlways.cpp @ 0:95c75e76d11b LLVM3.4
LLVM 3.4
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 12 Dec 2013 13:56:28 +0900 |
parents | |
children | e4204d083e25 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:95c75e76d11b |
---|---|
1 //===- InlineAlways.cpp - Code to inline always_inline functions ----------===// | |
2 // | |
3 // The LLVM Compiler Infrastructure | |
4 // | |
5 // This file is distributed under the University of Illinois Open Source | |
6 // License. See LICENSE.TXT for details. | |
7 // | |
8 //===----------------------------------------------------------------------===// | |
9 // | |
10 // This file implements a custom inliner that handles only functions that | |
11 // are marked as "always inline". | |
12 // | |
13 //===----------------------------------------------------------------------===// | |
14 | |
15 #define DEBUG_TYPE "inline" | |
16 #include "llvm/Transforms/IPO.h" | |
17 #include "llvm/ADT/SmallPtrSet.h" | |
18 #include "llvm/Analysis/CallGraph.h" | |
19 #include "llvm/Analysis/InlineCost.h" | |
20 #include "llvm/IR/CallingConv.h" | |
21 #include "llvm/IR/DataLayout.h" | |
22 #include "llvm/IR/Instructions.h" | |
23 #include "llvm/IR/IntrinsicInst.h" | |
24 #include "llvm/IR/Module.h" | |
25 #include "llvm/IR/Type.h" | |
26 #include "llvm/Support/CallSite.h" | |
27 #include "llvm/Transforms/IPO/InlinerPass.h" | |
28 | |
29 using namespace llvm; | |
30 | |
31 namespace { | |
32 | |
33 /// \brief Inliner pass which only handles "always inline" functions. | |
34 class AlwaysInliner : public Inliner { | |
35 InlineCostAnalysis *ICA; | |
36 | |
37 public: | |
38 // Use extremely low threshold. | |
39 AlwaysInliner() : Inliner(ID, -2000000000, /*InsertLifetime*/ true), ICA(0) { | |
40 initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); | |
41 } | |
42 | |
43 AlwaysInliner(bool InsertLifetime) | |
44 : Inliner(ID, -2000000000, InsertLifetime), ICA(0) { | |
45 initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry()); | |
46 } | |
47 | |
48 static char ID; // Pass identification, replacement for typeid | |
49 | |
50 virtual InlineCost getInlineCost(CallSite CS); | |
51 | |
52 virtual void getAnalysisUsage(AnalysisUsage &AU) const; | |
53 virtual bool runOnSCC(CallGraphSCC &SCC); | |
54 | |
55 using llvm::Pass::doFinalization; | |
56 virtual bool doFinalization(CallGraph &CG) { | |
57 return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/ true); | |
58 } | |
59 }; | |
60 | |
61 } | |
62 | |
63 char AlwaysInliner::ID = 0; | |
64 INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", | |
65 "Inliner for always_inline functions", false, false) | |
66 INITIALIZE_PASS_DEPENDENCY(CallGraph) | |
67 INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) | |
68 INITIALIZE_PASS_END(AlwaysInliner, "always-inline", | |
69 "Inliner for always_inline functions", false, false) | |
70 | |
71 Pass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); } | |
72 | |
73 Pass *llvm::createAlwaysInlinerPass(bool InsertLifetime) { | |
74 return new AlwaysInliner(InsertLifetime); | |
75 } | |
76 | |
77 /// \brief Get the inline cost for the always-inliner. | |
78 /// | |
79 /// The always inliner *only* handles functions which are marked with the | |
80 /// attribute to force inlining. As such, it is dramatically simpler and avoids | |
81 /// using the powerful (but expensive) inline cost analysis. Instead it uses | |
82 /// a very simple and boring direct walk of the instructions looking for | |
83 /// impossible-to-inline constructs. | |
84 /// | |
85 /// Note, it would be possible to go to some lengths to cache the information | |
86 /// computed here, but as we only expect to do this for relatively few and | |
87 /// small functions which have the explicit attribute to force inlining, it is | |
88 /// likely not worth it in practice. | |
89 InlineCost AlwaysInliner::getInlineCost(CallSite CS) { | |
90 Function *Callee = CS.getCalledFunction(); | |
91 | |
92 // Only inline direct calls to functions with always-inline attributes | |
93 // that are viable for inlining. FIXME: We shouldn't even get here for | |
94 // declarations. | |
95 if (Callee && !Callee->isDeclaration() && | |
96 Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex, | |
97 Attribute::AlwaysInline) && | |
98 ICA->isInlineViable(*Callee)) | |
99 return InlineCost::getAlways(); | |
100 | |
101 return InlineCost::getNever(); | |
102 } | |
103 | |
104 bool AlwaysInliner::runOnSCC(CallGraphSCC &SCC) { | |
105 ICA = &getAnalysis<InlineCostAnalysis>(); | |
106 return Inliner::runOnSCC(SCC); | |
107 } | |
108 | |
109 void AlwaysInliner::getAnalysisUsage(AnalysisUsage &AU) const { | |
110 AU.addRequired<InlineCostAnalysis>(); | |
111 Inliner::getAnalysisUsage(AU); | |
112 } |