1 //===- SimplifyHalfPowrLibCalls.cpp - Optimize specific half_powr calls ---===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements a simple pass that applies an experimental
11 // transformation on calls to specific functions.
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "simplify-libcalls-halfpowr"
16 #include "llvm/Transforms/Scalar.h"
17 #include "llvm/Instructions.h"
18 #include "llvm/Intrinsics.h"
19 #include "llvm/Module.h"
20 #include "llvm/Pass.h"
21 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
22 #include "llvm/Transforms/Utils/Cloning.h"
23 #include "llvm/Target/TargetData.h"
24 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/Support/Debug.h"
29 /// This pass optimizes well half_powr function calls.
31 class SimplifyHalfPowrLibCalls
: public FunctionPass
{
34 static char ID
; // Pass identification
35 SimplifyHalfPowrLibCalls() : FunctionPass(&ID
) {}
37 bool runOnFunction(Function
&F
);
39 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
43 InlineHalfPowrs(const std::vector
<Instruction
*> &HalfPowrs
,
44 Instruction
*InsertPt
);
46 char SimplifyHalfPowrLibCalls::ID
= 0;
47 } // end anonymous namespace.
49 static RegisterPass
<SimplifyHalfPowrLibCalls
>
50 X("simplify-libcalls-halfpowr", "Simplify half_powr library calls");
52 // Public interface to the Simplify HalfPowr LibCalls pass.
53 FunctionPass
*llvm::createSimplifyHalfPowrLibCallsPass() {
54 return new SimplifyHalfPowrLibCalls();
57 /// InlineHalfPowrs - Inline a sequence of adjacent half_powr calls, rearranging
58 /// their control flow to better facilitate subsequent optimization.
60 SimplifyHalfPowrLibCalls::
61 InlineHalfPowrs(const std::vector
<Instruction
*> &HalfPowrs
,
62 Instruction
*InsertPt
) {
63 std::vector
<BasicBlock
*> Bodies
;
64 BasicBlock
*NewBlock
= 0;
66 for (unsigned i
= 0, e
= HalfPowrs
.size(); i
!= e
; ++i
) {
67 CallInst
*Call
= cast
<CallInst
>(HalfPowrs
[i
]);
68 Function
*Callee
= Call
->getCalledFunction();
70 // Minimally sanity-check the CFG of half_powr to ensure that it contains
71 // the the kind of code we expect. If we're running this pass, we have
72 // reason to believe it will be what we expect.
73 Function::iterator I
= Callee
->begin();
74 BasicBlock
*Prologue
= I
++;
75 if (I
== Callee
->end()) break;
76 BasicBlock
*SubnormalHandling
= I
++;
77 if (I
== Callee
->end()) break;
78 BasicBlock
*Body
= I
++;
79 if (I
!= Callee
->end()) break;
80 if (SubnormalHandling
->getSinglePredecessor() != Prologue
)
82 BranchInst
*PBI
= dyn_cast
<BranchInst
>(Prologue
->getTerminator());
83 if (!PBI
|| !PBI
->isConditional())
85 BranchInst
*SNBI
= dyn_cast
<BranchInst
>(SubnormalHandling
->getTerminator());
86 if (!SNBI
|| SNBI
->isConditional())
88 if (!isa
<ReturnInst
>(Body
->getTerminator()))
91 Instruction
*NextInst
= next(BasicBlock::iterator(Call
));
93 // Inline the call, taking care of what code ends up where.
94 NewBlock
= SplitBlock(NextInst
->getParent(), NextInst
, this);
96 bool B
= InlineFunction(Call
, 0, TD
);
97 assert(B
&& "half_powr didn't inline?"); B
=B
;
99 BasicBlock
*NewBody
= NewBlock
->getSinglePredecessor();
101 Bodies
.push_back(NewBody
);
107 // Put the code for all the bodies into one block, to facilitate
108 // subsequent optimization.
109 (void)SplitEdge(NewBlock
->getSinglePredecessor(), NewBlock
, this);
110 for (unsigned i
= 0, e
= Bodies
.size(); i
!= e
; ++i
) {
111 BasicBlock
*Body
= Bodies
[i
];
112 Instruction
*FNP
= Body
->getFirstNonPHI();
113 // Splice the insts from body into NewBlock.
114 NewBlock
->getInstList().splice(NewBlock
->begin(), Body
->getInstList(),
115 FNP
, Body
->getTerminator());
118 return NewBlock
->begin();
121 /// runOnFunction - Top level algorithm.
123 bool SimplifyHalfPowrLibCalls::runOnFunction(Function
&F
) {
124 TD
= getAnalysisIfAvailable
<TargetData
>();
126 bool Changed
= false;
127 std::vector
<Instruction
*> HalfPowrs
;
128 for (Function::iterator BB
= F
.begin(), E
= F
.end(); BB
!= E
; ++BB
) {
129 for (BasicBlock::iterator I
= BB
->begin(), E
= BB
->end(); I
!= E
; ++I
) {
131 bool IsHalfPowr
= false;
132 if (CallInst
*CI
= dyn_cast
<CallInst
>(I
)) {
133 // Look for direct calls and calls to non-external functions.
134 Function
*Callee
= CI
->getCalledFunction();
135 if (Callee
&& Callee
->hasExternalLinkage()) {
136 // Look for calls with well-known names.
137 if (Callee
->getName() == "__half_powrf4")
142 HalfPowrs
.push_back(I
);
143 // We're looking for sequences of up to three such calls, which we'll
144 // simplify as a group.
145 if ((!IsHalfPowr
&& !HalfPowrs
.empty()) || HalfPowrs
.size() == 3) {
146 I
= InlineHalfPowrs(HalfPowrs
, I
);
147 E
= I
->getParent()->end();
152 assert(HalfPowrs
.empty() && "Block had no terminator!");