xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/R600MachineCFGStructurizer.cpp (revision 770cf0a5f02dc8983a89c6568d741fbc25baa999)
1 //===- R600MachineCFGStructurizer.cpp - CFG Structurizer ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //==-----------------------------------------------------------------------===//
8 
9 #include "MCTargetDesc/R600MCTargetDesc.h"
10 #include "R600.h"
11 #include "R600RegisterInfo.h"
12 #include "R600Subtarget.h"
13 #include "llvm/ADT/DepthFirstIterator.h"
14 #include "llvm/ADT/SCCIterator.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/CodeGen/MachineFunction.h"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/MachineJumpTableInfo.h"
19 #include "llvm/CodeGen/MachineLoopInfo.h"
20 #include "llvm/CodeGen/MachinePostDominators.h"
21 #include "llvm/InitializePasses.h"
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "structcfg"
26 
27 enum { DEFAULT_VEC_SLOTS = 8 };
28 
29 // TODO: move-begin.
30 
31 //===----------------------------------------------------------------------===//
32 //
33 // Statistics for CFGStructurizer.
34 //
35 //===----------------------------------------------------------------------===//
36 
37 STATISTIC(numSerialPatternMatch,    "CFGStructurizer number of serial pattern "
38     "matched");
39 STATISTIC(numIfPatternMatch,        "CFGStructurizer number of if pattern "
40     "matched");
41 STATISTIC(numClonedBlock,           "CFGStructurizer cloned blocks");
42 STATISTIC(numClonedInstr,           "CFGStructurizer cloned instructions");
43 
44 namespace {
45 
46 //===----------------------------------------------------------------------===//
47 //
48 // Miscellaneous utility for CFGStructurizer.
49 //
50 //===----------------------------------------------------------------------===//
51 
52 #define SHOWNEWINSTR(i) LLVM_DEBUG(dbgs() << "New instr: " << *i << "\n");
53 
54 #define SHOWNEWBLK(b, msg)                                                     \
55   LLVM_DEBUG(dbgs() << msg << "BB" << b->getNumber() << "size " << b->size();  \
56              dbgs() << "\n";);
57 
58 #define SHOWBLK_DETAIL(b, msg)                                                 \
59   LLVM_DEBUG(if (b) {                                                          \
60     dbgs() << msg << "BB" << b->getNumber() << "size " << b->size();           \
61     b->print(dbgs());                                                          \
62     dbgs() << "\n";                                                            \
63   });
64 
65 #define INVALIDSCCNUM -1
66 
67 //===----------------------------------------------------------------------===//
68 //
69 // supporting data structure for CFGStructurizer
70 //
71 //===----------------------------------------------------------------------===//
72 
73 class BlockInformation {
74 public:
75   bool IsRetired = false;
76   int SccNum = INVALIDSCCNUM;
77 
78   BlockInformation() = default;
79 };
80 
81 //===----------------------------------------------------------------------===//
82 //
83 // CFGStructurizer
84 //
85 //===----------------------------------------------------------------------===//
86 
87 class R600MachineCFGStructurizer : public MachineFunctionPass {
88 public:
89   using MBBVector = SmallVector<MachineBasicBlock *, 32>;
90   using MBBInfoMap = std::map<MachineBasicBlock *, BlockInformation *>;
91   using LoopLandInfoMap = std::map<MachineLoop *, MachineBasicBlock *>;
92 
93   enum PathToKind {
94     Not_SinglePath = 0,
95     SinglePath_InPath = 1,
96     SinglePath_NotInPath = 2
97   };
98 
99   static char ID;
100 
101   R600MachineCFGStructurizer() : MachineFunctionPass(ID) {}
102 
103   StringRef getPassName() const override {
104     return "AMDGPU Control Flow Graph structurizer Pass";
105   }
106 
107   void getAnalysisUsage(AnalysisUsage &AU) const override {
108     AU.addRequired<MachineDominatorTreeWrapperPass>();
109     AU.addRequired<MachinePostDominatorTreeWrapperPass>();
110     AU.addRequired<MachineLoopInfoWrapperPass>();
111     MachineFunctionPass::getAnalysisUsage(AU);
112   }
113 
114   /// Perform the CFG structurization
115   bool run();
116 
117   /// Perform the CFG preparation
118   /// This step will remove every unconditionnal/dead jump instructions and make
119   /// sure all loops have an exit block
120   bool prepare();
121 
122   bool runOnMachineFunction(MachineFunction &MF) override {
123     // FIXME: This pass causes verification failures.
124     MF.getProperties().setFailsVerification();
125 
126     TII = MF.getSubtarget<R600Subtarget>().getInstrInfo();
127     TRI = &TII->getRegisterInfo();
128     LLVM_DEBUG(MF.dump(););
129     OrderedBlks.clear();
130     Visited.clear();
131     FuncRep = &MF;
132     MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
133     LLVM_DEBUG(dbgs() << "LoopInfo:\n"; PrintLoopinfo(*MLI););
134     MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
135     LLVM_DEBUG(MDT->print(dbgs()););
136     PDT = &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree();
137     LLVM_DEBUG(PDT->print(dbgs()););
138     prepare();
139     run();
140     LLVM_DEBUG(MF.dump(););
141     return true;
142   }
143 
144 protected:
145   MachineDominatorTree *MDT;
146   MachinePostDominatorTree *PDT;
147   MachineLoopInfo *MLI;
148   const R600InstrInfo *TII = nullptr;
149   const R600RegisterInfo *TRI = nullptr;
150 
151   // PRINT FUNCTIONS
152   /// Print the ordered Blocks.
153   void printOrderedBlocks() const {
154     size_t i = 0;
155     for (MBBVector::const_iterator iterBlk = OrderedBlks.begin(),
156         iterBlkEnd = OrderedBlks.end(); iterBlk != iterBlkEnd; ++iterBlk, ++i) {
157       dbgs() << "BB" << (*iterBlk)->getNumber();
158       dbgs() << "(" << getSCCNum(*iterBlk) << "," << (*iterBlk)->size() << ")";
159       if (i != 0 && i % 10 == 0) {
160         dbgs() << "\n";
161       } else {
162         dbgs() << " ";
163       }
164     }
165   }
166 
167   static void PrintLoopinfo(const MachineLoopInfo &LoopInfo) {
168     for (const MachineLoop *L : LoopInfo)
169       L->print(dbgs());
170   }
171 
172   // UTILITY FUNCTIONS
173   int getSCCNum(MachineBasicBlock *MBB) const;
174   MachineBasicBlock *getLoopLandInfo(MachineLoop *LoopRep) const;
175   bool hasBackEdge(MachineBasicBlock *MBB) const;
176   bool isRetiredBlock(MachineBasicBlock *MBB) const;
177   bool isActiveLoophead(MachineBasicBlock *MBB) const;
178   PathToKind singlePathTo(MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB,
179       bool AllowSideEntry = true) const;
180   int countActiveBlock(MBBVector::const_iterator It,
181       MBBVector::const_iterator E) const;
182   bool needMigrateBlock(MachineBasicBlock *MBB) const;
183 
184   // Utility Functions
185   void reversePredicateSetter(MachineBasicBlock::iterator I,
186                               MachineBasicBlock &MBB);
187   /// Compute the reversed DFS post order of Blocks
188   void orderBlocks(MachineFunction *MF);
189 
190   // Function originally from CFGStructTraits
191   void insertInstrEnd(MachineBasicBlock *MBB, int NewOpcode,
192                       const DebugLoc &DL = DebugLoc());
193   MachineInstr *insertInstrBefore(MachineBasicBlock *MBB, int NewOpcode,
194                                   const DebugLoc &DL = DebugLoc());
195   MachineInstr *insertInstrBefore(MachineBasicBlock::iterator I, int NewOpcode);
196   void insertCondBranchBefore(MachineBasicBlock::iterator I, int NewOpcode,
197                               const DebugLoc &DL);
198   void insertCondBranchBefore(MachineBasicBlock *MBB,
199                               MachineBasicBlock::iterator I, int NewOpcode,
200                               int RegNum, const DebugLoc &DL);
201 
202   static int getBranchNzeroOpcode(int OldOpcode);
203   static int getBranchZeroOpcode(int OldOpcode);
204   static int getContinueNzeroOpcode(int OldOpcode);
205   static int getContinueZeroOpcode(int OldOpcode);
206   static MachineBasicBlock *getTrueBranch(MachineInstr *MI);
207   static void setTrueBranch(MachineInstr *MI, MachineBasicBlock *MBB);
208   static MachineBasicBlock *getFalseBranch(MachineBasicBlock *MBB,
209       MachineInstr *MI);
210   static bool isCondBranch(MachineInstr *MI);
211   static bool isUncondBranch(MachineInstr *MI);
212   static DebugLoc getLastDebugLocInBB(MachineBasicBlock *MBB);
213   static MachineInstr *getNormalBlockBranchInstr(MachineBasicBlock *MBB);
214 
215   /// The correct naming for this is getPossibleLoopendBlockBranchInstr.
216   ///
217   /// BB with backward-edge could have move instructions after the branch
218   /// instruction.  Such move instruction "belong to" the loop backward-edge.
219   MachineInstr *getLoopendBlockBranchInstr(MachineBasicBlock *MBB);
220 
221   static MachineInstr *getReturnInstr(MachineBasicBlock *MBB);
222   static bool isReturnBlock(MachineBasicBlock *MBB);
223   static void cloneSuccessorList(MachineBasicBlock *DstMBB,
224       MachineBasicBlock *SrcMBB);
225   static MachineBasicBlock *clone(MachineBasicBlock *MBB);
226 
227   /// MachineBasicBlock::ReplaceUsesOfBlockWith doesn't serve the purpose
228   /// because the AMDGPU instruction is not recognized as terminator fix this
229   /// and retire this routine
230   void replaceInstrUseOfBlockWith(MachineBasicBlock *SrcMBB,
231       MachineBasicBlock *OldMBB, MachineBasicBlock *NewBlk);
232 
233   static void wrapup(MachineBasicBlock *MBB);
234 
235   int patternMatch(MachineBasicBlock *MBB);
236   int patternMatchGroup(MachineBasicBlock *MBB);
237   int serialPatternMatch(MachineBasicBlock *MBB);
238   int ifPatternMatch(MachineBasicBlock *MBB);
239   int loopendPatternMatch();
240   int mergeLoop(MachineLoop *LoopRep);
241 
242   /// return true iff src1Blk->succ_empty() && src1Blk and src2Blk are in
243   /// the same loop with LoopLandInfo without explicitly keeping track of
244   /// loopContBlks and loopBreakBlks, this is a method to get the information.
245   bool isSameloopDetachedContbreak(MachineBasicBlock *Src1MBB,
246       MachineBasicBlock *Src2MBB);
247   int handleJumpintoIf(MachineBasicBlock *HeadMBB,
248       MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB);
249   int handleJumpintoIfImp(MachineBasicBlock *HeadMBB,
250       MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB);
251   int improveSimpleJumpintoIf(MachineBasicBlock *HeadMBB,
252       MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB,
253       MachineBasicBlock **LandMBBPtr);
254   void showImproveSimpleJumpintoIf(MachineBasicBlock *HeadMBB,
255       MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB,
256       MachineBasicBlock *LandMBB, bool Detail = false);
257   int cloneOnSideEntryTo(MachineBasicBlock *PreMBB,
258       MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB);
259   void mergeSerialBlock(MachineBasicBlock *DstMBB,
260       MachineBasicBlock *SrcMBB);
261 
262   void mergeIfthenelseBlock(MachineInstr *BranchMI,
263       MachineBasicBlock *MBB, MachineBasicBlock *TrueMBB,
264       MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB);
265   void mergeLooplandBlock(MachineBasicBlock *DstMBB,
266       MachineBasicBlock *LandMBB);
267   void mergeLoopbreakBlock(MachineBasicBlock *ExitingMBB,
268       MachineBasicBlock *LandMBB);
269   void settleLoopcontBlock(MachineBasicBlock *ContingMBB,
270       MachineBasicBlock *ContMBB);
271 
272   /// normalizeInfiniteLoopExit change
273   ///   B1:
274   ///        uncond_br LoopHeader
275   ///
276   /// to
277   ///   B1:
278   ///        cond_br 1 LoopHeader dummyExit
279   /// and return the newly added dummy exit block
280   MachineBasicBlock *normalizeInfiniteLoopExit(MachineLoop *LoopRep);
281   void removeUnconditionalBranch(MachineBasicBlock *MBB);
282 
283   /// Remove duplicate branches instructions in a block.
284   /// For instance
285   /// B0:
286   ///    cond_br X B1 B2
287   ///    cond_br X B1 B2
288   /// is transformed to
289   /// B0:
290   ///    cond_br X B1 B2
291   void removeRedundantConditionalBranch(MachineBasicBlock *MBB);
292 
293   void addDummyExitBlock(SmallVectorImpl<MachineBasicBlock *> &RetMBB);
294   void removeSuccessor(MachineBasicBlock *MBB);
295   MachineBasicBlock *cloneBlockForPredecessor(MachineBasicBlock *MBB,
296       MachineBasicBlock *PredMBB);
297   void migrateInstruction(MachineBasicBlock *SrcMBB,
298       MachineBasicBlock *DstMBB, MachineBasicBlock::iterator I);
299   void recordSccnum(MachineBasicBlock *MBB, int SCCNum);
300   void retireBlock(MachineBasicBlock *MBB);
301 
302 private:
303   MBBInfoMap BlockInfoMap;
304   LoopLandInfoMap LLInfoMap;
305   std::map<MachineLoop *, bool> Visited;
306   MachineFunction *FuncRep;
307   SmallVector<MachineBasicBlock *, DEFAULT_VEC_SLOTS> OrderedBlks;
308 };
309 
310 } // end anonymous namespace
311 
312 char R600MachineCFGStructurizer::ID = 0;
313 
314 int R600MachineCFGStructurizer::getSCCNum(MachineBasicBlock *MBB) const {
315   MBBInfoMap::const_iterator It = BlockInfoMap.find(MBB);
316   if (It == BlockInfoMap.end())
317     return INVALIDSCCNUM;
318   return (*It).second->SccNum;
319 }
320 
321 MachineBasicBlock *R600MachineCFGStructurizer::getLoopLandInfo(MachineLoop *LoopRep)
322     const {
323   LoopLandInfoMap::const_iterator It = LLInfoMap.find(LoopRep);
324   if (It == LLInfoMap.end())
325     return nullptr;
326   return (*It).second;
327 }
328 
329 bool R600MachineCFGStructurizer::hasBackEdge(MachineBasicBlock *MBB) const {
330   MachineLoop *LoopRep = MLI->getLoopFor(MBB);
331   if (!LoopRep)
332     return false;
333   MachineBasicBlock *LoopHeader = LoopRep->getHeader();
334   return MBB->isSuccessor(LoopHeader);
335 }
336 
337 bool R600MachineCFGStructurizer::isRetiredBlock(MachineBasicBlock *MBB) const {
338   MBBInfoMap::const_iterator It = BlockInfoMap.find(MBB);
339   if (It == BlockInfoMap.end())
340     return false;
341   return (*It).second->IsRetired;
342 }
343 
344 bool R600MachineCFGStructurizer::isActiveLoophead(MachineBasicBlock *MBB) const {
345   MachineLoop *LoopRep = MLI->getLoopFor(MBB);
346   while (LoopRep && LoopRep->getHeader() == MBB) {
347     MachineBasicBlock *LoopLand = getLoopLandInfo(LoopRep);
348     if(!LoopLand)
349       return true;
350     if (!isRetiredBlock(LoopLand))
351       return true;
352     LoopRep = LoopRep->getParentLoop();
353   }
354   return false;
355 }
356 
357 R600MachineCFGStructurizer::PathToKind R600MachineCFGStructurizer::singlePathTo(
358     MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB,
359     bool AllowSideEntry) const {
360   assert(DstMBB);
361   if (SrcMBB == DstMBB)
362     return SinglePath_InPath;
363   while (SrcMBB && SrcMBB->succ_size() == 1) {
364     SrcMBB = *SrcMBB->succ_begin();
365     if (SrcMBB == DstMBB)
366       return SinglePath_InPath;
367     if (!AllowSideEntry && SrcMBB->pred_size() > 1)
368       return Not_SinglePath;
369   }
370   if (SrcMBB && SrcMBB->succ_size()==0)
371     return SinglePath_NotInPath;
372   return Not_SinglePath;
373 }
374 
375 int R600MachineCFGStructurizer::countActiveBlock(MBBVector::const_iterator It,
376     MBBVector::const_iterator E) const {
377   int Count = 0;
378   while (It != E) {
379     if (!isRetiredBlock(*It))
380       ++Count;
381     ++It;
382   }
383   return Count;
384 }
385 
386 bool R600MachineCFGStructurizer::needMigrateBlock(MachineBasicBlock *MBB) const {
387   unsigned BlockSizeThreshold = 30;
388   unsigned CloneInstrThreshold = 100;
389   bool MultiplePreds = MBB && (MBB->pred_size() > 1);
390 
391   if(!MultiplePreds)
392     return false;
393   unsigned BlkSize = MBB->size();
394   return ((BlkSize > BlockSizeThreshold) &&
395       (BlkSize * (MBB->pred_size() - 1) > CloneInstrThreshold));
396 }
397 
398 void R600MachineCFGStructurizer::reversePredicateSetter(
399     MachineBasicBlock::iterator I, MachineBasicBlock &MBB) {
400   assert(I.isValid() && "Expected valid iterator");
401   for (;; --I) {
402     if (I == MBB.end())
403       continue;
404     if (I->getOpcode() == R600::PRED_X) {
405       switch (I->getOperand(2).getImm()) {
406       case R600::PRED_SETE_INT:
407         I->getOperand(2).setImm(R600::PRED_SETNE_INT);
408         return;
409       case R600::PRED_SETNE_INT:
410         I->getOperand(2).setImm(R600::PRED_SETE_INT);
411         return;
412       case R600::PRED_SETE:
413         I->getOperand(2).setImm(R600::PRED_SETNE);
414         return;
415       case R600::PRED_SETNE:
416         I->getOperand(2).setImm(R600::PRED_SETE);
417         return;
418       default:
419         llvm_unreachable("PRED_X Opcode invalid!");
420       }
421     }
422   }
423 }
424 
425 void R600MachineCFGStructurizer::insertInstrEnd(MachineBasicBlock *MBB,
426                                            int NewOpcode, const DebugLoc &DL) {
427   MachineInstr *MI =
428       MBB->getParent()->CreateMachineInstr(TII->get(NewOpcode), DL);
429   MBB->push_back(MI);
430   //assume the instruction doesn't take any reg operand ...
431   SHOWNEWINSTR(MI);
432 }
433 
434 MachineInstr *R600MachineCFGStructurizer::insertInstrBefore(MachineBasicBlock *MBB,
435                                                        int NewOpcode,
436                                                        const DebugLoc &DL) {
437   MachineInstr *MI =
438       MBB->getParent()->CreateMachineInstr(TII->get(NewOpcode), DL);
439   if (!MBB->empty())
440     MBB->insert(MBB->begin(), MI);
441   else
442     MBB->push_back(MI);
443   SHOWNEWINSTR(MI);
444   return MI;
445 }
446 
447 MachineInstr *R600MachineCFGStructurizer::insertInstrBefore(
448     MachineBasicBlock::iterator I, int NewOpcode) {
449   MachineInstr *OldMI = &(*I);
450   MachineBasicBlock *MBB = OldMI->getParent();
451   MachineInstr *NewMBB =
452       MBB->getParent()->CreateMachineInstr(TII->get(NewOpcode), DebugLoc());
453   MBB->insert(I, NewMBB);
454   //assume the instruction doesn't take any reg operand ...
455   SHOWNEWINSTR(NewMBB);
456   return NewMBB;
457 }
458 
459 void R600MachineCFGStructurizer::insertCondBranchBefore(
460     MachineBasicBlock::iterator I, int NewOpcode, const DebugLoc &DL) {
461   MachineInstr *OldMI = &(*I);
462   MachineBasicBlock *MBB = OldMI->getParent();
463   MachineFunction *MF = MBB->getParent();
464   MachineInstr *NewMI = MF->CreateMachineInstr(TII->get(NewOpcode), DL);
465   MBB->insert(I, NewMI);
466   MachineInstrBuilder MIB(*MF, NewMI);
467   MIB.addReg(OldMI->getOperand(1).getReg(), false);
468   SHOWNEWINSTR(NewMI);
469   //erase later oldInstr->eraseFromParent();
470 }
471 
472 void R600MachineCFGStructurizer::insertCondBranchBefore(
473     MachineBasicBlock *blk, MachineBasicBlock::iterator I, int NewOpcode,
474     int RegNum, const DebugLoc &DL) {
475   MachineFunction *MF = blk->getParent();
476   MachineInstr *NewInstr = MF->CreateMachineInstr(TII->get(NewOpcode), DL);
477   //insert before
478   blk->insert(I, NewInstr);
479   MachineInstrBuilder(*MF, NewInstr).addReg(RegNum, false);
480   SHOWNEWINSTR(NewInstr);
481 }
482 
483 int R600MachineCFGStructurizer::getBranchNzeroOpcode(int OldOpcode) {
484   switch(OldOpcode) {
485   case R600::JUMP_COND:
486   case R600::JUMP: return R600::IF_PREDICATE_SET;
487   case R600::BRANCH_COND_i32:
488   case R600::BRANCH_COND_f32: return R600::IF_LOGICALNZ_f32;
489   default: llvm_unreachable("internal error");
490   }
491   return -1;
492 }
493 
494 int R600MachineCFGStructurizer::getBranchZeroOpcode(int OldOpcode) {
495   switch(OldOpcode) {
496   case R600::JUMP_COND:
497   case R600::JUMP: return R600::IF_PREDICATE_SET;
498   case R600::BRANCH_COND_i32:
499   case R600::BRANCH_COND_f32: return R600::IF_LOGICALZ_f32;
500   default: llvm_unreachable("internal error");
501   }
502   return -1;
503 }
504 
505 int R600MachineCFGStructurizer::getContinueNzeroOpcode(int OldOpcode) {
506   switch(OldOpcode) {
507   case R600::JUMP_COND:
508   case R600::JUMP: return R600::CONTINUE_LOGICALNZ_i32;
509   default: llvm_unreachable("internal error");
510   }
511   return -1;
512 }
513 
514 int R600MachineCFGStructurizer::getContinueZeroOpcode(int OldOpcode) {
515   switch(OldOpcode) {
516   case R600::JUMP_COND:
517   case R600::JUMP: return R600::CONTINUE_LOGICALZ_i32;
518   default: llvm_unreachable("internal error");
519   }
520   return -1;
521 }
522 
523 MachineBasicBlock *R600MachineCFGStructurizer::getTrueBranch(MachineInstr *MI) {
524   return MI->getOperand(0).getMBB();
525 }
526 
527 void R600MachineCFGStructurizer::setTrueBranch(MachineInstr *MI,
528     MachineBasicBlock *MBB) {
529   MI->getOperand(0).setMBB(MBB);
530 }
531 
532 MachineBasicBlock *
533 R600MachineCFGStructurizer::getFalseBranch(MachineBasicBlock *MBB,
534     MachineInstr *MI) {
535   assert(MBB->succ_size() == 2);
536   MachineBasicBlock *TrueBranch = getTrueBranch(MI);
537   MachineBasicBlock::succ_iterator It = MBB->succ_begin();
538   MachineBasicBlock::succ_iterator Next = It;
539   ++Next;
540   return (*It == TrueBranch) ? *Next : *It;
541 }
542 
543 bool R600MachineCFGStructurizer::isCondBranch(MachineInstr *MI) {
544   switch (MI->getOpcode()) {
545     case R600::JUMP_COND:
546     case R600::BRANCH_COND_i32:
547     case R600::BRANCH_COND_f32: return true;
548   default:
549     return false;
550   }
551   return false;
552 }
553 
554 bool R600MachineCFGStructurizer::isUncondBranch(MachineInstr *MI) {
555   switch (MI->getOpcode()) {
556   case R600::JUMP:
557   case R600::BRANCH:
558     return true;
559   default:
560     return false;
561   }
562   return false;
563 }
564 
565 DebugLoc R600MachineCFGStructurizer::getLastDebugLocInBB(MachineBasicBlock *MBB) {
566   //get DebugLoc from the first MachineBasicBlock instruction with debug info
567   DebugLoc DL;
568   for (MachineInstr &MI : *MBB)
569     if (MI.getDebugLoc())
570       DL = MI.getDebugLoc();
571   return DL;
572 }
573 
574 MachineInstr *R600MachineCFGStructurizer::getNormalBlockBranchInstr(
575     MachineBasicBlock *MBB) {
576   MachineBasicBlock::reverse_iterator It = MBB->rbegin();
577   MachineInstr *MI = &*It;
578   if (MI && (isCondBranch(MI) || isUncondBranch(MI)))
579     return MI;
580   return nullptr;
581 }
582 
583 MachineInstr *R600MachineCFGStructurizer::getLoopendBlockBranchInstr(
584     MachineBasicBlock *MBB) {
585   for (MachineBasicBlock::reverse_iterator It = MBB->rbegin(), E = MBB->rend();
586       It != E; ++It) {
587     // FIXME: Simplify
588     MachineInstr *MI = &*It;
589     if (MI) {
590       if (isCondBranch(MI) || isUncondBranch(MI))
591         return MI;
592       if (!TII->isMov(MI->getOpcode()))
593         break;
594     }
595   }
596   return nullptr;
597 }
598 
599 MachineInstr *R600MachineCFGStructurizer::getReturnInstr(MachineBasicBlock *MBB) {
600   MachineBasicBlock::reverse_iterator It = MBB->rbegin();
601   if (It != MBB->rend()) {
602     MachineInstr *instr = &(*It);
603     if (instr->getOpcode() == R600::RETURN)
604       return instr;
605   }
606   return nullptr;
607 }
608 
609 bool R600MachineCFGStructurizer::isReturnBlock(MachineBasicBlock *MBB) {
610   MachineInstr *MI = getReturnInstr(MBB);
611   bool IsReturn = MBB->succ_empty();
612   if (MI)
613     assert(IsReturn);
614   else if (IsReturn)
615     LLVM_DEBUG(dbgs() << "BB" << MBB->getNumber()
616                       << " is return block without RETURN instr\n";);
617   return  IsReturn;
618 }
619 
620 void R600MachineCFGStructurizer::cloneSuccessorList(MachineBasicBlock *DstMBB,
621     MachineBasicBlock *SrcMBB) {
622   for (MachineBasicBlock *Succ : SrcMBB->successors())
623     DstMBB->addSuccessor(Succ);  // *iter's predecessor is also taken care of
624 }
625 
626 MachineBasicBlock *R600MachineCFGStructurizer::clone(MachineBasicBlock *MBB) {
627   MachineFunction *Func = MBB->getParent();
628   MachineBasicBlock *NewMBB = Func->CreateMachineBasicBlock();
629   Func->push_back(NewMBB);  //insert to function
630   for (const MachineInstr &It : *MBB)
631     NewMBB->push_back(Func->CloneMachineInstr(&It));
632   return NewMBB;
633 }
634 
635 void R600MachineCFGStructurizer::replaceInstrUseOfBlockWith(
636     MachineBasicBlock *SrcMBB, MachineBasicBlock *OldMBB,
637     MachineBasicBlock *NewBlk) {
638   MachineInstr *BranchMI = getLoopendBlockBranchInstr(SrcMBB);
639   if (BranchMI && isCondBranch(BranchMI) &&
640       getTrueBranch(BranchMI) == OldMBB)
641     setTrueBranch(BranchMI, NewBlk);
642 }
643 
644 void R600MachineCFGStructurizer::wrapup(MachineBasicBlock *MBB) {
645   assert((!MBB->getParent()->getJumpTableInfo()
646           || MBB->getParent()->getJumpTableInfo()->isEmpty())
647          && "found a jump table");
648 
649    //collect continue right before endloop
650    SmallVector<MachineInstr *, DEFAULT_VEC_SLOTS> ContInstr;
651    MachineBasicBlock::iterator Pre = MBB->begin();
652    MachineBasicBlock::iterator E = MBB->end();
653    MachineBasicBlock::iterator It = Pre;
654    while (It != E) {
655      if (Pre->getOpcode() == R600::CONTINUE
656          && It->getOpcode() == R600::ENDLOOP)
657        ContInstr.push_back(&*Pre);
658      Pre = It;
659      ++It;
660    }
661 
662    //delete continue right before endloop
663    for (auto *MI : ContInstr)
664      MI->eraseFromParent();
665 
666    // TODO to fix up jump table so later phase won't be confused.  if
667    // (jumpTableInfo->isEmpty() == false) { need to clean the jump table, but
668    // there isn't such an interface yet.  alternatively, replace all the other
669    // blocks in the jump table with the entryBlk //}
670 }
671 
672 bool R600MachineCFGStructurizer::prepare() {
673   bool Changed = false;
674 
675   //FIXME: if not reducible flow graph, make it so ???
676 
677   LLVM_DEBUG(dbgs() << "R600MachineCFGStructurizer::prepare\n";);
678 
679   orderBlocks(FuncRep);
680 
681   SmallVector<MachineBasicBlock *, DEFAULT_VEC_SLOTS> RetBlks;
682 
683   // Add an ExitBlk to loop that don't have one
684   for (MachineLoop *LoopRep : *MLI) {
685     MBBVector ExitingMBBs;
686     LoopRep->getExitingBlocks(ExitingMBBs);
687 
688     if (ExitingMBBs.size() == 0) {
689       MachineBasicBlock* DummyExitBlk = normalizeInfiniteLoopExit(LoopRep);
690       if (DummyExitBlk)
691         RetBlks.push_back(DummyExitBlk);
692     }
693   }
694 
695   // Remove unconditional branch instr.
696   // Add dummy exit block iff there are multiple returns.
697   for (MachineBasicBlock *MBB : OrderedBlks) {
698     removeUnconditionalBranch(MBB);
699     removeRedundantConditionalBranch(MBB);
700     if (isReturnBlock(MBB)) {
701       RetBlks.push_back(MBB);
702     }
703     assert(MBB->succ_size() <= 2);
704   }
705 
706   if (RetBlks.size() >= 2) {
707     addDummyExitBlock(RetBlks);
708     Changed = true;
709   }
710 
711   return Changed;
712 }
713 
714 bool R600MachineCFGStructurizer::run() {
715   //Assume reducible CFG...
716   LLVM_DEBUG(dbgs() << "R600MachineCFGStructurizer::run\n");
717 
718 #ifdef STRESSTEST
719   //Use the worse block ordering to test the algorithm.
720   ReverseVector(orderedBlks);
721 #endif
722 
723   LLVM_DEBUG(dbgs() << "Ordered blocks:\n"; printOrderedBlocks(););
724   int NumIter = 0;
725   bool Finish = false;
726   MachineBasicBlock *MBB;
727   bool MakeProgress = false;
728   int NumRemainedBlk = countActiveBlock(OrderedBlks.begin(),
729                                         OrderedBlks.end());
730 
731   do {
732     ++NumIter;
733     LLVM_DEBUG(dbgs() << "numIter = " << NumIter
734                       << ", numRemaintedBlk = " << NumRemainedBlk << "\n";);
735     (void)NumIter;
736 
737     SmallVectorImpl<MachineBasicBlock *>::const_iterator It =
738         OrderedBlks.begin();
739     SmallVectorImpl<MachineBasicBlock *>::const_iterator E =
740         OrderedBlks.end();
741 
742     SmallVectorImpl<MachineBasicBlock *>::const_iterator SccBeginIter =
743         It;
744     MachineBasicBlock *SccBeginMBB = nullptr;
745     int SccNumBlk = 0;  // The number of active blocks, init to a
746                         // maximum possible number.
747     int SccNumIter;     // Number of iteration in this SCC.
748 
749     while (It != E) {
750       MBB = *It;
751 
752       if (!SccBeginMBB) {
753         SccBeginIter = It;
754         SccBeginMBB = MBB;
755         SccNumIter = 0;
756         SccNumBlk = NumRemainedBlk; // Init to maximum possible number.
757         LLVM_DEBUG(dbgs() << "start processing SCC" << getSCCNum(SccBeginMBB);
758                    dbgs() << "\n";);
759       }
760 
761       if (!isRetiredBlock(MBB))
762         patternMatch(MBB);
763 
764       ++It;
765 
766       bool ContNextScc = true;
767       if (It == E
768           || getSCCNum(SccBeginMBB) != getSCCNum(*It)) {
769         // Just finish one scc.
770         ++SccNumIter;
771         int sccRemainedNumBlk = countActiveBlock(SccBeginIter, It);
772         if (sccRemainedNumBlk != 1 && sccRemainedNumBlk >= SccNumBlk) {
773           LLVM_DEBUG(dbgs() << "Can't reduce SCC " << getSCCNum(MBB)
774                             << ", sccNumIter = " << SccNumIter;
775                      dbgs() << "doesn't make any progress\n";);
776           (void)SccNumIter;
777           ContNextScc = true;
778         } else if (sccRemainedNumBlk != 1 && sccRemainedNumBlk < SccNumBlk) {
779           SccNumBlk = sccRemainedNumBlk;
780           It = SccBeginIter;
781           ContNextScc = false;
782           LLVM_DEBUG(dbgs() << "repeat processing SCC" << getSCCNum(MBB)
783                             << "sccNumIter = " << SccNumIter << '\n';);
784         } else {
785           // Finish the current scc.
786           ContNextScc = true;
787         }
788       } else {
789         // Continue on next component in the current scc.
790         ContNextScc = false;
791       }
792 
793       if (ContNextScc)
794         SccBeginMBB = nullptr;
795     } //while, "one iteration" over the function.
796 
797     MachineBasicBlock *EntryMBB =
798         *GraphTraits<MachineFunction *>::nodes_begin(FuncRep);
799     if (EntryMBB->succ_empty()) {
800       Finish = true;
801       LLVM_DEBUG(dbgs() << "Reduce to one block\n";);
802     } else {
803       int NewnumRemainedBlk
804         = countActiveBlock(OrderedBlks.begin(), OrderedBlks.end());
805       // consider cloned blocks ??
806       if (NewnumRemainedBlk == 1 || NewnumRemainedBlk < NumRemainedBlk) {
807         MakeProgress = true;
808         NumRemainedBlk = NewnumRemainedBlk;
809       } else {
810         MakeProgress = false;
811         LLVM_DEBUG(dbgs() << "No progress\n";);
812       }
813     }
814   } while (!Finish && MakeProgress);
815 
816   // Misc wrap up to maintain the consistency of the Function representation.
817   wrapup(*GraphTraits<MachineFunction *>::nodes_begin(FuncRep));
818 
819   // Detach retired Block, release memory.
820   for (auto &It : BlockInfoMap) {
821     if (It.second && It.second->IsRetired) {
822       assert((It.first)->getNumber() != -1);
823       LLVM_DEBUG(dbgs() << "Erase BB" << (It.first)->getNumber() << "\n";);
824       It.first->eraseFromParent(); // Remove from the parent Function.
825     }
826     delete It.second;
827   }
828   BlockInfoMap.clear();
829   LLInfoMap.clear();
830 
831   if (!Finish) {
832     LLVM_DEBUG(FuncRep->viewCFG());
833     report_fatal_error("IRREDUCIBLE_CFG");
834   }
835 
836   return true;
837 }
838 
839 void R600MachineCFGStructurizer::orderBlocks(MachineFunction *MF) {
840   int SccNum = 0;
841   for (scc_iterator<MachineFunction *> It = scc_begin(MF); !It.isAtEnd();
842        ++It, ++SccNum) {
843     const std::vector<MachineBasicBlock *> &SccNext = *It;
844     for (MachineBasicBlock *MBB : SccNext) {
845       OrderedBlks.push_back(MBB);
846       recordSccnum(MBB, SccNum);
847     }
848   }
849 
850   // walk through all the block in func to check for unreachable
851   for (auto *MBB : nodes(MF)) {
852     SccNum = getSCCNum(MBB);
853     if (SccNum == INVALIDSCCNUM)
854       dbgs() << "unreachable block BB" << MBB->getNumber() << "\n";
855   }
856 }
857 
858 int R600MachineCFGStructurizer::patternMatch(MachineBasicBlock *MBB) {
859   int NumMatch = 0;
860   int CurMatch;
861 
862   LLVM_DEBUG(dbgs() << "Begin patternMatch BB" << MBB->getNumber() << "\n";);
863 
864   while ((CurMatch = patternMatchGroup(MBB)) > 0)
865     NumMatch += CurMatch;
866 
867   LLVM_DEBUG(dbgs() << "End patternMatch BB" << MBB->getNumber()
868                     << ", numMatch = " << NumMatch << "\n";);
869 
870   return NumMatch;
871 }
872 
873 int R600MachineCFGStructurizer::patternMatchGroup(MachineBasicBlock *MBB) {
874   int NumMatch = 0;
875   NumMatch += loopendPatternMatch();
876   NumMatch += serialPatternMatch(MBB);
877   NumMatch += ifPatternMatch(MBB);
878   return NumMatch;
879 }
880 
881 int R600MachineCFGStructurizer::serialPatternMatch(MachineBasicBlock *MBB) {
882   if (MBB->succ_size() != 1)
883     return 0;
884 
885   MachineBasicBlock *childBlk = *MBB->succ_begin();
886   if (childBlk->pred_size() != 1 || isActiveLoophead(childBlk))
887     return 0;
888 
889   mergeSerialBlock(MBB, childBlk);
890   ++numSerialPatternMatch;
891   return 1;
892 }
893 
894 int R600MachineCFGStructurizer::ifPatternMatch(MachineBasicBlock *MBB) {
895   //two edges
896   if (MBB->succ_size() != 2)
897     return 0;
898   if (hasBackEdge(MBB))
899     return 0;
900   MachineInstr *BranchMI = getNormalBlockBranchInstr(MBB);
901   if (!BranchMI)
902     return 0;
903 
904   assert(isCondBranch(BranchMI));
905   int NumMatch = 0;
906 
907   MachineBasicBlock *TrueMBB = getTrueBranch(BranchMI);
908   NumMatch += serialPatternMatch(TrueMBB);
909   NumMatch += ifPatternMatch(TrueMBB);
910   MachineBasicBlock *FalseMBB = getFalseBranch(MBB, BranchMI);
911   NumMatch += serialPatternMatch(FalseMBB);
912   NumMatch += ifPatternMatch(FalseMBB);
913   MachineBasicBlock *LandBlk;
914   int Cloned = 0;
915 
916   assert (!TrueMBB->succ_empty() || !FalseMBB->succ_empty());
917   // TODO: Simplify
918   if (TrueMBB->succ_size() == 1 && FalseMBB->succ_size() == 1
919     && *TrueMBB->succ_begin() == *FalseMBB->succ_begin()) {
920     // Diamond pattern
921     LandBlk = *TrueMBB->succ_begin();
922   } else if (TrueMBB->succ_size() == 1 && *TrueMBB->succ_begin() == FalseMBB) {
923     // Triangle pattern, false is empty
924     LandBlk = FalseMBB;
925     FalseMBB = nullptr;
926   } else if (FalseMBB->succ_size() == 1
927              && *FalseMBB->succ_begin() == TrueMBB) {
928     // Triangle pattern, true is empty
929     // We reverse the predicate to make a triangle, empty false pattern;
930     std::swap(TrueMBB, FalseMBB);
931     reversePredicateSetter(MBB->end(), *MBB);
932     LandBlk = FalseMBB;
933     FalseMBB = nullptr;
934   } else if (FalseMBB->succ_size() == 1
935              && isSameloopDetachedContbreak(TrueMBB, FalseMBB)) {
936     LandBlk = *FalseMBB->succ_begin();
937   } else if (TrueMBB->succ_size() == 1
938     && isSameloopDetachedContbreak(FalseMBB, TrueMBB)) {
939     LandBlk = *TrueMBB->succ_begin();
940   } else {
941     return NumMatch + handleJumpintoIf(MBB, TrueMBB, FalseMBB);
942   }
943 
944   // improveSimpleJumpinfoIf can handle the case where landBlk == NULL but the
945   // new BB created for landBlk==NULL may introduce new challenge to the
946   // reduction process.
947   if (LandBlk &&
948       ((TrueMBB && TrueMBB->pred_size() > 1)
949       || (FalseMBB && FalseMBB->pred_size() > 1))) {
950      Cloned += improveSimpleJumpintoIf(MBB, TrueMBB, FalseMBB, &LandBlk);
951   }
952 
953   if (TrueMBB && TrueMBB->pred_size() > 1) {
954     TrueMBB = cloneBlockForPredecessor(TrueMBB, MBB);
955     ++Cloned;
956   }
957 
958   if (FalseMBB && FalseMBB->pred_size() > 1) {
959     FalseMBB = cloneBlockForPredecessor(FalseMBB, MBB);
960     ++Cloned;
961   }
962 
963   mergeIfthenelseBlock(BranchMI, MBB, TrueMBB, FalseMBB, LandBlk);
964 
965   ++numIfPatternMatch;
966 
967   numClonedBlock += Cloned;
968 
969   return 1 + Cloned + NumMatch;
970 }
971 
972 int R600MachineCFGStructurizer::loopendPatternMatch() {
973   std::deque<MachineLoop *> NestedLoops;
974   for (auto &It: *MLI)
975     for (MachineLoop *ML : depth_first(It))
976       NestedLoops.push_front(ML);
977 
978   if (NestedLoops.empty())
979     return 0;
980 
981   // Process nested loop outside->inside (we did push_front),
982   // so "continue" to a outside loop won't be mistaken as "break"
983   // of the current loop.
984   int Num = 0;
985   for (MachineLoop *ExaminedLoop : NestedLoops) {
986     if (ExaminedLoop->getNumBlocks() == 0 || Visited[ExaminedLoop])
987       continue;
988     LLVM_DEBUG(dbgs() << "Processing:\n"; ExaminedLoop->dump(););
989     int NumBreak = mergeLoop(ExaminedLoop);
990     if (NumBreak == -1)
991       break;
992     Num += NumBreak;
993   }
994   return Num;
995 }
996 
997 int R600MachineCFGStructurizer::mergeLoop(MachineLoop *LoopRep) {
998   MachineBasicBlock *LoopHeader = LoopRep->getHeader();
999   MBBVector ExitingMBBs;
1000   LoopRep->getExitingBlocks(ExitingMBBs);
1001   assert(!ExitingMBBs.empty() && "Infinite Loop not supported");
1002   LLVM_DEBUG(dbgs() << "Loop has " << ExitingMBBs.size()
1003                     << " exiting blocks\n";);
1004   // We assume a single ExitBlk
1005   MBBVector ExitBlks;
1006   LoopRep->getExitBlocks(ExitBlks);
1007   SmallPtrSet<MachineBasicBlock *, 2> ExitBlkSet(llvm::from_range, ExitBlks);
1008   assert(ExitBlkSet.size() == 1);
1009   MachineBasicBlock *ExitBlk = *ExitBlks.begin();
1010   assert(ExitBlk && "Loop has several exit block");
1011   MBBVector LatchBlks;
1012   for (auto *LB : inverse_children<MachineBasicBlock*>(LoopHeader))
1013     if (LoopRep->contains(LB))
1014       LatchBlks.push_back(LB);
1015 
1016   for (MachineBasicBlock *MBB : ExitingMBBs)
1017     mergeLoopbreakBlock(MBB, ExitBlk);
1018   for (MachineBasicBlock *MBB : LatchBlks)
1019     settleLoopcontBlock(MBB, LoopHeader);
1020   int Match = 0;
1021   do {
1022     Match = 0;
1023     Match += serialPatternMatch(LoopHeader);
1024     Match += ifPatternMatch(LoopHeader);
1025   } while (Match > 0);
1026   mergeLooplandBlock(LoopHeader, ExitBlk);
1027   MachineLoop *ParentLoop = LoopRep->getParentLoop();
1028   if (ParentLoop)
1029     MLI->changeLoopFor(LoopHeader, ParentLoop);
1030   else
1031     MLI->removeBlock(LoopHeader);
1032   Visited[LoopRep] = true;
1033   return 1;
1034 }
1035 
1036 bool R600MachineCFGStructurizer::isSameloopDetachedContbreak(
1037     MachineBasicBlock *Src1MBB, MachineBasicBlock *Src2MBB) {
1038   if (Src1MBB->succ_empty()) {
1039     MachineLoop *LoopRep = MLI->getLoopFor(Src1MBB);
1040     if (LoopRep&& LoopRep == MLI->getLoopFor(Src2MBB)) {
1041       MachineBasicBlock *&TheEntry = LLInfoMap[LoopRep];
1042       if (TheEntry) {
1043         LLVM_DEBUG(dbgs() << "isLoopContBreakBlock yes src1 = BB"
1044                           << Src1MBB->getNumber() << " src2 = BB"
1045                           << Src2MBB->getNumber() << "\n";);
1046         return true;
1047       }
1048     }
1049   }
1050   return false;
1051 }
1052 
1053 int R600MachineCFGStructurizer::handleJumpintoIf(MachineBasicBlock *HeadMBB,
1054     MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB) {
1055   int Num = handleJumpintoIfImp(HeadMBB, TrueMBB, FalseMBB);
1056   if (Num == 0) {
1057     LLVM_DEBUG(dbgs() << "handleJumpintoIf swap trueBlk and FalseBlk"
1058                       << "\n";);
1059     Num = handleJumpintoIfImp(HeadMBB, FalseMBB, TrueMBB);
1060   }
1061   return Num;
1062 }
1063 
1064 int R600MachineCFGStructurizer::handleJumpintoIfImp(MachineBasicBlock *HeadMBB,
1065     MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB) {
1066   int Num = 0;
1067   MachineBasicBlock *DownBlk;
1068 
1069   //trueBlk could be the common post dominator
1070   DownBlk = TrueMBB;
1071 
1072   LLVM_DEBUG(dbgs() << "handleJumpintoIfImp head = BB" << HeadMBB->getNumber()
1073                     << " true = BB" << TrueMBB->getNumber()
1074                     << ", numSucc=" << TrueMBB->succ_size() << " false = BB"
1075                     << FalseMBB->getNumber() << "\n";);
1076 
1077   while (DownBlk) {
1078     LLVM_DEBUG(dbgs() << "check down = BB" << DownBlk->getNumber(););
1079 
1080     if (singlePathTo(FalseMBB, DownBlk) == SinglePath_InPath) {
1081       LLVM_DEBUG(dbgs() << " working\n";);
1082 
1083       Num += cloneOnSideEntryTo(HeadMBB, TrueMBB, DownBlk);
1084       Num += cloneOnSideEntryTo(HeadMBB, FalseMBB, DownBlk);
1085 
1086       numClonedBlock += Num;
1087       Num += serialPatternMatch(*HeadMBB->succ_begin());
1088       Num += serialPatternMatch(*std::next(HeadMBB->succ_begin()));
1089       Num += ifPatternMatch(HeadMBB);
1090       assert(Num > 0);
1091 
1092       break;
1093     }
1094     LLVM_DEBUG(dbgs() << " not working\n";);
1095     DownBlk = (DownBlk->succ_size() == 1) ? (*DownBlk->succ_begin()) : nullptr;
1096   } // walk down the postDomTree
1097 
1098   return Num;
1099 }
1100 
1101 #ifndef NDEBUG
1102 void R600MachineCFGStructurizer::showImproveSimpleJumpintoIf(
1103     MachineBasicBlock *HeadMBB, MachineBasicBlock *TrueMBB,
1104     MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB, bool Detail) {
1105   dbgs() << "head = BB" << HeadMBB->getNumber()
1106          << " size = " << HeadMBB->size();
1107   if (Detail) {
1108     dbgs() << "\n";
1109     HeadMBB->print(dbgs());
1110     dbgs() << "\n";
1111   }
1112 
1113   if (TrueMBB) {
1114     dbgs() << ", true = BB" << TrueMBB->getNumber() << " size = "
1115            << TrueMBB->size() << " numPred = " << TrueMBB->pred_size();
1116     if (Detail) {
1117       dbgs() << "\n";
1118       TrueMBB->print(dbgs());
1119       dbgs() << "\n";
1120     }
1121   }
1122   if (FalseMBB) {
1123     dbgs() << ", false = BB" << FalseMBB->getNumber() << " size = "
1124            << FalseMBB->size() << " numPred = " << FalseMBB->pred_size();
1125     if (Detail) {
1126       dbgs() << "\n";
1127       FalseMBB->print(dbgs());
1128       dbgs() << "\n";
1129     }
1130   }
1131   if (LandMBB) {
1132     dbgs() << ", land = BB" << LandMBB->getNumber() << " size = "
1133            << LandMBB->size() << " numPred = " << LandMBB->pred_size();
1134     if (Detail) {
1135       dbgs() << "\n";
1136       LandMBB->print(dbgs());
1137       dbgs() << "\n";
1138     }
1139   }
1140 
1141   dbgs() << "\n";
1142 }
1143 #endif
1144 
1145 int R600MachineCFGStructurizer::improveSimpleJumpintoIf(MachineBasicBlock *HeadMBB,
1146     MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB,
1147     MachineBasicBlock **LandMBBPtr) {
1148   bool MigrateTrue = false;
1149   bool MigrateFalse = false;
1150 
1151   MachineBasicBlock *LandBlk = *LandMBBPtr;
1152 
1153   assert((!TrueMBB || TrueMBB->succ_size() <= 1)
1154          && (!FalseMBB || FalseMBB->succ_size() <= 1));
1155 
1156   if (TrueMBB == FalseMBB)
1157     return 0;
1158 
1159   MigrateTrue = needMigrateBlock(TrueMBB);
1160   MigrateFalse = needMigrateBlock(FalseMBB);
1161 
1162   if (!MigrateTrue && !MigrateFalse)
1163     return 0;
1164 
1165   // If we need to migrate either trueBlk and falseBlk, migrate the rest that
1166   // have more than one predecessors.  without doing this, its predecessor
1167   // rather than headBlk will have undefined value in initReg.
1168   if (!MigrateTrue && TrueMBB && TrueMBB->pred_size() > 1)
1169     MigrateTrue = true;
1170   if (!MigrateFalse && FalseMBB && FalseMBB->pred_size() > 1)
1171     MigrateFalse = true;
1172 
1173   LLVM_DEBUG(
1174       dbgs() << "before improveSimpleJumpintoIf: ";
1175       showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0););
1176 
1177   // org: headBlk => if () {trueBlk} else {falseBlk} => landBlk
1178   //
1179   // new: headBlk => if () {initReg = 1; org trueBlk branch} else
1180   //      {initReg = 0; org falseBlk branch }
1181   //      => landBlk => if (initReg) {org trueBlk} else {org falseBlk}
1182   //      => org landBlk
1183   //      if landBlk->pred_size() > 2, put the about if-else inside
1184   //      if (initReg !=2) {...}
1185   //
1186   // add initReg = initVal to headBlk
1187 
1188   const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
1189   if (!MigrateTrue || !MigrateFalse) {
1190     // XXX: We have an opportunity here to optimize the "branch into if" case
1191     // here.  Branch into if looks like this:
1192     //                        entry
1193     //                       /     |
1194     //           diamond_head       branch_from
1195     //             /      \           |
1196     // diamond_false        diamond_true
1197     //             \      /
1198     //               done
1199     //
1200     // The diamond_head block begins the "if" and the diamond_true block
1201     // is the block being "branched into".
1202     //
1203     // If MigrateTrue is true, then TrueBB is the block being "branched into"
1204     // and if MigrateFalse is true, then FalseBB is the block being
1205     // "branched into"
1206     //
1207     // Here is the pseudo code for how I think the optimization should work:
1208     // 1. Insert MOV GPR0, 0 before the branch instruction in diamond_head.
1209     // 2. Insert MOV GPR0, 1 before the branch instruction in branch_from.
1210     // 3. Move the branch instruction from diamond_head into its own basic
1211     //    block (new_block).
1212     // 4. Add an unconditional branch from diamond_head to new_block
1213     // 5. Replace the branch instruction in branch_from with an unconditional
1214     //    branch to new_block.  If branch_from has multiple predecessors, then
1215     //    we need to replace the True/False block in the branch
1216     //    instruction instead of replacing it.
1217     // 6. Change the condition of the branch instruction in new_block from
1218     //    COND to (COND || GPR0)
1219     //
1220     // In order insert these MOV instruction, we will need to use the
1221     // RegisterScavenger.  Usually liveness stops being tracked during
1222     // the late machine optimization passes, however if we implement
1223     // bool TargetRegisterInfo::requiresRegisterScavenging(
1224     //                                                const MachineFunction &MF)
1225     // and have it return true, liveness will be tracked correctly
1226     // by generic optimization passes.  We will also need to make sure that
1227     // all of our target-specific passes that run after regalloc and before
1228     // the CFGStructurizer track liveness and we will need to modify this pass
1229     // to correctly track liveness.
1230     //
1231     // After the above changes, the new CFG should look like this:
1232     //                        entry
1233     //                       /     |
1234     //           diamond_head       branch_from
1235     //                       \     /
1236     //                      new_block
1237     //                      /      |
1238     //         diamond_false        diamond_true
1239     //                      \      /
1240     //                        done
1241     //
1242     // Without this optimization, we are forced to duplicate the diamond_true
1243     // block and we will end up with a CFG like this:
1244     //
1245     //                        entry
1246     //                       /     |
1247     //           diamond_head       branch_from
1248     //             /      \                   |
1249     // diamond_false        diamond_true      diamond_true (duplicate)
1250     //             \      /                   |
1251     //               done --------------------|
1252     //
1253     // Duplicating diamond_true can be very costly especially if it has a
1254     // lot of instructions.
1255     return 0;
1256   }
1257 
1258   int NumNewBlk = 0;
1259 
1260   bool LandBlkHasOtherPred = (LandBlk->pred_size() > 2);
1261 
1262   //insert R600::ENDIF to avoid special case "input landBlk == NULL"
1263   MachineBasicBlock::iterator I = insertInstrBefore(LandBlk, R600::ENDIF);
1264 
1265   if (LandBlkHasOtherPred) {
1266     report_fatal_error("Extra register needed to handle CFG");
1267     Register CmpResReg =
1268         HeadMBB->getParent()->getRegInfo().createVirtualRegister(I32RC);
1269     report_fatal_error("Extra compare instruction needed to handle CFG");
1270     insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET,
1271         CmpResReg, DebugLoc());
1272   }
1273 
1274   // XXX: We are running this after RA, so creating virtual registers will
1275   // cause an assertion failure in the PostRA scheduling pass.
1276   Register InitReg =
1277       HeadMBB->getParent()->getRegInfo().createVirtualRegister(I32RC);
1278   insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET, InitReg,
1279       DebugLoc());
1280 
1281   if (MigrateTrue) {
1282     migrateInstruction(TrueMBB, LandBlk, I);
1283     // need to uncondionally insert the assignment to ensure a path from its
1284     // predecessor rather than headBlk has valid value in initReg if
1285     // (initVal != 1).
1286     report_fatal_error("Extra register needed to handle CFG");
1287   }
1288   insertInstrBefore(I, R600::ELSE);
1289 
1290   if (MigrateFalse) {
1291     migrateInstruction(FalseMBB, LandBlk, I);
1292     // need to uncondionally insert the assignment to ensure a path from its
1293     // predecessor rather than headBlk has valid value in initReg if
1294     // (initVal != 0)
1295     report_fatal_error("Extra register needed to handle CFG");
1296   }
1297 
1298   if (LandBlkHasOtherPred) {
1299     // add endif
1300     insertInstrBefore(I, R600::ENDIF);
1301 
1302     // put initReg = 2 to other predecessors of landBlk
1303     for (MachineBasicBlock *MBB : LandBlk->predecessors())
1304       if (MBB != TrueMBB && MBB != FalseMBB)
1305         report_fatal_error("Extra register needed to handle CFG");
1306   }
1307   LLVM_DEBUG(
1308       dbgs() << "result from improveSimpleJumpintoIf: ";
1309       showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0););
1310 
1311   // update landBlk
1312   *LandMBBPtr = LandBlk;
1313 
1314   return NumNewBlk;
1315 }
1316 
1317 void R600MachineCFGStructurizer::mergeSerialBlock(MachineBasicBlock *DstMBB,
1318     MachineBasicBlock *SrcMBB) {
1319   LLVM_DEBUG(dbgs() << "serialPattern BB" << DstMBB->getNumber() << " <= BB"
1320                     << SrcMBB->getNumber() << "\n";);
1321   DstMBB->splice(DstMBB->end(), SrcMBB, SrcMBB->begin(), SrcMBB->end());
1322 
1323   DstMBB->removeSuccessor(SrcMBB, true);
1324   cloneSuccessorList(DstMBB, SrcMBB);
1325 
1326   removeSuccessor(SrcMBB);
1327   MLI->removeBlock(SrcMBB);
1328   retireBlock(SrcMBB);
1329 }
1330 
1331 void R600MachineCFGStructurizer::mergeIfthenelseBlock(MachineInstr *BranchMI,
1332     MachineBasicBlock *MBB, MachineBasicBlock *TrueMBB,
1333     MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB) {
1334   assert (TrueMBB);
1335   LLVM_DEBUG(dbgs() << "ifPattern BB" << MBB->getNumber(); dbgs() << "{  ";
1336              if (TrueMBB) { dbgs() << "BB" << TrueMBB->getNumber(); } dbgs()
1337              << "  } else ";
1338              dbgs() << "{  "; if (FalseMBB) {
1339                dbgs() << "BB" << FalseMBB->getNumber();
1340              } dbgs() << "  }\n ";
1341              dbgs() << "landBlock: "; if (!LandMBB) { dbgs() << "NULL"; } else {
1342                dbgs() << "BB" << LandMBB->getNumber();
1343              } dbgs() << "\n";);
1344 
1345   int OldOpcode = BranchMI->getOpcode();
1346   DebugLoc BranchDL = BranchMI->getDebugLoc();
1347 
1348 //    transform to
1349 //    if cond
1350 //       trueBlk
1351 //    else
1352 //       falseBlk
1353 //    endif
1354 //    landBlk
1355 
1356   MachineBasicBlock::iterator I = BranchMI;
1357   insertCondBranchBefore(I, getBranchNzeroOpcode(OldOpcode),
1358       BranchDL);
1359 
1360   if (TrueMBB) {
1361     MBB->splice(I, TrueMBB, TrueMBB->begin(), TrueMBB->end());
1362     MBB->removeSuccessor(TrueMBB, true);
1363     if (LandMBB && TrueMBB->succ_size()!=0)
1364       TrueMBB->removeSuccessor(LandMBB, true);
1365     retireBlock(TrueMBB);
1366     MLI->removeBlock(TrueMBB);
1367   }
1368 
1369   if (FalseMBB) {
1370     insertInstrBefore(I, R600::ELSE);
1371     MBB->splice(I, FalseMBB, FalseMBB->begin(),
1372                    FalseMBB->end());
1373     MBB->removeSuccessor(FalseMBB, true);
1374     if (LandMBB && !FalseMBB->succ_empty())
1375       FalseMBB->removeSuccessor(LandMBB, true);
1376     retireBlock(FalseMBB);
1377     MLI->removeBlock(FalseMBB);
1378   }
1379   insertInstrBefore(I, R600::ENDIF);
1380 
1381   BranchMI->eraseFromParent();
1382 
1383   if (LandMBB && TrueMBB && FalseMBB)
1384     MBB->addSuccessor(LandMBB);
1385 }
1386 
1387 void R600MachineCFGStructurizer::mergeLooplandBlock(MachineBasicBlock *DstBlk,
1388     MachineBasicBlock *LandMBB) {
1389   LLVM_DEBUG(dbgs() << "loopPattern header = BB" << DstBlk->getNumber()
1390                     << " land = BB" << LandMBB->getNumber() << "\n";);
1391 
1392   insertInstrBefore(DstBlk, R600::WHILELOOP, DebugLoc());
1393   insertInstrEnd(DstBlk, R600::ENDLOOP, DebugLoc());
1394   DstBlk->replaceSuccessor(DstBlk, LandMBB);
1395 }
1396 
1397 void R600MachineCFGStructurizer::mergeLoopbreakBlock(MachineBasicBlock *ExitingMBB,
1398     MachineBasicBlock *LandMBB) {
1399   LLVM_DEBUG(dbgs() << "loopbreakPattern exiting = BB"
1400                     << ExitingMBB->getNumber() << " land = BB"
1401                     << LandMBB->getNumber() << "\n";);
1402   MachineInstr *BranchMI = getLoopendBlockBranchInstr(ExitingMBB);
1403   assert(BranchMI && isCondBranch(BranchMI));
1404   DebugLoc DL = BranchMI->getDebugLoc();
1405   MachineBasicBlock *TrueBranch = getTrueBranch(BranchMI);
1406   MachineBasicBlock::iterator I = BranchMI;
1407   if (TrueBranch != LandMBB)
1408     reversePredicateSetter(I, *I->getParent());
1409   insertCondBranchBefore(ExitingMBB, I, R600::IF_PREDICATE_SET, R600::PREDICATE_BIT, DL);
1410   insertInstrBefore(I, R600::BREAK);
1411   insertInstrBefore(I, R600::ENDIF);
1412   //now branchInst can be erase safely
1413   BranchMI->eraseFromParent();
1414   //now take care of successors, retire blocks
1415   ExitingMBB->removeSuccessor(LandMBB, true);
1416 }
1417 
1418 void R600MachineCFGStructurizer::settleLoopcontBlock(MachineBasicBlock *ContingMBB,
1419     MachineBasicBlock *ContMBB) {
1420   LLVM_DEBUG(dbgs() << "settleLoopcontBlock conting = BB"
1421                     << ContingMBB->getNumber() << ", cont = BB"
1422                     << ContMBB->getNumber() << "\n";);
1423 
1424   MachineInstr *MI = getLoopendBlockBranchInstr(ContingMBB);
1425   if (MI) {
1426     assert(isCondBranch(MI));
1427     MachineBasicBlock::iterator I = MI;
1428     MachineBasicBlock *TrueBranch = getTrueBranch(MI);
1429     int OldOpcode = MI->getOpcode();
1430     DebugLoc DL = MI->getDebugLoc();
1431 
1432     bool UseContinueLogical = ((&*ContingMBB->rbegin()) == MI);
1433 
1434     if (!UseContinueLogical) {
1435       int BranchOpcode =
1436           TrueBranch == ContMBB ? getBranchNzeroOpcode(OldOpcode) :
1437           getBranchZeroOpcode(OldOpcode);
1438       insertCondBranchBefore(I, BranchOpcode, DL);
1439       // insertEnd to ensure phi-moves, if exist, go before the continue-instr.
1440       insertInstrEnd(ContingMBB, R600::CONTINUE, DL);
1441       insertInstrEnd(ContingMBB, R600::ENDIF, DL);
1442     } else {
1443       int BranchOpcode =
1444           TrueBranch == ContMBB ? getContinueNzeroOpcode(OldOpcode) :
1445           getContinueZeroOpcode(OldOpcode);
1446       insertCondBranchBefore(I, BranchOpcode, DL);
1447     }
1448 
1449     MI->eraseFromParent();
1450   } else {
1451     // if we've arrived here then we've already erased the branch instruction
1452     // travel back up the basic block to see the last reference of our debug
1453     // location we've just inserted that reference here so it should be
1454     // representative insertEnd to ensure phi-moves, if exist, go before the
1455     // continue-instr.
1456     insertInstrEnd(ContingMBB, R600::CONTINUE,
1457         getLastDebugLocInBB(ContingMBB));
1458   }
1459 }
1460 
1461 int R600MachineCFGStructurizer::cloneOnSideEntryTo(MachineBasicBlock *PreMBB,
1462     MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB) {
1463   int Cloned = 0;
1464   assert(PreMBB->isSuccessor(SrcMBB));
1465   while (SrcMBB && SrcMBB != DstMBB) {
1466     assert(SrcMBB->succ_size() == 1);
1467     if (SrcMBB->pred_size() > 1) {
1468       SrcMBB = cloneBlockForPredecessor(SrcMBB, PreMBB);
1469       ++Cloned;
1470     }
1471 
1472     PreMBB = SrcMBB;
1473     SrcMBB = *SrcMBB->succ_begin();
1474   }
1475 
1476   return Cloned;
1477 }
1478 
1479 MachineBasicBlock *
1480 R600MachineCFGStructurizer::cloneBlockForPredecessor(MachineBasicBlock *MBB,
1481     MachineBasicBlock *PredMBB) {
1482   assert(PredMBB->isSuccessor(MBB) && "succBlk is not a predecessor of curBlk");
1483 
1484   MachineBasicBlock *CloneMBB = clone(MBB);  //clone instructions
1485   replaceInstrUseOfBlockWith(PredMBB, MBB, CloneMBB);
1486   //srcBlk, oldBlk, newBlk
1487 
1488   PredMBB->replaceSuccessor(MBB, CloneMBB);
1489 
1490   // add all successor to cloneBlk
1491   cloneSuccessorList(CloneMBB, MBB);
1492 
1493   numClonedInstr += MBB->size();
1494 
1495   LLVM_DEBUG(dbgs() << "Cloned block: "
1496                     << "BB" << MBB->getNumber() << "size " << MBB->size()
1497                     << "\n";);
1498 
1499   SHOWNEWBLK(CloneMBB, "result of Cloned block: ");
1500 
1501   return CloneMBB;
1502 }
1503 
1504 void R600MachineCFGStructurizer::migrateInstruction(MachineBasicBlock *SrcMBB,
1505     MachineBasicBlock *DstMBB, MachineBasicBlock::iterator I) {
1506   MachineBasicBlock::iterator SpliceEnd;
1507   //look for the input branchinstr, not the AMDGPU branchinstr
1508   MachineInstr *BranchMI = getNormalBlockBranchInstr(SrcMBB);
1509   if (!BranchMI) {
1510     LLVM_DEBUG(dbgs() << "migrateInstruction don't see branch instr\n";);
1511     SpliceEnd = SrcMBB->end();
1512   } else {
1513     LLVM_DEBUG(dbgs() << "migrateInstruction see branch instr: " << *BranchMI);
1514     SpliceEnd = BranchMI;
1515   }
1516   LLVM_DEBUG(dbgs() << "migrateInstruction before splice dstSize = "
1517                     << DstMBB->size() << "srcSize = " << SrcMBB->size()
1518                     << "\n";);
1519 
1520   //splice insert before insertPos
1521   DstMBB->splice(I, SrcMBB, SrcMBB->begin(), SpliceEnd);
1522 
1523   LLVM_DEBUG(dbgs() << "migrateInstruction after splice dstSize = "
1524                     << DstMBB->size() << "srcSize = " << SrcMBB->size()
1525                     << '\n';);
1526 }
1527 
1528 MachineBasicBlock *
1529 R600MachineCFGStructurizer::normalizeInfiniteLoopExit(MachineLoop* LoopRep) {
1530   MachineBasicBlock *LoopHeader = LoopRep->getHeader();
1531   MachineBasicBlock *LoopLatch = LoopRep->getLoopLatch();
1532 
1533   if (!LoopHeader || !LoopLatch)
1534     return nullptr;
1535   MachineInstr *BranchMI = getLoopendBlockBranchInstr(LoopLatch);
1536   // Is LoopRep an infinite loop ?
1537   if (!BranchMI || !isUncondBranch(BranchMI))
1538     return nullptr;
1539 
1540   MachineBasicBlock *DummyExitBlk = FuncRep->CreateMachineBasicBlock();
1541   FuncRep->push_back(DummyExitBlk);  //insert to function
1542   SHOWNEWBLK(DummyExitBlk, "DummyExitBlock to normalize infiniteLoop: ");
1543   LLVM_DEBUG(dbgs() << "Old branch instr: " << *BranchMI << "\n";);
1544   LLVMContext &Ctx = LoopHeader->getParent()->getFunction().getContext();
1545   Ctx.emitError("Extra register needed to handle CFG");
1546   return nullptr;
1547 }
1548 
1549 void R600MachineCFGStructurizer::removeUnconditionalBranch(MachineBasicBlock *MBB) {
1550   MachineInstr *BranchMI;
1551 
1552   // I saw two unconditional branch in one basic block in example
1553   // test_fc_do_while_or.c need to fix the upstream on this to remove the loop.
1554   while ((BranchMI = getLoopendBlockBranchInstr(MBB))
1555           && isUncondBranch(BranchMI)) {
1556     LLVM_DEBUG(dbgs() << "Removing uncond branch instr: " << *BranchMI);
1557     BranchMI->eraseFromParent();
1558   }
1559 }
1560 
1561 void R600MachineCFGStructurizer::removeRedundantConditionalBranch(
1562     MachineBasicBlock *MBB) {
1563   if (MBB->succ_size() != 2)
1564     return;
1565   MachineBasicBlock *MBB1 = *MBB->succ_begin();
1566   MachineBasicBlock *MBB2 = *std::next(MBB->succ_begin());
1567   if (MBB1 != MBB2)
1568     return;
1569 
1570   MachineInstr *BranchMI = getNormalBlockBranchInstr(MBB);
1571   assert(BranchMI && isCondBranch(BranchMI));
1572   LLVM_DEBUG(dbgs() << "Removing unneeded cond branch instr: " << *BranchMI);
1573   BranchMI->eraseFromParent();
1574   SHOWNEWBLK(MBB1, "Removing redundant successor");
1575   MBB->removeSuccessor(MBB1, true);
1576 }
1577 
1578 void R600MachineCFGStructurizer::addDummyExitBlock(
1579     SmallVectorImpl<MachineBasicBlock*> &RetMBB) {
1580   MachineBasicBlock *DummyExitBlk = FuncRep->CreateMachineBasicBlock();
1581   FuncRep->push_back(DummyExitBlk);  //insert to function
1582   insertInstrEnd(DummyExitBlk, R600::RETURN);
1583 
1584   for (MachineBasicBlock *MBB : RetMBB) {
1585     if (MachineInstr *MI = getReturnInstr(MBB))
1586       MI->eraseFromParent();
1587     MBB->addSuccessor(DummyExitBlk);
1588     LLVM_DEBUG(dbgs() << "Add dummyExitBlock to BB" << MBB->getNumber()
1589                       << " successors\n";);
1590   }
1591   SHOWNEWBLK(DummyExitBlk, "DummyExitBlock: ");
1592 }
1593 
1594 void R600MachineCFGStructurizer::removeSuccessor(MachineBasicBlock *MBB) {
1595   while (MBB->succ_size())
1596     MBB->removeSuccessor(*MBB->succ_begin());
1597 }
1598 
1599 void R600MachineCFGStructurizer::recordSccnum(MachineBasicBlock *MBB,
1600     int SccNum) {
1601   BlockInformation *&srcBlkInfo = BlockInfoMap[MBB];
1602   if (!srcBlkInfo)
1603     srcBlkInfo = new BlockInformation();
1604   srcBlkInfo->SccNum = SccNum;
1605 }
1606 
1607 void R600MachineCFGStructurizer::retireBlock(MachineBasicBlock *MBB) {
1608   LLVM_DEBUG(dbgs() << "Retiring BB" << MBB->getNumber() << "\n";);
1609 
1610   BlockInformation *&SrcBlkInfo = BlockInfoMap[MBB];
1611 
1612   if (!SrcBlkInfo)
1613     SrcBlkInfo = new BlockInformation();
1614 
1615   SrcBlkInfo->IsRetired = true;
1616   assert(MBB->succ_empty() && MBB->pred_empty() && "can't retire block yet");
1617 }
1618 
1619 INITIALIZE_PASS_BEGIN(R600MachineCFGStructurizer, "amdgpustructurizer",
1620                       "AMDGPU CFG Structurizer", false, false)
1621 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
1622 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass)
1623 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
1624 INITIALIZE_PASS_END(R600MachineCFGStructurizer, "amdgpustructurizer",
1625                       "AMDGPU CFG Structurizer", false, false)
1626 
1627 FunctionPass *llvm::createR600MachineCFGStructurizerPass() {
1628   return new R600MachineCFGStructurizer();
1629 }
1630