llvm.org GIT mirror llvm / 4e65485
Initial commit of (very basic) if converter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37092 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
2 changed file(s) with 307 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
8080 /// branches.
8181 FunctionPass *createBranchFoldingPass();
8282
83 /// IfConverter Pass - This pass performs machine code if conversion.
84 FunctionPass *createIfConverterPass();
85
8386 /// DebugLabelFoldingPass - This pass prunes out redundant debug labels. This
8487 /// allows a debug emitter to determine if the range of two labels is empty,
8588 /// by seeing if the labels map to the same reduced label.
0 //===-- IfConversion.cpp - Machine code if conversion pass. ---------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by the Evan Cheng and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the machine instruction level if-conversion pass.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #define DEBUG_TYPE "ifconversion"
14 #include "llvm/CodeGen/Passes.h"
15 #include "llvm/CodeGen/MachineModuleInfo.h"
16 #include "llvm/CodeGen/MachineFunctionPass.h"
17 #include "llvm/Target/TargetInstrInfo.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/ADT/Statistic.h"
21 using namespace llvm;
22
23 STATISTIC(NumIfConvBBs, "Number of if-converted blocks");
24
25 namespace {
26 class IfConverter : public MachineFunctionPass {
27 enum BBICKind {
28 ICInvalid, // BB data invalid.
29 ICNotClassfied, // BB data valid, but not classified.
30 ICTriangle, // BB is part of a triangle sub-CFG.
31 ICDiamond, // BB is part of a diamond sub-CFG.
32 ICTriangleEntry, // BB is entry of a triangle sub-CFG.
33 ICDiamondEntry // BB is entry of a diamond sub-CFG.
34 };
35
36 /// BBInfo - One per MachineBasicBlock, this is used to cache the result
37 /// if-conversion feasibility analysis. This includes results from
38 /// TargetInstrInfo::AnalyzeBranch() (i.e. TBB, FBB, and Cond), and its
39 /// classification, and common merge block of its successors (if it's a
40 /// diamond shape).
41 struct BBInfo {
42 BBICKind Kind;
43 MachineBasicBlock *EBB;
44 MachineBasicBlock *TBB;
45 MachineBasicBlock *FBB;
46 MachineBasicBlock *CMBB;
47 std::vector Cond;
48 BBInfo() : Kind(ICInvalid), EBB(0), TBB(0), FBB(0), CMBB(0) {}
49 };
50
51 /// BBAnalysis - Results of if-conversion feasibility analysis indexed by
52 /// basic block number.
53 std::vector BBAnalysis;
54
55 const TargetInstrInfo *TII;
56 bool MadeChange;
57 public:
58 static char ID;
59 IfConverter() : MachineFunctionPass((intptr_t)&ID) {}
60
61 virtual bool runOnMachineFunction(MachineFunction &MF);
62 virtual const char *getPassName() const { return "If converter"; }
63
64 private:
65 void AnalyzeBlock(MachineBasicBlock *BB);
66 void InitialFunctionAnalysis(MachineFunction &MF,
67 std::vector &Candidates);
68 bool IfConvertDiamond(BBInfo &BBI);
69 bool IfConvertTriangle(BBInfo &BBI);
70 bool isBlockPredicatable(MachineBasicBlock *BB,
71 bool IgnoreTerm = false) const;
72 void PredicateBlock(MachineBasicBlock *BB,
73 std::vector &Cond,
74 bool IgnoreTerm = false);
75 void MergeBlocks(MachineBasicBlock *TBB, MachineBasicBlock *FBB);
76 };
77 char IfConverter::ID = 0;
78 }
79
80 FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); }
81
82 bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
83 TII = MF.getTarget().getInstrInfo();
84 if (!TII) return false;
85
86 MadeChange = false;
87
88 MF.RenumberBlocks();
89 unsigned NumBBs = MF.getNumBlockIDs();
90 BBAnalysis.resize(NumBBs);
91
92 std::vector Candidates;
93 // Do an intial analysis for each basic block and finding all the potential
94 // candidates to perform if-convesion.
95 InitialFunctionAnalysis(MF, Candidates);
96
97 for (unsigned i = 0, e = Candidates.size(); i != e; ++i) {
98 BBInfo &BBI = BBAnalysis[i];
99 switch (BBI.Kind) {
100 default: assert(false && "Unexpected!");
101 break;
102 case ICTriangleEntry:
103 MadeChange |= IfConvertTriangle(BBI);
104 break;
105 case ICDiamondEntry:
106 MadeChange |= IfConvertDiamond(BBI);
107 break;
108 }
109 }
110 return MadeChange;
111 }
112
113 static MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB,
114 MachineBasicBlock *TBB) {
115 for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
116 E = BB->succ_end(); SI != E; ++SI) {
117 MachineBasicBlock *SuccBB = *SI;
118 if (SuccBB != TBB)
119 return SuccBB;
120 }
121 return NULL;
122 }
123
124 void IfConverter::AnalyzeBlock(MachineBasicBlock *BB) {
125 BBInfo &BBI = BBAnalysis[BB->getNumber()];
126
127 if (BBI.Kind != ICInvalid)
128 return; // Always analyzed.
129 BBI.EBB = BB;
130
131 // Look for 'root' of a simple (non-nested) triangle or diamond.
132 BBI.Kind = ICNotClassfied;
133 if (TII->AnalyzeBranch(*BB, BBI.TBB, BBI.FBB, BBI.Cond)
134 || !BBI.TBB || BBI.Cond.size() == 0)
135 return;
136 AnalyzeBlock(BBI.TBB);
137 BBInfo &TBBI = BBAnalysis[BBI.TBB->getNumber()];
138 if (TBBI.Kind != ICNotClassfied)
139 return;
140
141 if (!BBI.FBB)
142 BBI.FBB = findFalseBlock(BB, BBI.TBB);
143 AnalyzeBlock(BBI.FBB);
144 BBInfo &FBBI = BBAnalysis[BBI.FBB->getNumber()];
145 if (FBBI.Kind != ICNotClassfied)
146 return;
147
148 // TODO: Only handle very simple cases for now.
149 if (TBBI.FBB || FBBI.FBB || TBBI.Cond.size() > 1 || FBBI.Cond.size() > 1)
150 return;
151
152 if (TBBI.TBB && TBBI.TBB == BBI.FBB) {
153 // Triangle:
154 // EBB
155 // | \_
156 // | |
157 // | TBB
158 // | /
159 // FBB
160 BBI.Kind = ICTriangleEntry;
161 TBBI.Kind = FBBI.Kind = ICTriangle;
162 } else if (TBBI.TBB == FBBI.TBB) {
163 // Diamond:
164 // EBB
165 // / \_
166 // | |
167 // TBB FBB
168 // \ /
169 // MBB
170 // Note MBB can be empty in case both TBB and FBB are return blocks.
171 BBI.Kind = ICDiamondEntry;
172 TBBI.Kind = FBBI.Kind = ICDiamond;
173 BBI.CMBB = TBBI.TBB;
174 }
175 return;
176 }
177
178 void IfConverter::InitialFunctionAnalysis(MachineFunction &MF,
179 std::vector &Candidates) {
180 for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
181 MachineBasicBlock *BB = I;
182 AnalyzeBlock(BB);
183 BBInfo &BBI = BBAnalysis[BB->getNumber()];
184 if (BBI.Kind == ICTriangleEntry || BBI.Kind == ICDiamondEntry)
185 Candidates.push_back(BB->getNumber());
186 }
187 }
188
189 bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
190 if (isBlockPredicatable(BBI.TBB, true)) {
191 // Predicate the 'true' block after removing its branch.
192 TII->RemoveBranch(*BBI.TBB);
193 PredicateBlock(BBI.TBB, BBI.Cond);
194
195 // Join the 'true' and 'false' blocks by copying the instructions
196 // from the 'false' block to the 'true' block.
197 MergeBlocks(BBI.TBB, BBI.FBB);
198
199 // Adjust entry block, it should have but a single unconditional
200 // branch.
201 BBI.EBB->removeSuccessor(BBI.FBB);
202 TII->RemoveBranch(*BBI.EBB);
203 std::vector NoCond;
204 TII->InsertBranch(*BBI.EBB, BBI.TBB, NULL, NoCond);
205
206 // FIXME: Must maintain LiveIns.
207 NumIfConvBBs++;
208 return true;
209 }
210 return false;
211 }
212
213 bool IfConverter::IfConvertDiamond(BBInfo &BBI) {
214 if (isBlockPredicatable(BBI.TBB, true) &&
215 isBlockPredicatable(BBI.FBB, true)) {
216 std::vector Dups;
217 if (!BBI.CMBB) {
218 // No common merge block. Check if the terminators (e.g. return) are
219 // the same or predicatable.
220 MachineBasicBlock::iterator TT = BBI.TBB->getFirstTerminator();
221 MachineBasicBlock::iterator FT = BBI.FBB->getFirstTerminator();
222 while (TT != BBI.TBB->end() && FT != BBI.FBB->end()) {
223 if (TT->isIdenticalTo(FT))
224 Dups.push_back(TT); // Will erase these later.
225 else if (!TII->isPredicatable(TT) && !TII->isPredicatable(FT))
226 return false; // Can't if-convert. Abort!
227 ++TT;
228 ++FT;
229 }
230
231 while (TT != BBI.TBB->end())
232 if (!TII->isPredicatable(TT))
233 return false; // Can't if-convert. Abort!
234 while (FT != BBI.FBB->end())
235 if (!TII->isPredicatable(FT))
236 return false; // Can't if-convert. Abort!
237 }
238
239 // Remove the duplicated instructions from the 'true' block.
240 for (unsigned i = 0, e = Dups.size(); i != e; ++i)
241 Dups[i]->eraseFromParent();
242
243 // Predicate the 'true' block after removing its branch.
244 TII->RemoveBranch(*BBI.TBB);
245 PredicateBlock(BBI.TBB, BBI.Cond);
246
247 // Predicate the 'false' block.
248 std::vector NewCond(BBI.Cond);
249 TII->ReverseBranchCondition(NewCond);
250 PredicateBlock(BBI.FBB, NewCond, true);
251
252 // Join the 'true' and 'false' blocks by copying the instructions
253 // from the 'false' block to the 'true' block.
254 MergeBlocks(BBI.TBB, BBI.FBB);
255
256 // Adjust entry block, it should have but a single unconditional
257 // branch .
258 BBI.EBB->removeSuccessor(BBI.FBB);
259 TII->RemoveBranch(*BBI.EBB);
260 std::vector NoCond;
261 TII->InsertBranch(*BBI.EBB, BBI.TBB, NULL, NoCond);
262
263 // FIXME: Must maintain LiveIns.
264 NumIfConvBBs += 2;
265 return true;
266 }
267 return false;
268 }
269
270 /// isBlockPredicatable - Returns true if the block is predicatable. In most
271 /// cases, that means all the instructions in the block has M_PREDICATED flag.
272 /// If IgnoreTerm is true, assume all the terminator instructions can be
273 /// converted or deleted.
274 bool IfConverter::isBlockPredicatable(MachineBasicBlock *BB,
275 bool IgnoreTerm) const {
276 for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
277 I != E; ++I) {
278 if (IgnoreTerm && TII->isTerminatorInstr(I->getOpcode()))
279 continue;
280 if (!TII->isPredicatable(I))
281 return false;
282 }
283 return true;
284 }
285
286 /// PredicateBlock - Predicate every instruction in the block with the specified
287 /// condition. If IgnoreTerm is true, skip over all terminator instructions.
288 void IfConverter::PredicateBlock(MachineBasicBlock *BB,
289 std::vector &Cond,
290 bool IgnoreTerm) {
291 for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
292 I != E; ++I) {
293 if (IgnoreTerm && TII->isTerminatorInstr(I->getOpcode()))
294 continue;
295 TII->PredicateInstruction(&*I, Cond);
296 }
297 }
298
299 /// MergeBlocks - Move all instructions from FBB to the end of TBB.
300 ///
301 void IfConverter::MergeBlocks(MachineBasicBlock *TBB, MachineBasicBlock *FBB) {
302 TBB->splice(TBB->end(), FBB, FBB->begin(), FBB->end());
303 }