1193323Sed//===- InlineAlways.cpp - Code to inline always_inline functions ----------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements a custom inliner that handles only functions that
11193323Sed// are marked as "always inline".
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#define DEBUG_TYPE "inline"
16249423Sdim#include "llvm/Transforms/IPO.h"
17249423Sdim#include "llvm/ADT/SmallPtrSet.h"
18193323Sed#include "llvm/Analysis/CallGraph.h"
19198090Srdivacky#include "llvm/Analysis/InlineCost.h"
20249423Sdim#include "llvm/IR/CallingConv.h"
21249423Sdim#include "llvm/IR/DataLayout.h"
22249423Sdim#include "llvm/IR/Instructions.h"
23249423Sdim#include "llvm/IR/IntrinsicInst.h"
24249423Sdim#include "llvm/IR/Module.h"
25249423Sdim#include "llvm/IR/Type.h"
26193323Sed#include "llvm/Support/CallSite.h"
27193323Sed#include "llvm/Transforms/IPO/InlinerPass.h"
28193323Sed
29193323Sedusing namespace llvm;
30193323Sed
31193323Sednamespace {
32193323Sed
33249423Sdim/// \brief Inliner pass which only handles "always inline" functions.
34249423Sdimclass AlwaysInliner : public Inliner {
35249423Sdim  InlineCostAnalysis *ICA;
36249423Sdim
37249423Sdimpublic:
38249423Sdim  // Use extremely low threshold.
39249423Sdim  AlwaysInliner() : Inliner(ID, -2000000000, /*InsertLifetime*/ true), ICA(0) {
40249423Sdim    initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry());
41249423Sdim  }
42249423Sdim
43249423Sdim  AlwaysInliner(bool InsertLifetime)
44249423Sdim      : Inliner(ID, -2000000000, InsertLifetime), ICA(0) {
45249423Sdim    initializeAlwaysInlinerPass(*PassRegistry::getPassRegistry());
46249423Sdim  }
47249423Sdim
48249423Sdim  static char ID; // Pass identification, replacement for typeid
49249423Sdim
50249423Sdim  virtual InlineCost getInlineCost(CallSite CS);
51249423Sdim
52249423Sdim  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
53249423Sdim  virtual bool runOnSCC(CallGraphSCC &SCC);
54249423Sdim
55249423Sdim  using llvm::Pass::doFinalization;
56249423Sdim  virtual bool doFinalization(CallGraph &CG) {
57249423Sdim    return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/ true);
58249423Sdim  }
59249423Sdim};
60249423Sdim
61193323Sed}
62193323Sed
63193323Sedchar AlwaysInliner::ID = 0;
64218893SdimINITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline",
65218893Sdim                "Inliner for always_inline functions", false, false)
66263508SdimINITIALIZE_PASS_DEPENDENCY(CallGraph)
67249423SdimINITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis)
68218893SdimINITIALIZE_PASS_END(AlwaysInliner, "always-inline",
69218893Sdim                "Inliner for always_inline functions", false, false)
70193323Sed
71193323SedPass *llvm::createAlwaysInlinerPass() { return new AlwaysInliner(); }
72193323Sed
73234353SdimPass *llvm::createAlwaysInlinerPass(bool InsertLifetime) {
74234353Sdim  return new AlwaysInliner(InsertLifetime);
75234353Sdim}
76234353Sdim
77234353Sdim/// \brief Get the inline cost for the always-inliner.
78234353Sdim///
79234353Sdim/// The always inliner *only* handles functions which are marked with the
80234353Sdim/// attribute to force inlining. As such, it is dramatically simpler and avoids
81234353Sdim/// using the powerful (but expensive) inline cost analysis. Instead it uses
82234353Sdim/// a very simple and boring direct walk of the instructions looking for
83234353Sdim/// impossible-to-inline constructs.
84234353Sdim///
85234353Sdim/// Note, it would be possible to go to some lengths to cache the information
86234353Sdim/// computed here, but as we only expect to do this for relatively few and
87234353Sdim/// small functions which have the explicit attribute to force inlining, it is
88234353Sdim/// likely not worth it in practice.
89234353SdimInlineCost AlwaysInliner::getInlineCost(CallSite CS) {
90234353Sdim  Function *Callee = CS.getCalledFunction();
91234353Sdim
92249423Sdim  // Only inline direct calls to functions with always-inline attributes
93249423Sdim  // that are viable for inlining. FIXME: We shouldn't even get here for
94249423Sdim  // declarations.
95249423Sdim  if (Callee && !Callee->isDeclaration() &&
96249423Sdim      Callee->getAttributes().hasAttribute(AttributeSet::FunctionIndex,
97249423Sdim                                           Attribute::AlwaysInline) &&
98249423Sdim      ICA->isInlineViable(*Callee))
99249423Sdim    return InlineCost::getAlways();
100234353Sdim
101249423Sdim  return InlineCost::getNever();
102249423Sdim}
103234353Sdim
104249423Sdimbool AlwaysInliner::runOnSCC(CallGraphSCC &SCC) {
105249423Sdim  ICA = &getAnalysis<InlineCostAnalysis>();
106249423Sdim  return Inliner::runOnSCC(SCC);
107234353Sdim}
108234353Sdim
109249423Sdimvoid AlwaysInliner::getAnalysisUsage(AnalysisUsage &AU) const {
110249423Sdim  AU.addRequired<InlineCostAnalysis>();
111249423Sdim  Inliner::getAnalysisUsage(AU);
112193323Sed}
113