LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PartiallyInlineLibCalls.cpp
Go to the documentation of this file.
1 //===--- PartiallyInlineLibCalls.cpp - Partially inline libcalls ----------===//
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 pass tries to partially inline the fast path of well-known library
11 // functions, such as using square-root instructions for cases where sqrt()
12 // does not need to set errno.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #define DEBUG_TYPE "partially-inline-libcalls"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/Pass.h"
23 #include "llvm/Transforms/Scalar.h"
25 
26 using namespace llvm;
27 
28 namespace {
29  class PartiallyInlineLibCalls : public FunctionPass {
30  public:
31  static char ID;
32 
33  PartiallyInlineLibCalls() :
34  FunctionPass(ID) {
36  }
37 
38  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
39  virtual bool runOnFunction(Function &F);
40 
41  private:
42  /// Optimize calls to sqrt.
43  bool optimizeSQRT(CallInst *Call, Function *CalledFunc,
44  BasicBlock &CurrBB, Function::iterator &BB);
45  };
46 
48 }
49 
50 INITIALIZE_PASS(PartiallyInlineLibCalls, "partially-inline-libcalls",
51  "Partially inline calls to library functions", false, false)
52 
53 void PartiallyInlineLibCalls::getAnalysisUsage(AnalysisUsage &AU) const {
54  AU.addRequired<TargetLibraryInfo>();
55  AU.addRequired<TargetTransformInfo>();
57 }
58 
59 bool PartiallyInlineLibCalls::runOnFunction(Function &F) {
60  bool Changed = false;
61  Function::iterator CurrBB;
62  TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
63  const TargetTransformInfo *TTI = &getAnalysis<TargetTransformInfo>();
64  for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) {
65  CurrBB = BB++;
66 
67  for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end();
68  II != IE; ++II) {
69  CallInst *Call = dyn_cast<CallInst>(&*II);
70  Function *CalledFunc;
71 
72  if (!Call || !(CalledFunc = Call->getCalledFunction()))
73  continue;
74 
75  // Skip if function either has local linkage or is not a known library
76  // function.
77  LibFunc::Func LibFunc;
78  if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() ||
79  !TLI->getLibFunc(CalledFunc->getName(), LibFunc))
80  continue;
81 
82  switch (LibFunc) {
83  case LibFunc::sqrtf:
84  case LibFunc::sqrt:
85  if (TTI->haveFastSqrt(Call->getType()) &&
86  optimizeSQRT(Call, CalledFunc, *CurrBB, BB))
87  break;
88  continue;
89  default:
90  continue;
91  }
92 
93  Changed = true;
94  break;
95  }
96  }
97 
98  return Changed;
99 }
100 
101 bool PartiallyInlineLibCalls::optimizeSQRT(CallInst *Call,
102  Function *CalledFunc,
103  BasicBlock &CurrBB,
104  Function::iterator &BB) {
105  // There is no need to change the IR, since backend will emit sqrt
106  // instruction if the call has already been marked read-only.
107  if (Call->onlyReadsMemory())
108  return false;
109 
110  // Do the following transformation:
111  //
112  // (before)
113  // dst = sqrt(src)
114  //
115  // (after)
116  // v0 = sqrt_noreadmem(src) # native sqrt instruction.
117  // if (v0 is a NaN)
118  // v1 = sqrt(src) # library call.
119  // dst = phi(v0, v1)
120  //
121 
122  // Move all instructions following Call to newly created block JoinBB.
123  // Create phi and replace all uses.
124  BasicBlock *JoinBB = llvm::SplitBlock(&CurrBB, Call->getNextNode(), this);
125  IRBuilder<> Builder(JoinBB, JoinBB->begin());
126  PHINode *Phi = Builder.CreatePHI(Call->getType(), 2);
127  Call->replaceAllUsesWith(Phi);
128 
129  // Create basic block LibCallBB and insert a call to library function sqrt.
130  BasicBlock *LibCallBB = BasicBlock::Create(CurrBB.getContext(), "call.sqrt",
131  CurrBB.getParent(), JoinBB);
132  Builder.SetInsertPoint(LibCallBB);
133  Instruction *LibCall = Call->clone();
134  Builder.Insert(LibCall);
135  Builder.CreateBr(JoinBB);
136 
137  // Add attribute "readnone" so that backend can use a native sqrt instruction
138  // for this call. Insert a FP compare instruction and a conditional branch
139  // at the end of CurrBB.
140  Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
141  CurrBB.getTerminator()->eraseFromParent();
142  Builder.SetInsertPoint(&CurrBB);
143  Value *FCmp = Builder.CreateFCmpOEQ(Call, Call);
144  Builder.CreateCondBr(FCmp, JoinBB, LibCallBB);
145 
146  // Add phi operands.
147  Phi->addIncoming(Call, &CurrBB);
148  Phi->addIncoming(LibCall, LibCallBB);
149 
150  BB = JoinBB;
151  return true;
152 }
153 
155  return new PartiallyInlineLibCalls();
156 }
static PassRegistry * getPassRegistry()
iterator end()
Definition: Function.h:397
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:266
virtual void getAnalysisUsage(AnalysisUsage &) const
Definition: Pass.cpp:75
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:116
F(f)
float sqrtf(float x);
iterator begin()
Definition: BasicBlock.h:193
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
NodeTy * getNextNode()
Get the next node, or 0 for the list tail.
Definition: ilist_node.h:80
bool getLibFunc(StringRef funcName, LibFunc::Func &F) const
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:421
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
Instruction * clone() const
Function does not access memory.
Definition: Attributes.h:93
double sqrt(double x);
void replaceAllUsesWith(Value *V)
Definition: Value.cpp:303
iterator begin()
Definition: Function.h:395
void addAttribute(unsigned i, Attribute::AttrKind attr)
addAttribute - adds the attribute to the list of attributes.
LLVM Basic Block Representation.
Definition: BasicBlock.h:72
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:153
Type * getType() const
Definition: Value.h:111
Function * getCalledFunction() const
BasicBlock * SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P)
FunctionPass * createPartiallyInlineLibCallsPass()
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:120
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
Definition: BasicBlock.h:109
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:33
LLVM Value Representation.
Definition: Value.h:66
void initializePartiallyInlineLibCallsPass(PassRegistry &)