blob: 5c8bed585b640c54904850d8e13f7f026daa0722 [file] [log] [blame]
Richard Sandiford37cd6cf2013-08-23 10:27:02 +00001//===--- PartiallyInlineLibCalls.cpp - Partially inline libcalls ----------===//
Akira Hatanaka5c50a162013-06-11 22:21:44 +00002//
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//
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000010// 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.
Akira Hatanaka5c50a162013-06-11 22:21:44 +000013//
14//===----------------------------------------------------------------------===//
15
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000016#include "llvm/Analysis/TargetTransformInfo.h"
Akira Hatanaka5c50a162013-06-11 22:21:44 +000017#include "llvm/IR/IRBuilder.h"
18#include "llvm/IR/Intrinsics.h"
19#include "llvm/Pass.h"
20#include "llvm/Support/CommandLine.h"
21#include "llvm/Target/TargetLibraryInfo.h"
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000022#include "llvm/Transforms/Scalar.h"
Akira Hatanaka5c50a162013-06-11 22:21:44 +000023#include "llvm/Transforms/Utils/BasicBlockUtils.h"
24
25using namespace llvm;
26
Chandler Carruth964daaa2014-04-22 02:55:47 +000027#define DEBUG_TYPE "partially-inline-libcalls"
28
Akira Hatanaka5c50a162013-06-11 22:21:44 +000029namespace {
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000030 class PartiallyInlineLibCalls : public FunctionPass {
Akira Hatanaka5c50a162013-06-11 22:21:44 +000031 public:
32 static char ID;
33
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000034 PartiallyInlineLibCalls() :
35 FunctionPass(ID) {
36 initializePartiallyInlineLibCallsPass(*PassRegistry::getPassRegistry());
Akira Hatanaka5c50a162013-06-11 22:21:44 +000037 }
38
Craig Topper3e4c6972014-03-05 09:10:37 +000039 void getAnalysisUsage(AnalysisUsage &AU) const override;
40 bool runOnFunction(Function &F) override;
Akira Hatanaka5c50a162013-06-11 22:21:44 +000041
42 private:
43 /// Optimize calls to sqrt.
44 bool optimizeSQRT(CallInst *Call, Function *CalledFunc,
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000045 BasicBlock &CurrBB, Function::iterator &BB);
Akira Hatanaka5c50a162013-06-11 22:21:44 +000046 };
47
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000048 char PartiallyInlineLibCalls::ID = 0;
Akira Hatanaka5c50a162013-06-11 22:21:44 +000049}
50
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000051INITIALIZE_PASS(PartiallyInlineLibCalls, "partially-inline-libcalls",
52 "Partially inline calls to library functions", false, false)
Akira Hatanaka5c50a162013-06-11 22:21:44 +000053
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000054void PartiallyInlineLibCalls::getAnalysisUsage(AnalysisUsage &AU) const {
Akira Hatanaka5c50a162013-06-11 22:21:44 +000055 AU.addRequired<TargetLibraryInfo>();
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000056 AU.addRequired<TargetTransformInfo>();
Akira Hatanaka5c50a162013-06-11 22:21:44 +000057 FunctionPass::getAnalysisUsage(AU);
58}
59
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000060bool PartiallyInlineLibCalls::runOnFunction(Function &F) {
Akira Hatanaka5c50a162013-06-11 22:21:44 +000061 bool Changed = false;
62 Function::iterator CurrBB;
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000063 TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
64 const TargetTransformInfo *TTI = &getAnalysis<TargetTransformInfo>();
Akira Hatanaka5c50a162013-06-11 22:21:44 +000065 for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) {
66 CurrBB = BB++;
67
68 for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end();
69 II != IE; ++II) {
70 CallInst *Call = dyn_cast<CallInst>(&*II);
71 Function *CalledFunc;
72
73 if (!Call || !(CalledFunc = Call->getCalledFunction()))
74 continue;
75
Akira Hatanaka5c50a162013-06-11 22:21:44 +000076 // Skip if function either has local linkage or is not a known library
77 // function.
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000078 LibFunc::Func LibFunc;
Akira Hatanaka5c50a162013-06-11 22:21:44 +000079 if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() ||
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000080 !TLI->getLibFunc(CalledFunc->getName(), LibFunc))
Akira Hatanaka5c50a162013-06-11 22:21:44 +000081 continue;
82
83 switch (LibFunc) {
84 case LibFunc::sqrtf:
85 case LibFunc::sqrt:
Richard Sandiford37cd6cf2013-08-23 10:27:02 +000086 if (TTI->haveFastSqrt(Call->getType()) &&
87 optimizeSQRT(Call, CalledFunc, *CurrBB, BB))
Akira Hatanaka5c50a162013-06-11 22:21:44 +000088 break;
89 continue;
90 default:
91 continue;
92 }
93
94 Changed = true;
95 break;
96 }
97 }
98
99 return Changed;
100}
101
Richard Sandiford37cd6cf2013-08-23 10:27:02 +0000102bool PartiallyInlineLibCalls::optimizeSQRT(CallInst *Call,
103 Function *CalledFunc,
104 BasicBlock &CurrBB,
105 Function::iterator &BB) {
Akira Hatanaka5c50a162013-06-11 22:21:44 +0000106 // There is no need to change the IR, since backend will emit sqrt
107 // instruction if the call has already been marked read-only.
108 if (Call->onlyReadsMemory())
109 return false;
110
Peter Collingbournee52646c2014-08-01 23:21:21 +0000111 // The call must have the expected result type.
112 if (!Call->getType()->isFloatingPointTy())
113 return false;
114
Akira Hatanaka5c50a162013-06-11 22:21:44 +0000115 // Do the following transformation:
116 //
117 // (before)
118 // dst = sqrt(src)
119 //
120 // (after)
121 // v0 = sqrt_noreadmem(src) # native sqrt instruction.
122 // if (v0 is a NaN)
123 // v1 = sqrt(src) # library call.
124 // dst = phi(v0, v1)
125 //
126
127 // Move all instructions following Call to newly created block JoinBB.
128 // Create phi and replace all uses.
129 BasicBlock *JoinBB = llvm::SplitBlock(&CurrBB, Call->getNextNode(), this);
130 IRBuilder<> Builder(JoinBB, JoinBB->begin());
131 PHINode *Phi = Builder.CreatePHI(Call->getType(), 2);
132 Call->replaceAllUsesWith(Phi);
133
134 // Create basic block LibCallBB and insert a call to library function sqrt.
135 BasicBlock *LibCallBB = BasicBlock::Create(CurrBB.getContext(), "call.sqrt",
136 CurrBB.getParent(), JoinBB);
137 Builder.SetInsertPoint(LibCallBB);
138 Instruction *LibCall = Call->clone();
139 Builder.Insert(LibCall);
140 Builder.CreateBr(JoinBB);
141
142 // Add attribute "readnone" so that backend can use a native sqrt instruction
143 // for this call. Insert a FP compare instruction and a conditional branch
144 // at the end of CurrBB.
145 Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
146 CurrBB.getTerminator()->eraseFromParent();
147 Builder.SetInsertPoint(&CurrBB);
148 Value *FCmp = Builder.CreateFCmpOEQ(Call, Call);
149 Builder.CreateCondBr(FCmp, JoinBB, LibCallBB);
150
151 // Add phi operands.
152 Phi->addIncoming(Call, &CurrBB);
153 Phi->addIncoming(LibCall, LibCallBB);
154
155 BB = JoinBB;
156 return true;
157}
Richard Sandiford37cd6cf2013-08-23 10:27:02 +0000158
159FunctionPass *llvm::createPartiallyInlineLibCallsPass() {
160 return new PartiallyInlineLibCalls();
161}