LLVM  4.0.0
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 
19 #include "llvm/IR/IRBuilder.h"
20 #include "llvm/Transforms/Scalar.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "partially-inline-libcalls"
26 
27 
28 static bool optimizeSQRT(CallInst *Call, Function *CalledFunc,
29  BasicBlock &CurrBB, Function::iterator &BB) {
30  // There is no need to change the IR, since backend will emit sqrt
31  // instruction if the call has already been marked read-only.
32  if (Call->onlyReadsMemory())
33  return false;
34 
35  // The call must have the expected result type.
36  if (!Call->getType()->isFloatingPointTy())
37  return false;
38 
39  // Do the following transformation:
40  //
41  // (before)
42  // dst = sqrt(src)
43  //
44  // (after)
45  // v0 = sqrt_noreadmem(src) # native sqrt instruction.
46  // if (v0 is a NaN)
47  // v1 = sqrt(src) # library call.
48  // dst = phi(v0, v1)
49  //
50 
51  // Move all instructions following Call to newly created block JoinBB.
52  // Create phi and replace all uses.
53  BasicBlock *JoinBB = llvm::SplitBlock(&CurrBB, Call->getNextNode());
54  IRBuilder<> Builder(JoinBB, JoinBB->begin());
55  PHINode *Phi = Builder.CreatePHI(Call->getType(), 2);
56  Call->replaceAllUsesWith(Phi);
57 
58  // Create basic block LibCallBB and insert a call to library function sqrt.
59  BasicBlock *LibCallBB = BasicBlock::Create(CurrBB.getContext(), "call.sqrt",
60  CurrBB.getParent(), JoinBB);
61  Builder.SetInsertPoint(LibCallBB);
62  Instruction *LibCall = Call->clone();
63  Builder.Insert(LibCall);
64  Builder.CreateBr(JoinBB);
65 
66  // Add attribute "readnone" so that backend can use a native sqrt instruction
67  // for this call. Insert a FP compare instruction and a conditional branch
68  // at the end of CurrBB.
69  Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
70  CurrBB.getTerminator()->eraseFromParent();
71  Builder.SetInsertPoint(&CurrBB);
72  Value *FCmp = Builder.CreateFCmpOEQ(Call, Call);
73  Builder.CreateCondBr(FCmp, JoinBB, LibCallBB);
74 
75  // Add phi operands.
76  Phi->addIncoming(Call, &CurrBB);
77  Phi->addIncoming(LibCall, LibCallBB);
78 
79  BB = JoinBB->getIterator();
80  return true;
81 }
82 
84  const TargetTransformInfo *TTI) {
85  bool Changed = false;
86 
87  Function::iterator CurrBB;
88  for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) {
89  CurrBB = BB++;
90 
91  for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end();
92  II != IE; ++II) {
93  CallInst *Call = dyn_cast<CallInst>(&*II);
94  Function *CalledFunc;
95 
96  if (!Call || !(CalledFunc = Call->getCalledFunction()))
97  continue;
98 
99  // Skip if function either has local linkage or is not a known library
100  // function.
101  LibFunc::Func LibFunc;
102  if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() ||
103  !TLI->getLibFunc(CalledFunc->getName(), LibFunc))
104  continue;
105 
106  switch (LibFunc) {
107  case LibFunc::sqrtf:
108  case LibFunc::sqrt:
109  if (TTI->haveFastSqrt(Call->getType()) &&
110  optimizeSQRT(Call, CalledFunc, *CurrBB, BB))
111  break;
112  continue;
113  default:
114  continue;
115  }
116 
117  Changed = true;
118  break;
119  }
120  }
121 
122  return Changed;
123 }
124 
127  auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
128  auto &TTI = AM.getResult<TargetIRAnalysis>(F);
129  if (!runPartiallyInlineLibCalls(F, &TLI, &TTI))
130  return PreservedAnalyses::all();
131  return PreservedAnalyses::none();
132 }
133 
134 namespace {
135 class PartiallyInlineLibCallsLegacyPass : public FunctionPass {
136 public:
137  static char ID;
138 
139  PartiallyInlineLibCallsLegacyPass() : FunctionPass(ID) {
142  }
143 
144  void getAnalysisUsage(AnalysisUsage &AU) const override {
148  }
149 
150  bool runOnFunction(Function &F) override {
151  if (skipFunction(F))
152  return false;
153 
154  TargetLibraryInfo *TLI =
155  &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
156  const TargetTransformInfo *TTI =
157  &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
158  return runPartiallyInlineLibCalls(F, TLI, TTI);
159  }
160 };
161 }
162 
164 INITIALIZE_PASS_BEGIN(PartiallyInlineLibCallsLegacyPass,
165  "partially-inline-libcalls",
166  "Partially inline calls to library functions", false,
167  false)
170 INITIALIZE_PASS_END(PartiallyInlineLibCallsLegacyPass,
171  "partially-inline-libcalls",
172  "Partially inline calls to library functions", false, false)
173 
175  return new PartiallyInlineLibCallsLegacyPass();
176 }
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:76
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:274
BasicBlock * SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the specified block at the specified instruction - everything before SplitPt stays in Old and e...
iterator end()
Definition: Function.h:537
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:84
This class represents a function call, abstracting a target machine's calling convention.
libcalls Conditionally eliminate dead library calls
Analysis pass providing the TargetTransformInfo.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:100
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:228
partially inline Partially calls to library functions
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:588
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following: ...
FunctionPass * createPartiallyInlineLibCallsPass()
#define F(x, y, z)
Definition: MD5.cpp:51
bool isFloatingPointTy() const
Return true if this is one of the six floating-point types.
Definition: Type.h:160
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:401
iterator begin()
Definition: Function.h:535
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:110
bool getLibFunc(StringRef funcName, LibFunc::Func &F) const
Searches for a particular function name.
Wrapper pass for TargetTransformInfo.
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:107
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:653
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
static bool runPartiallyInlineLibCalls(Function &F, TargetLibraryInfo *TLI, const TargetTransformInfo *TTI)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:93
self_iterator getIterator()
Definition: ilist_node.h:81
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:113
static bool optimizeSQRT(CallInst *Call, Function *CalledFunc, BasicBlock &CurrBB, Function::iterator &BB)
INITIALIZE_PASS_BEGIN(PartiallyInlineLibCallsLegacyPass,"partially-inline-libcalls","Partially inline calls to library functions", false, false) INITIALIZE_PASS_END(PartiallyInlineLibCallsLegacyPass
Iterator for intrusive lists based on ilist_node.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
Provides information about what library functions are available for the current target.
always inline
Function * getCalledFunction() const
Return the function called, or null if this is an indirect function invocation.
bool haveFastSqrt(Type *Ty) const
Return true if the hardware has a fast square-root instruction.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:124
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
Analysis pass providing the TargetLibraryInfo.
partially inline Partially calls to library false
partially inline libcalls
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:33
LLVM Value Representation.
Definition: Value.h:71
A container for analyses that lazily runs them and caches their results.
void addAttribute(unsigned i, Attribute::AttrKind Kind)
adds the attribute to the list of attributes.
This pass exposes codegen information to IR-level passes.
void initializePartiallyInlineLibCallsLegacyPassPass(PassRegistry &)