1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===-- AMDILCFGStructurizer.cpp - CFG Structurizer -----------------------===//
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//                     The LLVM Compiler Infrastructure
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file is distributed under the University of Illinois Open Source
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// License. See LICENSE.TXT for details.
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//==-----------------------------------------------------------------------===//
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUGME 0
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_TYPE "structcfg"
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDGPUInstrInfo.h"
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDIL.h"
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "AMDILUtilityFunctions.h"
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/SCCIterator.h"
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/SmallVector.h"
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/ADT/Statistic.h"
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Analysis/DominatorInternals.h"
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Analysis/Dominators.h"
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineDominators.h"
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineDominators.h"
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunction.h"
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunctionAnalysis.h"
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunctionPass.h"
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineFunctionPass.h"
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineInstrBuilder.h"
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineJumpTableInfo.h"
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineLoopInfo.h"
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/CodeGen/MachineRegisterInfo.h"
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "llvm/Target/TargetInstrInfo.h"
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define FirstNonDebugInstr(A) A->begin()
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvm;
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// TODO: move-begin.
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Statistics for CFGStructurizer.
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numSerialPatternMatch,    "CFGStructurizer number of serial pattern "
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    "matched");
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numIfPatternMatch,        "CFGStructurizer number of if pattern "
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    "matched");
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numLoopbreakPatternMatch, "CFGStructurizer number of loop-break "
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    "pattern matched");
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numLoopcontPatternMatch,  "CFGStructurizer number of loop-continue "
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    "pattern matched");
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numLoopPatternMatch,      "CFGStructurizer number of loop pattern "
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    "matched");
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numClonedBlock,           "CFGStructurizer cloned blocks");
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgSTATISTIC(numClonedInstr,           "CFGStructurizer cloned instructions");
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// Miscellaneous utility for CFGStructurizer.
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SHOWNEWINSTR(i) \
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) errs() << "New instr: " << *i << "\n"
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SHOWNEWBLK(b, msg) \
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgif (DEBUGME) { \
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  errs() << msg << "BB" << b->getNumber() << "size " << b->size(); \
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  errs() << "\n"; \
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SHOWBLK_DETAIL(b, msg) \
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgif (DEBUGME) { \
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (b) { \
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  errs() << msg << "BB" << b->getNumber() << "size " << b->size(); \
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  b->print(errs()); \
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  errs() << "\n"; \
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } \
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INVALIDSCCNUM -1
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define INVALIDREGNUM 0
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class LoopinfoT>
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid PrintLoopinfo(const LoopinfoT &LoopInfo, llvm::raw_ostream &OS) {
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename LoopinfoT::iterator iter = LoopInfo.begin(),
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = LoopInfo.end();
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter != iterEnd; ++iter) {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    (*iter)->print(OS, 0);
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class NodeT>
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid ReverseVector(SmallVector<NodeT *, DEFAULT_VEC_SLOTS> &Src) {
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  size_t sz = Src.size();
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (size_t i = 0; i < sz/2; ++i) {
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    NodeT *t = Src[i];
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Src[i] = Src[sz - i - 1];
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Src[sz - i - 1] = t;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end namespace llvmCFGStruct
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// MachinePostDominatorTree
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm {
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// to compute the a post-dominator tree.
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct MachinePostDominatorTree : public MachineFunctionPass {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static char ID; // Pass identification, replacement for typeid
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DominatorTreeBase<MachineBasicBlock> *DT;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  MachinePostDominatorTree() : MachineFunctionPass(ID)
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DT = new DominatorTreeBase<MachineBasicBlock>(true); //true indicate
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // postdominator
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ~MachinePostDominatorTree();
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  virtual bool runOnMachineFunction(MachineFunction &MF);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    AU.setPreservesAll();
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineFunctionPass::getAnalysisUsage(AU);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline const std::vector<MachineBasicBlock *> &getRoots() const {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->getRoots();
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline MachineDomTreeNode *getRootNode() const {
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->getRootNode();
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->getNode(BB);
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->getNode(BB);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline bool dominates(MachineDomTreeNode *A, MachineDomTreeNode *B) const {
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->dominates(A, B);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline bool dominates(MachineBasicBlock *A, MachineBasicBlock *B) const {
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->dominates(A, B);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline bool
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  properlyDominates(const MachineDomTreeNode *A, MachineDomTreeNode *B) const {
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->properlyDominates(A, B);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline bool
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  properlyDominates(MachineBasicBlock *A, MachineBasicBlock *B) const {
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->properlyDominates(A, B);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  inline MachineBasicBlock *
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B) {
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DT->findNearestCommonDominator(A, B);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  virtual void print(llvm::raw_ostream &OS, const Module *M = 0) const {
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DT->print(OS);
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar MachinePostDominatorTree::ID = 0;
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic RegisterPass<MachinePostDominatorTree>
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmachinePostDominatorTreePass("machinepostdomtree",
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             "MachinePostDominator Tree Construction",
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             true, true);
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//const PassInfo *const llvm::MachinePostDominatorsID
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//= &machinePostDominatorTreePass;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool MachinePostDominatorTree::runOnMachineFunction(MachineFunction &F) {
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DT->recalculate(F);
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //DEBUG(DT->dump());
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return false;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgMachinePostDominatorTree::~MachinePostDominatorTree() {
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  delete DT;
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// supporting data structure for CFGStructurizer
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct CFGStructTraits {
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate <class InstrT>
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass BlockInformation {
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool isRetired;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int  sccNum;
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //SmallVector<InstrT*, DEFAULT_VEC_SLOTS> succInstr;
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //Instructions defining the corresponding successor.
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockInformation() : isRetired(false), sccNum(INVALIDSCCNUM) {}
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate <class BlockT, class InstrT, class RegiT>
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass LandInformation {
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *landBlk;
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::set<RegiT> breakInitRegs;  //Registers that need to "reg = 0", before
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  //WHILELOOP(thisloop) init before entering
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  //thisloop.
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::set<RegiT> contInitRegs;   //Registers that need to "reg = 0", after
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  //WHILELOOP(thisloop) init after entering
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  //thisloop.
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::set<RegiT> endbranchInitRegs; //Init before entering this loop, at loop
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     //land block, branch cond on this reg.
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::set<RegiT> breakOnRegs;       //registers that need to "if (reg) break
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     //endif" after ENDLOOP(thisloop) break
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     //outerLoopOf(thisLoop).
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::set<RegiT> contOnRegs;       //registers that need to "if (reg) continue
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    //endif" after ENDLOOP(thisloop) continue on
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    //outerLoopOf(thisLoop).
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LandInformation() : landBlk(NULL) {}
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvmCFGStruct
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGStructurizer
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// bixia TODO: port it to BasicBlock, not just MachineBasicBlock.
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass  CFGStructurizer
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef enum {
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    Not_SinglePath = 0,
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SinglePath_InPath = 1,
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SinglePath_NotInPath = 2
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } PathToKind;
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename PassT::InstructionType         InstrT;
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename PassT::FunctionType            FuncT;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename PassT::DominatortreeType       DomTreeT;
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename PassT::PostDominatortreeType   PostDomTreeT;
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename PassT::DomTreeNodeType         DomTreeNodeT;
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename PassT::LoopinfoType            LoopInfoT;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef GraphTraits<FuncT *>                    FuncGTraits;
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //typedef FuncGTraits::nodes_iterator BlockIterator;
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename FuncT::iterator                BlockIterator;
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename FuncGTraits::NodeType          BlockT;
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef GraphTraits<BlockT *>                   BlockGTraits;
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef GraphTraits<Inverse<BlockT *> >         InvBlockGTraits;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //typedef BlockGTraits::succ_iterator InstructionIterator;
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename BlockT::iterator               InstrIterator;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef CFGStructTraits<PassT>                  CFGTraits;
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef BlockInformation<InstrT>                BlockInfo;
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef std::map<BlockT *, BlockInfo *>         BlockInfoMap;
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef int                                     RegiT;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef typename PassT::LoopType                LoopT;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef LandInformation<BlockT, InstrT, RegiT>  LoopLandInfo;
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        typedef std::map<LoopT *, LoopLandInfo *> LoopLandInfoMap;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        //landing info for loop break
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef SmallVector<BlockT *, 32>               BlockTSmallerVector;
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGStructurizer();
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ~CFGStructurizer();
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  /// Perform the CFG structurization
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool run(FuncT &Func, PassT &Pass, const AMDGPURegisterInfo *tri);
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  /// Perform the CFG preparation
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool prepare(FuncT &Func, PassT &Pass, const AMDGPURegisterInfo *tri);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void reversePredicateSetter(typename BlockT::iterator);
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void   orderBlocks();
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void   printOrderedBlocks(llvm::raw_ostream &OS);
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int patternMatch(BlockT *CurBlock);
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int patternMatchGroup(BlockT *CurBlock);
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int serialPatternMatch(BlockT *CurBlock);
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int ifPatternMatch(BlockT *CurBlock);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int switchPatternMatch(BlockT *CurBlock);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int loopendPatternMatch(BlockT *CurBlock);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int loopPatternMatch(BlockT *CurBlock);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int loopbreakPatternMatch(LoopT *LoopRep, BlockT *LoopHeader);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int loopcontPatternMatch(LoopT *LoopRep, BlockT *LoopHeader);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //int loopWithoutBreak(BlockT *);
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void handleLoopbreak (BlockT *ExitingBlock, LoopT *ExitingLoop,
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        BlockT *ExitBlock, LoopT *exitLoop, BlockT *landBlock);
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void handleLoopcontBlock(BlockT *ContingBlock, LoopT *contingLoop,
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           BlockT *ContBlock, LoopT *contLoop);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool isSameloopDetachedContbreak(BlockT *Src1Block, BlockT *Src2Block);
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int handleJumpintoIf(BlockT *HeadBlock, BlockT *TrueBlock,
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       BlockT *FalseBlock);
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int handleJumpintoIfImp(BlockT *HeadBlock, BlockT *TrueBlock,
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          BlockT *FalseBlock);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int improveSimpleJumpintoIf(BlockT *HeadBlock, BlockT *TrueBlock,
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              BlockT *FalseBlock, BlockT **LandBlockPtr);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void showImproveSimpleJumpintoIf(BlockT *HeadBlock, BlockT *TrueBlock,
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   BlockT *FalseBlock, BlockT *LandBlock,
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   bool Detail = false);
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  PathToKind singlePathTo(BlockT *SrcBlock, BlockT *DstBlock,
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          bool AllowSideEntry = true);
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *singlePathEnd(BlockT *srcBlock, BlockT *DstBlock,
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        bool AllowSideEntry = true);
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int cloneOnSideEntryTo(BlockT *PreBlock, BlockT *SrcBlock, BlockT *DstBlock);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void mergeSerialBlock(BlockT *DstBlock, BlockT *srcBlock);
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void mergeIfthenelseBlock(InstrT *BranchInstr, BlockT *CurBlock,
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            BlockT *TrueBlock, BlockT *FalseBlock,
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            BlockT *LandBlock);
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void mergeLooplandBlock(BlockT *DstBlock, LoopLandInfo *LoopLand);
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void mergeLoopbreakBlock(BlockT *ExitingBlock, BlockT *ExitBlock,
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           BlockT *ExitLandBlock, RegiT SetReg);
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void settleLoopcontBlock(BlockT *ContingBlock, BlockT *ContBlock,
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                           RegiT SetReg);
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *relocateLoopcontBlock(LoopT *ParentLoopRep, LoopT *LoopRep,
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                std::set<BlockT*> &ExitBlockSet,
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                BlockT *ExitLandBlk);
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *addLoopEndbranchBlock(LoopT *LoopRep,
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                BlockTSmallerVector &ExitingBlocks,
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                BlockTSmallerVector &ExitBlocks);
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *normalizeInfiniteLoopExit(LoopT *LoopRep);
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void removeUnconditionalBranch(BlockT *SrcBlock);
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void removeRedundantConditionalBranch(BlockT *SrcBlock);
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void addDummyExitBlock(SmallVector<BlockT *, DEFAULT_VEC_SLOTS> &RetBlocks);
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void removeSuccessor(BlockT *SrcBlock);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *cloneBlockForPredecessor(BlockT *CurBlock, BlockT *PredBlock);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *exitingBlock2ExitBlock (LoopT *LoopRep, BlockT *exitingBlock);
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void migrateInstruction(BlockT *SrcBlock, BlockT *DstBlock,
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          InstrIterator InsertPos);
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void recordSccnum(BlockT *SrcBlock, int SCCNum);
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int getSCCNum(BlockT *srcBlk);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void retireBlock(BlockT *DstBlock, BlockT *SrcBlock);
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool isRetiredBlock(BlockT *SrcBlock);
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool isActiveLoophead(BlockT *CurBlock);
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool needMigrateBlock(BlockT *Block);
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *recordLoopLandBlock(LoopT *LoopRep, BlockT *LandBlock,
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              BlockTSmallerVector &exitBlocks,
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              std::set<BlockT*> &ExitBlockSet);
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void setLoopLandBlock(LoopT *LoopRep, BlockT *Block = NULL);
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *getLoopLandBlock(LoopT *LoopRep);
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *getLoopLandInfo(LoopT *LoopRep);
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void addLoopBreakOnReg(LoopT *LoopRep, RegiT RegNum);
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void addLoopContOnReg(LoopT *LoopRep, RegiT RegNum);
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void addLoopBreakInitReg(LoopT *LoopRep, RegiT RegNum);
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void addLoopContInitReg(LoopT *LoopRep, RegiT RegNum);
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  void addLoopEndbranchInitReg(LoopT *LoopRep, RegiT RegNum);
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool hasBackEdge(BlockT *curBlock);
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned getLoopDepth  (LoopT *LoopRep);
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int countActiveBlock(
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator IterStart,
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator IterEnd);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *findNearestCommonPostDom(std::set<BlockT *>&);
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *findNearestCommonPostDom(BlockT *Block1, BlockT *Block2);
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DomTreeT *domTree;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  PostDomTreeT *postDomTree;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopInfoT *loopInfo;
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  PassT *passRep;
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  FuncT *funcRep;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockInfoMap blockInfoMap;
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfoMap loopLandInfoMap;
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<BlockT *, DEFAULT_VEC_SLOTS> orderedBlks;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const AMDGPURegisterInfo *TRI;
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};  //template class CFGStructurizer
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> CFGStructurizer<PassT>::CFGStructurizer()
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  : domTree(NULL), postDomTree(NULL), loopInfo(NULL) {
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> CFGStructurizer<PassT>::~CFGStructurizer() {
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename BlockInfoMap::iterator I = blockInfoMap.begin(),
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       E = blockInfoMap.end(); I != E; ++I) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    delete I->second;
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::prepare(FuncT &func, PassT &pass,
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     const AMDGPURegisterInfo * tri) {
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  passRep = &pass;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  funcRep = &func;
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TRI = tri;
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool changed = false;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //func.RenumberBlocks();
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //to do, if not reducible flow graph, make it so ???
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "AMDGPUCFGStructurizer::prepare\n";
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //func.viewCFG();
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //func.viewCFGOnly();
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //func.dump();
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //FIXME: gcc complains on this.
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //domTree = &pass.getAnalysis<DomTreeT>();
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //domTree = CFGTraits::getDominatorTree(pass);
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //if (DEBUGME) {
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //    domTree->print(errs());
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //}
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //FIXME: gcc complains on this.
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //domTree = &pass.getAnalysis<DomTreeT>();
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //postDomTree = CFGTraits::getPostDominatorTree(pass);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //if (DEBUGME) {
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //   postDomTree->print(errs());
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //}
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //FIXME: gcc complains on this.
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //loopInfo = &pass.getAnalysis<LoopInfoT>();
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  loopInfo = CFGTraits::getLoopInfo(pass);
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "LoopInfo:\n";
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    PrintLoopinfo(*loopInfo, errs());
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  orderBlocks();
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Ordered blocks:\n";
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    printOrderedBlocks(errs());
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<BlockT *, DEFAULT_VEC_SLOTS> retBlks;
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename LoopInfoT::iterator iter = loopInfo->begin(),
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = loopInfo->end();
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter != iterEnd; ++iter) {
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LoopT* loopRep = (*iter);
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockTSmallerVector exitingBlks;
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    loopRep->getExitingBlocks(exitingBlks);
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (exitingBlks.size() == 0) {
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT* dummyExitBlk = normalizeInfiniteLoopExit(loopRep);
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (dummyExitBlk != NULL)
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        retBlks.push_back(dummyExitBlk);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Remove unconditional branch instr.
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Add dummy exit block iff there are multiple returns.
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterBlk = orderedBlks.begin(), iterEndBlk = orderedBlks.end();
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterBlk != iterEndBlk;
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ++iterBlk) {
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curBlk = *iterBlk;
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    removeUnconditionalBranch(curBlk);
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    removeRedundantConditionalBranch(curBlk);
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (CFGTraits::isReturnBlock(curBlk)) {
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      retBlks.push_back(curBlk);
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(curBlk->succ_size() <= 2);
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //assert(curBlk->size() > 0);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //removeEmptyBlock(curBlk) ??
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //for
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (retBlks.size() >= 2) {
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    addDummyExitBlock(retBlks);
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    changed = true;
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return changed;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //CFGStructurizer::prepare
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::run(FuncT &func, PassT &pass,
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const AMDGPURegisterInfo * tri) {
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  passRep = &pass;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  funcRep = &func;
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TRI = tri;
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //func.RenumberBlocks();
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //Assume reducible CFG...
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "AMDGPUCFGStructurizer::run\n";
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //errs() << func.getFunction()->getNameStr() << "\n";
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    func.viewCFG();
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //func.viewCFGOnly();
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //func.dump();
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 1
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //FIXME: gcc complains on this.
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //domTree = &pass.getAnalysis<DomTreeT>();
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  domTree = CFGTraits::getDominatorTree(pass);
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    domTree->print(errs(), (const llvm::Module*)0);
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //FIXME: gcc complains on this.
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //domTree = &pass.getAnalysis<DomTreeT>();
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  postDomTree = CFGTraits::getPostDominatorTree(pass);
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    postDomTree->print(errs());
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //FIXME: gcc complains on this.
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //loopInfo = &pass.getAnalysis<LoopInfoT>();
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  loopInfo = CFGTraits::getLoopInfo(pass);
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "LoopInfo:\n";
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    PrintLoopinfo(*loopInfo, errs());
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  orderBlocks();
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//#define STRESSTEST
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef STRESSTEST
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //Use the worse block ordering to test the algorithm.
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ReverseVector(orderedBlks);
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Ordered blocks:\n";
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    printOrderedBlocks(errs());
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numIter = 0;
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool finish = false;
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *curBlk;
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool makeProgress = false;
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numRemainedBlk = countActiveBlock(orderedBlks.begin(),
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        orderedBlks.end());
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  do {
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++numIter;
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "numIter = " << numIter
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             << ", numRemaintedBlk = " << numRemainedBlk << "\n";
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      iterBlk = orderedBlks.begin();
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      iterBlkEnd = orderedBlks.end();
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sccBeginIter = iterBlk;
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *sccBeginBlk = NULL;
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int sccNumBlk = 0;  // The number of active blocks, init to a
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        // maximum possible number.
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int sccNumIter;     // Number of iteration in this SCC.
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    while (iterBlk != iterBlkEnd) {
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curBlk = *iterBlk;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (sccBeginBlk == NULL) {
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        sccBeginIter = iterBlk;
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        sccBeginBlk = curBlk;
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        sccNumIter = 0;
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        sccNumBlk = numRemainedBlk; // Init to maximum possible number.
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (DEBUGME) {
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              errs() << "start processing SCC" << getSCCNum(sccBeginBlk);
599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              errs() << "\n";
600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!isRetiredBlock(curBlk)) {
604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        patternMatch(curBlk);
605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ++iterBlk;
608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bool contNextScc = true;
610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (iterBlk == iterBlkEnd
611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          || getSCCNum(sccBeginBlk) != getSCCNum(*iterBlk)) {
612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // Just finish one scc.
613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++sccNumIter;
614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        int sccRemainedNumBlk = countActiveBlock(sccBeginIter, iterBlk);
615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (sccRemainedNumBlk != 1 && sccRemainedNumBlk >= sccNumBlk) {
616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          if (DEBUGME) {
617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            errs() << "Can't reduce SCC " << getSCCNum(curBlk)
618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   << ", sccNumIter = " << sccNumIter;
619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            errs() << "doesn't make any progress\n";
620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          }
621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          contNextScc = true;
622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else if (sccRemainedNumBlk != 1 && sccRemainedNumBlk < sccNumBlk) {
623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          sccNumBlk = sccRemainedNumBlk;
624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          iterBlk = sccBeginIter;
625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          contNextScc = false;
626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          if (DEBUGME) {
627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            errs() << "repeat processing SCC" << getSCCNum(curBlk)
628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   << "sccNumIter = " << sccNumIter << "\n";
629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            func.viewCFG();
630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            //func.viewCFGOnly();
631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          }
632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else {
633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          // Finish the current scc.
634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          contNextScc = true;
635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // Continue on next component in the current scc.
638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        contNextScc = false;
639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (contNextScc) {
642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        sccBeginBlk = NULL;
643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } //while, "one iteration" over the function.
645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *entryBlk = FuncGTraits::nodes_begin(&func);
647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (entryBlk->succ_size() == 0) {
648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      finish = true;
649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "Reduce to one block\n";
651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int newnumRemainedBlk
654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        = countActiveBlock(orderedBlks.begin(), orderedBlks.end());
655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // consider cloned blocks ??
656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (newnumRemainedBlk == 1 || newnumRemainedBlk < numRemainedBlk) {
657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        makeProgress = true;
658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        numRemainedBlk = newnumRemainedBlk;
659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        makeProgress = false;
661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (DEBUGME) {
662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          errs() << "No progress\n";
663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } while (!finish && makeProgress);
667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Misc wrap up to maintain the consistency of the Function representation.
669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::wrapup(FuncGTraits::nodes_begin(&func));
670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Detach retired Block, release memory.
672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename BlockInfoMap::iterator iterMap = blockInfoMap.begin(),
673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEndMap = blockInfoMap.end(); iterMap != iterEndMap; ++iterMap) {
674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if ((*iterMap).second && (*iterMap).second->isRetired) {
675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(((*iterMap).first)->getNumber() != -1);
676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "Erase BB" << ((*iterMap).first)->getNumber() << "\n";
678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (*iterMap).first->eraseFromParent();  //Remove from the parent Function.
680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    delete (*iterMap).second;
682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  blockInfoMap.clear();
684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // clear loopLandInfoMap
686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename LoopLandInfoMap::iterator iterMap = loopLandInfoMap.begin(),
687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEndMap = loopLandInfoMap.end(); iterMap != iterEndMap; ++iterMap) {
688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    delete (*iterMap).second;
689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  loopLandInfoMap.clear();
691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    func.viewCFG();
694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //func.dump();
695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!finish) {
698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(!"IRREDUCIBL_CF");
699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return true;
702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //CFGStructurizer::run
703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// Print the ordered Blocks.
705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::printOrderedBlocks(llvm::raw_ostream &os) {
708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  size_t i = 0;
709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::const_iterator
710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      iterBlk = orderedBlks.begin(), iterBlkEnd = orderedBlks.end();
711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterBlk != iterBlkEnd;
712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ++iterBlk, ++i) {
713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    os << "BB" << (*iterBlk)->getNumber();
714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    os << "(" << getSCCNum(*iterBlk) << "," << (*iterBlk)->size() << ")";
715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (i != 0 && i % 10 == 0) {
716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      os << "\n";
717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      os << " ";
719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //printOrderedBlocks
722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/// Compute the reversed DFS post order of Blocks
724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org///
725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> void CFGStructurizer<PassT>::orderBlocks() {
726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int sccNum = 0;
727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *bb;
728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (scc_iterator<FuncT *> sccIter = scc_begin(funcRep),
729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       sccEnd = scc_end(funcRep); sccIter != sccEnd; ++sccIter, ++sccNum) {
730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    std::vector<BlockT *> &sccNext = *sccIter;
731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (typename std::vector<BlockT *>::const_iterator
732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blockIter = sccNext.begin(), blockEnd = sccNext.end();
733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         blockIter != blockEnd; ++blockIter) {
734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      bb = *blockIter;
735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      orderedBlks.push_back(bb);
736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      recordSccnum(bb, sccNum);
737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //walk through all the block in func to check for unreachable
741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (BlockIterator blockIter1 = FuncGTraits::nodes_begin(funcRep),
742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       blockEnd1 = FuncGTraits::nodes_end(funcRep);
743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       blockIter1 != blockEnd1; ++blockIter1) {
744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *bb = &(*blockIter1);
745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    sccNum = getSCCNum(bb);
746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (sccNum == INVALIDSCCNUM) {
747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "unreachable block BB" << bb->getNumber() << "\n";
748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //end of for
750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //orderBlocks
751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT> int CFGStructurizer<PassT>::patternMatch(BlockT *curBlk) {
753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numMatch = 0;
754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int curMatch;
755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "Begin patternMatch BB" << curBlk->getNumber() << "\n";
758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while ((curMatch = patternMatchGroup(curBlk)) > 0) {
761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    numMatch += curMatch;
762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "End patternMatch BB" << curBlk->getNumber()
766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      << ", numMatch = " << numMatch << "\n";
767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return numMatch;
770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //patternMatch
771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::patternMatchGroup(BlockT *curBlk) {
774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numMatch = 0;
775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numMatch += serialPatternMatch(curBlk);
776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numMatch += ifPatternMatch(curBlk);
777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //numMatch += switchPatternMatch(curBlk);
778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numMatch += loopendPatternMatch(curBlk);
779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numMatch += loopPatternMatch(curBlk);
780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return numMatch;
781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}//patternMatchGroup
782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::serialPatternMatch(BlockT *curBlk) {
785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (curBlk->succ_size() != 1) {
786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *childBlk = *curBlk->succ_begin();
790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (childBlk->pred_size() != 1 || isActiveLoophead(childBlk)) {
791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  mergeSerialBlock(curBlk, childBlk);
795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ++numSerialPatternMatch;
796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return 1;
797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //serialPatternMatch
798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::ifPatternMatch(BlockT *curBlk) {
801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //two edges
802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (curBlk->succ_size() != 2) {
803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (hasBackEdge(curBlk)) {
807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrT *branchInstr = CFGTraits::getNormalBlockBranchInstr(curBlk);
811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (branchInstr == NULL) {
812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(CFGTraits::isCondBranch(branchInstr));
816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *trueBlk = CFGTraits::getTrueBranch(branchInstr);
818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *falseBlk = CFGTraits::getFalseBranch(curBlk, branchInstr);
819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *landBlk;
820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int cloned = 0;
821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // TODO: Simplify
823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (trueBlk->succ_size() == 1 && falseBlk->succ_size() == 1
824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    && *trueBlk->succ_begin() == *falseBlk->succ_begin()) {
825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    landBlk = *trueBlk->succ_begin();
826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (trueBlk->succ_size() == 0 && falseBlk->succ_size() == 0) {
827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    landBlk = NULL;
828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (trueBlk->succ_size() == 1 && *trueBlk->succ_begin() == falseBlk) {
829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    landBlk = falseBlk;
830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    falseBlk = NULL;
831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (falseBlk->succ_size() == 1
832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             && *falseBlk->succ_begin() == trueBlk) {
833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    landBlk = trueBlk;
834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    trueBlk = NULL;
835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (falseBlk->succ_size() == 1
836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             && isSameloopDetachedContbreak(trueBlk, falseBlk)) {
837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    landBlk = *falseBlk->succ_begin();
838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else if (trueBlk->succ_size() == 1
839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    && isSameloopDetachedContbreak(falseBlk, trueBlk)) {
840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    landBlk = *trueBlk->succ_begin();
841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else {
842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return handleJumpintoIf(curBlk, trueBlk, falseBlk);
843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // improveSimpleJumpinfoIf can handle the case where landBlk == NULL but the
846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // new BB created for landBlk==NULL may introduce new challenge to the
847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // reduction process.
848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (landBlk != NULL &&
849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ((trueBlk && trueBlk->pred_size() > 1)
850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      || (falseBlk && falseBlk->pred_size() > 1))) {
851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     cloned += improveSimpleJumpintoIf(curBlk, trueBlk, falseBlk, &landBlk);
852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (trueBlk && trueBlk->pred_size() > 1) {
855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    trueBlk = cloneBlockForPredecessor(trueBlk, curBlk);
856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++cloned;
857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (falseBlk && falseBlk->pred_size() > 1) {
860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    falseBlk = cloneBlockForPredecessor(falseBlk, curBlk);
861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++cloned;
862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  mergeIfthenelseBlock(branchInstr, curBlk, trueBlk, falseBlk, landBlk);
865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ++numIfPatternMatch;
867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numClonedBlock += cloned;
869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return 1 + cloned;
871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //ifPatternMatch
872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::switchPatternMatch(BlockT *curBlk) {
875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return 0;
876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //switchPatternMatch
877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopendPatternMatch(BlockT *curBlk) {
880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopT *loopRep = loopInfo->getLoopFor(curBlk);
881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typename std::vector<LoopT *> nestedLoops;
882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (loopRep) {
883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    nestedLoops.push_back(loopRep);
884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    loopRep = loopRep->getParentLoop();
885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (nestedLoops.size() == 0) {
888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Process nested loop outside->inside, so "continue" to a outside loop won't
892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // be mistaken as "break" of the current loop.
893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int num = 0;
894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename std::vector<LoopT *>::reverse_iterator
895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter = nestedLoops.rbegin(), iterEnd = nestedLoops.rend();
896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter != iterEnd; ++iter) {
897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    loopRep = *iter;
898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (getLoopLandBlock(loopRep) != NULL) {
900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      continue;
901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *loopHeader = loopRep->getHeader();
904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int numBreak = loopbreakPatternMatch(loopRep, loopHeader);
906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (numBreak == -1) {
908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int numCont = loopcontPatternMatch(loopRep, loopHeader);
912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    num += numBreak + numCont;
913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return num;
916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopendPatternMatch
917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopPatternMatch(BlockT *curBlk) {
920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (curBlk->succ_size() != 0) {
921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numLoop = 0;
925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopT *loopRep = loopInfo->getLoopFor(curBlk);
926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (loopRep && loopRep->getHeader() == curBlk) {
927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LoopLandInfo *loopLand = getLoopLandInfo(loopRep);
928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (loopLand) {
929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *landBlk = loopLand->landBlk;
930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(landBlk);
931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!isRetiredBlock(landBlk)) {
932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        mergeLooplandBlock(curBlk, loopLand);
933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++numLoop;
934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    loopRep = loopRep->getParentLoop();
937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numLoopPatternMatch += numLoop;
940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return numLoop;
942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopPatternMatch
943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopbreakPatternMatch(LoopT *loopRep,
946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  BlockT *loopHeader) {
947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockTSmallerVector exitingBlks;
948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  loopRep->getExitingBlocks(exitingBlks);
949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Loop has " << exitingBlks.size() << " exiting blocks\n";
952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (exitingBlks.size() == 0) {
955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    setLoopLandBlock(loopRep);
956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Compute the corresponding exitBlks and exit block set.
960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockTSmallerVector exitBlks;
961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::set<BlockT *> exitBlkSet;
962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename BlockTSmallerVector::const_iterator iter = exitingBlks.begin(),
963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = exitingBlks.end(); iter != iterEnd; ++iter) {
964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *exitingBlk = *iter;
965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *exitBlk = exitingBlock2ExitBlock(loopRep, exitingBlk);
966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    exitBlks.push_back(exitBlk);
967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    exitBlkSet.insert(exitBlk);  //non-duplicate insert
968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(exitBlkSet.size() > 0);
971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(exitBlks.size() == exitingBlks.size());
972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Loop has " << exitBlkSet.size() << " exit blocks\n";
975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Find exitLandBlk.
978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *exitLandBlk = NULL;
979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numCloned = 0;
980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numSerial = 0;
981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (exitBlkSet.size() == 1)
983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    exitLandBlk = *exitBlkSet.begin();
985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else {
986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    exitLandBlk = findNearestCommonPostDom(exitBlkSet);
987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (exitLandBlk == NULL) {
989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -1;
990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bool allInPath = true;
993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bool allNotInPath = true;
994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (typename std::set<BlockT*>::const_iterator
995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iter = exitBlkSet.begin(),
996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterEnd = exitBlkSet.end();
997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iter != iterEnd; ++iter) {
998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *exitBlk = *iter;
999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PathToKind pathKind = singlePathTo(exitBlk, exitLandBlk, true);
1001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
1002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "BB" << exitBlk->getNumber()
1003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               << " to BB" << exitLandBlk->getNumber() << " PathToKind="
1004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               << pathKind << "\n";
1005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      allInPath = allInPath && (pathKind == SinglePath_InPath);
1008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      allNotInPath = allNotInPath && (pathKind == SinglePath_NotInPath);
1009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!allInPath && !allNotInPath) {
1011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (DEBUGME) {
1012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org              errs() << "singlePath check fail\n";
1013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return -1;
1015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } // check all exit blocks
1017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (allNotInPath) {
1019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 1
1020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // TODO: Simplify, maybe separate function?
1022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //funcRep->viewCFG();
1023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LoopT *parentLoopRep = loopRep->getParentLoop();
1024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *parentLoopHeader = NULL;
1025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (parentLoopRep)
1026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        parentLoopHeader = parentLoopRep->getHeader();
1027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (exitLandBlk == parentLoopHeader &&
1029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          (exitLandBlk = relocateLoopcontBlock(parentLoopRep,
1030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               loopRep,
1031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               exitBlkSet,
1032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               exitLandBlk)) != NULL) {
1033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (DEBUGME) {
1034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          errs() << "relocateLoopcontBlock success\n";
1035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else if ((exitLandBlk = addLoopEndbranchBlock(loopRep,
1037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                      exitingBlks,
1038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                      exitBlks)) != NULL) {
1039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (DEBUGME) {
1040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          errs() << "insertEndbranchBlock success\n";
1041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (DEBUGME) {
1044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          errs() << "loop exit fail\n";
1045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return -1;
1047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else
1049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return -1;
1050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Handle side entry to exit path.
1054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    exitBlks.clear();
1055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    exitBlkSet.clear();
1056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (typename BlockTSmallerVector::iterator iterExiting =
1057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           exitingBlks.begin(),
1058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterExitingEnd = exitingBlks.end();
1059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterExiting != iterExitingEnd; ++iterExiting) {
1060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *exitingBlk = *iterExiting;
1061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *exitBlk = exitingBlock2ExitBlock(loopRep, exitingBlk);
1062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *newExitBlk = exitBlk;
1063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (exitBlk != exitLandBlk && exitBlk->pred_size() > 1) {
1065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        newExitBlk = cloneBlockForPredecessor(exitBlk, exitingBlk);
1066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ++numCloned;
1067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      numCloned += cloneOnSideEntryTo(exitingBlk, newExitBlk, exitLandBlk);
1070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exitBlks.push_back(newExitBlk);
1072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exitBlkSet.insert(newExitBlk);
1073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (typename BlockTSmallerVector::iterator iterExit = exitBlks.begin(),
1076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterExitEnd = exitBlks.end();
1077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterExit != iterExitEnd; ++iterExit) {
1078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *exitBlk = *iterExit;
1079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      numSerial += serialPatternMatch(exitBlk);
1080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (typename BlockTSmallerVector::iterator iterExit = exitBlks.begin(),
1083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterExitEnd = exitBlks.end();
1084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterExit != iterExitEnd; ++iterExit) {
1085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *exitBlk = *iterExit;
1086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (exitBlk->pred_size() > 1) {
1087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (exitBlk != exitLandBlk) {
1088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          return -1;
1089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (exitBlk != exitLandBlk &&
1092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            (exitBlk->succ_size() != 1 ||
1093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *exitBlk->succ_begin() != exitLandBlk)) {
1094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          return -1;
1095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } // else
1099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // LoopT *exitLandLoop = loopInfo->getLoopFor(exitLandBlk);
1101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  exitLandBlk = recordLoopLandBlock(loopRep, exitLandBlk, exitBlks, exitBlkSet);
1102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Fold break into the breaking block. Leverage across level breaks.
1104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(exitingBlks.size() == exitBlks.size());
1105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename BlockTSmallerVector::const_iterator iterExit = exitBlks.begin(),
1106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterExiting = exitingBlks.begin(), iterExitEnd = exitBlks.end();
1107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterExit != iterExitEnd; ++iterExit, ++iterExiting) {
1108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *exitBlk = *iterExit;
1109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *exitingBlk = *iterExiting;
1110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(exitBlk->pred_size() == 1 || exitBlk == exitLandBlk);
1111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LoopT *exitingLoop = loopInfo->getLoopFor(exitingBlk);
1112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    handleLoopbreak(exitingBlk, exitingLoop, exitBlk, loopRep, exitLandBlk);
1113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numBreak = static_cast<int>(exitingBlks.size());
1116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numLoopbreakPatternMatch += numBreak;
1117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numClonedBlock += numCloned;
1118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return numBreak + numSerial + numCloned;
1119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopbreakPatternMatch
1120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::loopcontPatternMatch(LoopT *loopRep,
1123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 BlockT *loopHeader) {
1124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numCont = 0;
1125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<BlockT *, DEFAULT_VEC_SLOTS> contBlk;
1126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename InvBlockGTraits::ChildIteratorType iter =
1127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       InvBlockGTraits::child_begin(loopHeader),
1128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = InvBlockGTraits::child_end(loopHeader);
1129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter != iterEnd; ++iter) {
1130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curBlk = *iter;
1131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (loopRep->contains(curBlk)) {
1132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      handleLoopcontBlock(curBlk, loopInfo->getLoopFor(curBlk),
1133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          loopHeader, loopRep);
1134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      contBlk.push_back(curBlk);
1135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ++numCont;
1136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::iterator
1140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter = contBlk.begin(), iterEnd = contBlk.end();
1141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter != iterEnd; ++iter) {
1142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    (*iter)->removeSuccessor(loopHeader);
1143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numLoopcontPatternMatch += numCont;
1146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return numCont;
1148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //loopcontPatternMatch
1149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::isSameloopDetachedContbreak(BlockT *src1Blk,
1153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         BlockT *src2Blk) {
1154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // return true iff src1Blk->succ_size() == 0 && src1Blk and src2Blk are in the
1155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // same loop with LoopLandInfo without explicitly keeping track of
1156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // loopContBlks and loopBreakBlks, this is a method to get the information.
1157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //
1158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (src1Blk->succ_size() == 0) {
1159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LoopT *loopRep = loopInfo->getLoopFor(src1Blk);
1160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (loopRep != NULL && loopRep == loopInfo->getLoopFor(src2Blk)) {
1161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
1162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (theEntry != NULL) {
1163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (DEBUGME) {
1164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          errs() << "isLoopContBreakBlock yes src1 = BB"
1165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 << src1Blk->getNumber()
1166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 << " src2 = BB" << src2Blk->getNumber() << "\n";
1167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
1168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return true;
1169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return false;
1173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}  //isSameloopDetachedContbreak
1174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::handleJumpintoIf(BlockT *headBlk,
1177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             BlockT *trueBlk,
1178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             BlockT *falseBlk) {
1179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int num = handleJumpintoIfImp(headBlk, trueBlk, falseBlk);
1180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (num == 0) {
1181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
1182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "handleJumpintoIf swap trueBlk and FalseBlk" << "\n";
1183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    num = handleJumpintoIfImp(headBlk, falseBlk, trueBlk);
1185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return num;
1187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::handleJumpintoIfImp(BlockT *headBlk,
1191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                BlockT *trueBlk,
1192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                BlockT *falseBlk) {
1193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int num = 0;
1194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *downBlk;
1195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //trueBlk could be the common post dominator
1197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  downBlk = trueBlk;
1198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "handleJumpintoIfImp head = BB" << headBlk->getNumber()
1201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " true = BB" << trueBlk->getNumber()
1202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << ", numSucc=" << trueBlk->succ_size()
1203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " false = BB" << falseBlk->getNumber() << "\n";
1204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (downBlk) {
1207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
1208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "check down = BB" << downBlk->getNumber();
1209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (//postDomTree->dominates(downBlk, falseBlk) &&
1212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        singlePathTo(falseBlk, downBlk) == SinglePath_InPath) {
1213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
1214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << " working\n";
1215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num += cloneOnSideEntryTo(headBlk, trueBlk, downBlk);
1218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num += cloneOnSideEntryTo(headBlk, falseBlk, downBlk);
1219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      numClonedBlock += num;
1221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num += serialPatternMatch(*headBlk->succ_begin());
1222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num += serialPatternMatch(*(++headBlk->succ_begin()));
1223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      num += ifPatternMatch(headBlk);
1224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(num > 0); //
1225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
1227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
1229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << " not working\n";
1230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    downBlk = (downBlk->succ_size() == 1) ? (*downBlk->succ_begin()) : NULL;
1232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } // walk down the postDomTree
1233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return num;
1235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //handleJumpintoIf
1236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::showImproveSimpleJumpintoIf(BlockT *headBlk,
1239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         BlockT *trueBlk,
1240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         BlockT *falseBlk,
1241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         BlockT *landBlk,
1242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                         bool detail) {
1243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  errs() << "head = BB" << headBlk->getNumber()
1244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         << " size = " << headBlk->size();
1245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (detail) {
1246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "\n";
1247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    headBlk->print(errs());
1248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "\n";
1249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (trueBlk) {
1252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << ", true = BB" << trueBlk->getNumber() << " size = "
1253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << trueBlk->size() << " numPred = " << trueBlk->pred_size();
1254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (detail) {
1255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "\n";
1256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      trueBlk->print(errs());
1257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "\n";
1258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (falseBlk) {
1261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << ", false = BB" << falseBlk->getNumber() << " size = "
1262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << falseBlk->size() << " numPred = " << falseBlk->pred_size();
1263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (detail) {
1264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "\n";
1265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      falseBlk->print(errs());
1266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "\n";
1267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (landBlk) {
1270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << ", land = BB" << landBlk->getNumber() << " size = "
1271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << landBlk->size() << " numPred = " << landBlk->pred_size();
1272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (detail) {
1273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "\n";
1274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      landBlk->print(errs());
1275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "\n";
1276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "\n";
1280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //showImproveSimpleJumpintoIf
1281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::improveSimpleJumpintoIf(BlockT *headBlk,
1284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    BlockT *trueBlk,
1285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    BlockT *falseBlk,
1286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                    BlockT **plandBlk) {
1287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool migrateTrue = false;
1288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool migrateFalse = false;
1289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *landBlk = *plandBlk;
1291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert((trueBlk == NULL || trueBlk->succ_size() <= 1)
1293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         && (falseBlk == NULL || falseBlk->succ_size() <= 1));
1294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (trueBlk == falseBlk) {
1296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
1297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
1300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "improveSimpleJumpintoIf: ";
1302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 0);
1303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
1305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // unsigned landPredSize = landBlk ? landBlk->pred_size() : 0;
1307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // May consider the # landBlk->pred_size() as it represents the number of
1308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // assignment initReg = .. needed to insert.
1309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  migrateTrue = needMigrateBlock(trueBlk);
1310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  migrateFalse = needMigrateBlock(falseBlk);
1311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!migrateTrue && !migrateFalse) {
1313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return 0;
1314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // If we need to migrate either trueBlk and falseBlk, migrate the rest that
1317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // have more than one predecessors.  without doing this, its predecessor
1318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // rather than headBlk will have undefined value in initReg.
1319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!migrateTrue && trueBlk && trueBlk->pred_size() > 1) {
1320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    migrateTrue = true;
1321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!migrateFalse && falseBlk && falseBlk->pred_size() > 1) {
1323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    migrateFalse = true;
1324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "before improveSimpleJumpintoIf: ";
1328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 0);
1329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 1);
1330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // org: headBlk => if () {trueBlk} else {falseBlk} => landBlk
1333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //
1334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // new: headBlk => if () {initReg = 1; org trueBlk branch} else
1335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //      {initReg = 0; org falseBlk branch }
1336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //      => landBlk => if (initReg) {org trueBlk} else {org falseBlk}
1337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //      => org landBlk
1338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //      if landBlk->pred_size() > 2, put the about if-else inside
1339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //      if (initReg !=2) {...}
1340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //
1341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // add initReg = initVal to headBlk
1342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
1344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned initReg =
1345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    funcRep->getRegInfo().createVirtualRegister(I32RC);
1346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (!migrateTrue || !migrateFalse) {
1347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int initVal = migrateTrue ? 0 : 1;
1348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(headBlk, passRep, initReg, initVal);
1349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int numNewBlk = 0;
1352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (landBlk == NULL) {
1354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    landBlk = funcRep->CreateMachineBasicBlock();
1355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    funcRep->push_back(landBlk);  //insert to function
1356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (trueBlk) {
1358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      trueBlk->addSuccessor(landBlk);
1359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      headBlk->addSuccessor(landBlk);
1361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (falseBlk) {
1364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      falseBlk->addSuccessor(landBlk);
1365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      headBlk->addSuccessor(landBlk);
1367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    numNewBlk ++;
1370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool landBlkHasOtherPred = (landBlk->pred_size() > 2);
1373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //insert AMDGPU::ENDIF to avoid special case "input landBlk == NULL"
1375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typename BlockT::iterator insertPos =
1376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::getInstrPos
1377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    (landBlk, CFGTraits::insertInstrBefore(landBlk, AMDGPU::ENDIF, passRep));
1378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (landBlkHasOtherPred) {
1380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned immReg =
1381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      funcRep->getRegInfo().createVirtualRegister(I32RC);
1382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 2);
1383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned cmpResReg =
1384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      funcRep->getRegInfo().createVirtualRegister(I32RC);
1385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertCompareInstrBefore(landBlk, insertPos, passRep, cmpResReg,
1387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        initReg, immReg);
1388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertCondBranchBefore(landBlk, insertPos,
1389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      AMDGPU::IF_LOGICALZ_i32, passRep,
1390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      cmpResReg, DebugLoc());
1391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertCondBranchBefore(landBlk, insertPos, AMDGPU::IF_LOGICALNZ_i32,
1394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    passRep, initReg, DebugLoc());
1395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (migrateTrue) {
1397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    migrateInstruction(trueBlk, landBlk, insertPos);
1398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // need to uncondionally insert the assignment to ensure a path from its
1399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // predecessor rather than headBlk has valid value in initReg if
1400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // (initVal != 1).
1401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(trueBlk, passRep, initReg, 1);
1402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertInstrBefore(insertPos, AMDGPU::ELSE, passRep);
1404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (migrateFalse) {
1406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    migrateInstruction(falseBlk, landBlk, insertPos);
1407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // need to uncondionally insert the assignment to ensure a path from its
1408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // predecessor rather than headBlk has valid value in initReg if
1409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // (initVal != 0)
1410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(falseBlk, passRep, initReg, 0);
1411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //CFGTraits::insertInstrBefore(insertPos, AMDGPU::ENDIF, passRep);
1413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (landBlkHasOtherPred) {
1415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // add endif
1416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertInstrBefore(insertPos, AMDGPU::ENDIF, passRep);
1417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // put initReg = 2 to other predecessors of landBlk
1419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (typename BlockT::pred_iterator predIter = landBlk->pred_begin(),
1420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         predIterEnd = landBlk->pred_end(); predIter != predIterEnd;
1421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         ++predIter) {
1422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *curBlk = *predIter;
1423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (curBlk != trueBlk && curBlk != falseBlk) {
1424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        CFGTraits::insertAssignInstrBefore(curBlk, passRep, initReg, 2);
1425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } //for
1427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "result from improveSimpleJumpintoIf: ";
1430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 0);
1431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //showImproveSimpleJumpintoIf(headBlk, trueBlk, falseBlk, landBlk, 1);
1432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // update landBlk
1435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  *plandBlk = landBlk;
1436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return numNewBlk;
1438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //improveSimpleJumpintoIf
1439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::handleLoopbreak(BlockT *exitingBlk,
1442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              LoopT *exitingLoop,
1443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             BlockT *exitBlk,
1444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              LoopT *exitLoop,
1445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                             BlockT *landBlk) {
1446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Trying to break loop-depth = " << getLoopDepth(exitLoop)
1448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " from loop-depth = " << getLoopDepth(exitingLoop) << "\n";
1449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
1451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RegiT initReg = INVALIDREGNUM;
1453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (exitingLoop != exitLoop) {
1454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    initReg = static_cast<int>
1455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (funcRep->getRegInfo().createVirtualRegister(I32RC));
1456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(initReg != INVALIDREGNUM);
1457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    addLoopBreakInitReg(exitLoop, initReg);
1458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    while (exitingLoop != exitLoop && exitingLoop) {
1459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      addLoopBreakOnReg(exitingLoop, initReg);
1460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exitingLoop = exitingLoop->getParentLoop();
1461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(exitingLoop == exitLoop);
1463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  mergeLoopbreakBlock(exitingBlk, exitBlk, landBlk, initReg);
1466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //handleLoopbreak
1468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::handleLoopcontBlock(BlockT *contingBlk,
1471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  LoopT *contingLoop,
1472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 BlockT *contBlk,
1473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  LoopT *contLoop) {
1474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "loopcontPattern cont = BB" << contingBlk->getNumber()
1476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " header = BB" << contBlk->getNumber() << "\n";
1477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Trying to continue loop-depth = "
1479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << getLoopDepth(contLoop)
1480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " from loop-depth = " << getLoopDepth(contingLoop) << "\n";
1481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RegiT initReg = INVALIDREGNUM;
1484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
1485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (contingLoop != contLoop) {
1486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    initReg = static_cast<int>
1487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (funcRep->getRegInfo().createVirtualRegister(I32RC));
1488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(initReg != INVALIDREGNUM);
1489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    addLoopContInitReg(contLoop, initReg);
1490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    while (contingLoop && contingLoop->getParentLoop() != contLoop) {
1491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      addLoopBreakOnReg(contingLoop, initReg);  //not addLoopContOnReg
1492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      contingLoop = contingLoop->getParentLoop();
1493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(contingLoop && contingLoop->getParentLoop() == contLoop);
1495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    addLoopContOnReg(contingLoop, initReg);
1496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  settleLoopcontBlock(contingBlk, contBlk, initReg);
1499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //contingBlk->removeSuccessor(loopHeader);
1500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //handleLoopcontBlock
1501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeSerialBlock(BlockT *dstBlk, BlockT *srcBlk) {
1504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "serialPattern BB" << dstBlk->getNumber()
1506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " <= BB" << srcBlk->getNumber() << "\n";
1507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //removeUnconditionalBranch(dstBlk);
1509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  dstBlk->splice(dstBlk->end(), srcBlk, FirstNonDebugInstr(srcBlk), srcBlk->end());
1510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  dstBlk->removeSuccessor(srcBlk);
1512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::cloneSuccessorList(dstBlk, srcBlk);
1513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  removeSuccessor(srcBlk);
1515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  retireBlock(dstBlk, srcBlk);
1516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeSerialBlock
1517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeIfthenelseBlock(InstrT *branchInstr,
1520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  BlockT *curBlk,
1521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  BlockT *trueBlk,
1522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  BlockT *falseBlk,
1523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  BlockT *landBlk) {
1524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "ifPattern BB" << curBlk->getNumber();
1526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "{  ";
1527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (trueBlk) {
1528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "BB" << trueBlk->getNumber();
1529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "  } else ";
1531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "{  ";
1532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (falseBlk) {
1533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "BB" << falseBlk->getNumber();
1534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "  }\n ";
1536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "landBlock: ";
1537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (landBlk == NULL) {
1538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "NULL";
1539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "BB" << landBlk->getNumber();
1541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "\n";
1543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int oldOpcode = branchInstr->getOpcode();
1546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc branchDL = branchInstr->getDebugLoc();
1547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    transform to
1549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    if cond
1550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//       trueBlk
1551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    else
1552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//       falseBlk
1553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    endif
1554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    landBlk
1555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typename BlockT::iterator branchInstrPos =
1557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::getInstrPos(curBlk, branchInstr);
1558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertCondBranchBefore(branchInstrPos,
1559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    CFGTraits::getBranchNzeroOpcode(oldOpcode),
1560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    passRep,
1561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									branchDL);
1562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (trueBlk) {
1564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curBlk->splice(branchInstrPos, trueBlk, FirstNonDebugInstr(trueBlk), trueBlk->end());
1565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curBlk->removeSuccessor(trueBlk);
1566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (landBlk && trueBlk->succ_size()!=0) {
1567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      trueBlk->removeSuccessor(landBlk);
1568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    retireBlock(curBlk, trueBlk);
1570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::ELSE, passRep);
1572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (falseBlk) {
1574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curBlk->splice(branchInstrPos, falseBlk, FirstNonDebugInstr(falseBlk),
1575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                   falseBlk->end());
1576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curBlk->removeSuccessor(falseBlk);
1577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (landBlk && falseBlk->succ_size() != 0) {
1578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      falseBlk->removeSuccessor(landBlk);
1579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    retireBlock(curBlk, falseBlk);
1581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::ENDIF, passRep);
1583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //curBlk->remove(branchInstrPos);
1585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  branchInstr->eraseFromParent();
1586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (landBlk && trueBlk && falseBlk) {
1588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curBlk->addSuccessor(landBlk);
1589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeIfthenelseBlock
1592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeLooplandBlock(BlockT *dstBlk,
1595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                LoopLandInfo *loopLand) {
1596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *landBlk = loopLand->landBlk;
1597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "loopPattern header = BB" << dstBlk->getNumber()
1600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " land = BB" << landBlk->getNumber() << "\n";
1601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Loop contInitRegs are init at the beginning of the loop.
1604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename std::set<RegiT>::const_iterator iter =
1605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         loopLand->contInitRegs.begin(),
1606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = loopLand->contInitRegs.end(); iter != iterEnd; ++iter) {
1607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(dstBlk, passRep, *iter, 0);
1608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  /* we last inserterd the DebugLoc in the
1611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   * BREAK_LOGICALZ_i32 or AMDGPU::BREAK_LOGICALNZ statement in the current dstBlk.
1612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   * search for the DebugLoc in the that statement.
1613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   * if not found, we have to insert the empty/default DebugLoc */
1614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrT *loopBreakInstr = CFGTraits::getLoopBreakInstr(dstBlk);
1615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc DLBreak = (loopBreakInstr) ? loopBreakInstr->getDebugLoc() : DebugLoc();
1616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertInstrBefore(dstBlk, AMDGPU::WHILELOOP, passRep, DLBreak);
1618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Loop breakInitRegs are init before entering the loop.
1619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename std::set<RegiT>::const_iterator iter =
1620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         loopLand->breakInitRegs.begin(),
1621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = loopLand->breakInitRegs.end(); iter != iterEnd; ++iter)
1622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
1623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(dstBlk, passRep, *iter, 0);
1624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Loop endbranchInitRegs are init before entering the loop.
1626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename std::set<RegiT>::const_iterator iter =
1627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         loopLand->endbranchInitRegs.begin(),
1628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = loopLand->endbranchInitRegs.end(); iter != iterEnd; ++iter) {
1629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(dstBlk, passRep, *iter, 0);
1630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  /* we last inserterd the DebugLoc in the continue statement in the current dstBlk
1633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   * search for the DebugLoc in the continue statement.
1634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   * if not found, we have to insert the empty/default DebugLoc */
1635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrT *continueInstr = CFGTraits::getContinueInstr(dstBlk);
1636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc DLContinue = (continueInstr) ? continueInstr->getDebugLoc() : DebugLoc();
1637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertInstrEnd(dstBlk, AMDGPU::ENDLOOP, passRep, DLContinue);
1639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Loop breakOnRegs are check after the ENDLOOP: break the loop outside this
1640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // loop.
1641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename std::set<RegiT>::const_iterator iter =
1642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         loopLand->breakOnRegs.begin(),
1643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = loopLand->breakOnRegs.end(); iter != iterEnd; ++iter) {
1644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertCondBranchEnd(dstBlk, AMDGPU::BREAK_LOGICALNZ_i32, passRep,
1645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   *iter);
1646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Loop contOnRegs are check after the ENDLOOP: cont the loop outside this
1649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // loop.
1650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (std::set<RegiT>::const_iterator iter = loopLand->contOnRegs.begin(),
1651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = loopLand->contOnRegs.end(); iter != iterEnd; ++iter) {
1652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertCondBranchEnd(dstBlk, AMDGPU::CONTINUE_LOGICALNZ_i32,
1653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                   passRep, *iter);
1654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  dstBlk->splice(dstBlk->end(), landBlk, landBlk->begin(), landBlk->end());
1657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename BlockT::succ_iterator iter = landBlk->succ_begin(),
1659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = landBlk->succ_end(); iter != iterEnd; ++iter) {
1660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    dstBlk->addSuccessor(*iter);  // *iter's predecessor is also taken care of.
1661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  removeSuccessor(landBlk);
1664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  retireBlock(dstBlk, landBlk);
1665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeLooplandBlock
1666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::reversePredicateSetter(typename BlockT::iterator I)
1669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
1670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (I--) {
1671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (I->getOpcode() == AMDGPU::PRED_X) {
1672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      switch (static_cast<MachineInstr *>(I)->getOperand(2).getImm()) {
1673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_IS_ZERO_INT:
1674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_NOT_ZERO_INT);
1675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return;
1676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_IS_NOT_ZERO_INT:
1677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_ZERO_INT);
1678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return;
1679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_IS_ZERO:
1680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_NOT_ZERO);
1681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return;
1682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case OPCODE_IS_NOT_ZERO:
1683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        static_cast<MachineInstr *>(I)->getOperand(2).setImm(OPCODE_IS_ZERO);
1684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return;
1685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
1686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert(0 && "PRED_X Opcode invalid!");
1687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
1691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::mergeLoopbreakBlock(BlockT *exitingBlk,
1694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 BlockT *exitBlk,
1695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 BlockT *exitLandBlk,
1696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 RegiT  setReg) {
1697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "loopbreakPattern exiting = BB" << exitingBlk->getNumber()
1699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " exit = BB" << exitBlk->getNumber()
1700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << " land = BB" << exitLandBlk->getNumber() << "\n";
1701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(exitingBlk);
1704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(branchInstr && CFGTraits::isCondBranch(branchInstr));
1705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc DL = branchInstr->getDebugLoc();
1707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *trueBranch = CFGTraits::getTrueBranch(branchInstr);
1709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int oldOpcode = branchInstr->getOpcode();
1710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //    transform exitingBlk to
1712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //    if ( ) {
1713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //       exitBlk (if exitBlk != exitLandBlk)
1714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //       setReg = 1
1715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //       break
1716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //    }endif
1717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //    successor = {orgSuccessor(exitingBlk) - exitBlk}
1718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typename BlockT::iterator branchInstrPos =
1720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::getInstrPos(exitingBlk, branchInstr);
1721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (exitBlk == exitLandBlk && setReg == INVALIDREGNUM) {
1723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //break_logical
1724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (trueBranch != exitBlk) {
1726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reversePredicateSetter(branchInstrPos);
1727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int newOpcode = CFGTraits::getBreakZeroOpcode(oldOpcode);
1729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertCondBranchBefore(branchInstrPos, newOpcode, passRep, DL);
1730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else {
1731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (trueBranch != exitBlk) {
1732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      reversePredicateSetter(branchInstr);
1733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int newOpcode = CFGTraits::getBreakZeroOpcode(oldOpcode);
1735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertCondBranchBefore(branchInstrPos, newOpcode, passRep, DL);
1736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (exitBlk != exitLandBlk) {
1737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //splice is insert-before ...
1738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exitingBlk->splice(branchInstrPos, exitBlk, exitBlk->begin(),
1739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         exitBlk->end());
1740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (setReg != INVALIDREGNUM) {
1742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertAssignInstrBefore(branchInstrPos, passRep, setReg, 1);
1743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::BREAK, passRep);
1745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertInstrBefore(branchInstrPos, AMDGPU::ENDIF, passRep);
1746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //if_logical
1747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //now branchInst can be erase safely
1749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //exitingBlk->eraseFromParent(branchInstr);
1750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  branchInstr->eraseFromParent();
1751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //now take care of successors, retire blocks
1753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  exitingBlk->removeSuccessor(exitBlk);
1754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (exitBlk != exitLandBlk) {
1755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //splice is insert-before ...
1756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    exitBlk->removeSuccessor(exitLandBlk);
1757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    retireBlock(exitingBlk, exitBlk);
1758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //mergeLoopbreakBlock
1761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::settleLoopcontBlock(BlockT *contingBlk,
1764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 BlockT *contBlk,
1765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 RegiT   setReg) {
1766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
1767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "settleLoopcontBlock conting = BB"
1768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << contingBlk->getNumber()
1769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << ", cont = BB" << contBlk->getNumber() << "\n";
1770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(contingBlk);
1773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (branchInstr) {
1774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(CFGTraits::isCondBranch(branchInstr));
1775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typename BlockT::iterator branchInstrPos =
1776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::getInstrPos(contingBlk, branchInstr);
1777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *trueBranch = CFGTraits::getTrueBranch(branchInstr);
1778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int oldOpcode = branchInstr->getOpcode();
1779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	DebugLoc DL = branchInstr->getDebugLoc();
1780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //    transform contingBlk to
1782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //     if () {
1783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //          move instr after branchInstr
1784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //          continue
1785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //        or
1786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //          setReg = 1
1787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //          break
1788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //     }endif
1789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //     successor = {orgSuccessor(contingBlk) - loopHeader}
1790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bool useContinueLogical =
1792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (setReg == INVALIDREGNUM && (&*contingBlk->rbegin()) == branchInstr);
1793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (useContinueLogical == false)
1795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    {
1796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int branchOpcode =
1797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        trueBranch == contBlk ? CFGTraits::getBranchNzeroOpcode(oldOpcode)
1798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              : CFGTraits::getBranchZeroOpcode(oldOpcode);
1799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertCondBranchBefore(branchInstrPos, branchOpcode, passRep, DL);
1801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (setReg != INVALIDREGNUM) {
1803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        CFGTraits::insertAssignInstrBefore(branchInstrPos, passRep, setReg, 1);
1804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // insertEnd to ensure phi-moves, if exist, go before the continue-instr.
1805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        CFGTraits::insertInstrEnd(contingBlk, AMDGPU::BREAK, passRep, DL);
1806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
1807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        // insertEnd to ensure phi-moves, if exist, go before the continue-instr.
1808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        CFGTraits::insertInstrEnd(contingBlk, AMDGPU::CONTINUE, passRep, DL);
1809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertInstrEnd(contingBlk, AMDGPU::ENDIF, passRep, DL);
1812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int branchOpcode =
1814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        trueBranch == contBlk ? CFGTraits::getContinueNzeroOpcode(oldOpcode)
1815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              : CFGTraits::getContinueZeroOpcode(oldOpcode);
1816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertCondBranchBefore(branchInstrPos, branchOpcode, passRep, DL);
1818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //contingBlk->eraseFromParent(branchInstr);
1821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    branchInstr->eraseFromParent();
1822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else {
1823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* if we've arrived here then we've already erased the branch instruction
1824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * travel back up the basic block to see the last reference of our debug location
1825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	 * we've just inserted that reference here so it should be representative */
1826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (setReg != INVALIDREGNUM) {
1827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertAssignInstrBefore(contingBlk, passRep, setReg, 1);
1828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // insertEnd to ensure phi-moves, if exist, go before the continue-instr.
1829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertInstrEnd(contingBlk, AMDGPU::BREAK, passRep, CFGTraits::getLastDebugLocInBB(contingBlk));
1830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // insertEnd to ensure phi-moves, if exist, go before the continue-instr.
1832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertInstrEnd(contingBlk, AMDGPU::CONTINUE, passRep, CFGTraits::getLastDebugLocInBB(contingBlk));
1833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //else
1835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //settleLoopcontBlock
1837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// BBs in exitBlkSet are determined as in break-path for loopRep,
1839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// before we can put code for BBs as inside loop-body for loopRep
1840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// check whether those BBs are determined as cont-BB for parentLoopRep
1841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// earlier.
1842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// If so, generate a new BB newBlk
1843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    (1) set newBlk common successor of BBs in exitBlkSet
1844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    (2) change the continue-instr in BBs in exitBlkSet to break-instr
1845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//    (3) generate continue-instr in newBlk
1846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
1847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
1849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::relocateLoopcontBlock(LoopT *parentLoopRep,
1850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              LoopT *loopRep,
1851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              std::set<BlockT *> &exitBlkSet,
1852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              BlockT *exitLandBlk) {
1853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  std::set<BlockT *> endBlkSet;
1854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//  BlockT *parentLoopHead = parentLoopRep->getHeader();
1856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename std::set<BlockT *>::const_iterator iter = exitBlkSet.begin(),
1859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = exitBlkSet.end();
1860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter != iterEnd; ++iter) {
1861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *exitBlk = *iter;
1862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *endBlk = singlePathEnd(exitBlk, exitLandBlk);
1863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (endBlk == NULL || CFGTraits::getContinueInstr(endBlk) == NULL)
1865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
1866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    endBlkSet.insert(endBlk);
1868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *newBlk = funcRep->CreateMachineBasicBlock();
1871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  funcRep->push_back(newBlk);  //insert to function
1872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertInstrEnd(newBlk, AMDGPU::CONTINUE, passRep);
1873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SHOWNEWBLK(newBlk, "New continue block: ");
1874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename std::set<BlockT*>::const_iterator iter = endBlkSet.begin(),
1876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = endBlkSet.end();
1877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iter != iterEnd; ++iter) {
1878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *endBlk = *iter;
1879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      InstrT *contInstr = CFGTraits::getContinueInstr(endBlk);
1880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (contInstr) {
1881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        contInstr->eraseFromParent();
1882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      endBlk->addSuccessor(newBlk);
1884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
1885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "Add new continue Block to BB"
1886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               << endBlk->getNumber() << " successors\n";
1887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
1888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
1889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return newBlk;
1891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //relocateLoopcontBlock
1892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// LoopEndbranchBlock is a BB created by the CFGStructurizer to use as
1895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// LoopLandBlock. This BB branch on the loop endBranchInit register to the
1896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// pathes corresponding to the loop exiting branches.
1897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
1900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::addLoopEndbranchBlock(LoopT *loopRep,
1901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              BlockTSmallerVector &exitingBlks,
1902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                              BlockTSmallerVector &exitBlks) {
1903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const AMDGPUInstrInfo *tii =
1904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo());
1905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
1906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RegiT endBranchReg = static_cast<int>
1908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    (funcRep->getRegInfo().createVirtualRegister(I32RC));
1909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(endBranchReg >= 0);
1910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // reg = 0 before entering the loop
1912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  addLoopEndbranchInitReg(loopRep, endBranchReg);
1913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  uint32_t numBlks = static_cast<uint32_t>(exitingBlks.size());
1915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(numBlks >=2 && numBlks == exitBlks.size());
1916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *preExitingBlk = exitingBlks[0];
1918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *preExitBlk = exitBlks[0];
1919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *preBranchBlk = funcRep->CreateMachineBasicBlock();
1920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  funcRep->push_back(preBranchBlk);  //insert to function
1921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SHOWNEWBLK(preBranchBlk, "New loopEndbranch block: ");
1922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *newLandBlk = preBranchBlk;
1924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::replaceInstrUseOfBlockWith(preExitingBlk, preExitBlk,
1926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        newLandBlk);
1927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  preExitingBlk->removeSuccessor(preExitBlk);
1928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  preExitingBlk->addSuccessor(newLandBlk);
1929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //it is redundant to add reg = 0 to exitingBlks[0]
1931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // For 1..n th exiting path (the last iteration handles two pathes) create the
1933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // branch to the previous path and the current path.
1934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (uint32_t i = 1; i < numBlks; ++i) {
1935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curExitingBlk = exitingBlks[i];
1936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curExitBlk = exitBlks[i];
1937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curBranchBlk;
1938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (i == numBlks - 1) {
1940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curBranchBlk = curExitBlk;
1941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
1942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curBranchBlk = funcRep->CreateMachineBasicBlock();
1943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      funcRep->push_back(curBranchBlk);  //insert to function
1944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SHOWNEWBLK(curBranchBlk, "New loopEndbranch block: ");
1945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
1946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Add reg = i to exitingBlks[i].
1948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::insertAssignInstrBefore(curExitingBlk, passRep,
1949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       endBranchReg, i);
1950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Remove the edge (exitingBlks[i] exitBlks[i]) add new edge
1952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // (exitingBlks[i], newLandBlk).
1953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    CFGTraits::replaceInstrUseOfBlockWith(curExitingBlk, curExitBlk,
1954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          newLandBlk);
1955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curExitingBlk->removeSuccessor(curExitBlk);
1956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curExitingBlk->addSuccessor(newLandBlk);
1957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // add to preBranchBlk the branch instruction:
1959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // if (endBranchReg == preVal)
1960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //    preExitBlk
1961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // else
1962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //    curBranchBlk
1963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //
1964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // preValReg = i - 1
1965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DebugLoc DL;
1967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  RegiT preValReg = static_cast<int>
1968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    (funcRep->getRegInfo().createVirtualRegister(I32RC));
1969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  preBranchBlk->insert(preBranchBlk->begin(),
1971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       tii->getMovImmInstr(preBranchBlk->getParent(), preValReg,
1972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       i - 1));
1973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // condResReg = (endBranchReg == preValReg)
1975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    RegiT condResReg = static_cast<int>
1976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (funcRep->getRegInfo().createVirtualRegister(I32RC));
1977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BuildMI(preBranchBlk, DL, tii->get(tii->getIEQOpcode()), condResReg)
1978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .addReg(endBranchReg).addReg(preValReg);
1979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BuildMI(preBranchBlk, DL, tii->get(AMDGPU::BRANCH_COND_i32))
1981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      .addMBB(preExitBlk).addReg(condResReg);
1982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    preBranchBlk->addSuccessor(preExitBlk);
1984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    preBranchBlk->addSuccessor(curBranchBlk);
1985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    // Update preExitingBlk, preExitBlk, preBranchBlk.
1987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    preExitingBlk = curExitingBlk;
1988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    preExitBlk = curExitBlk;
1989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    preBranchBlk = curBranchBlk;
1990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }  //end for 1 .. n blocks
1992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return newLandBlk;
1994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //addLoopEndbranchBlock
1995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
1996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
1997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::PathToKind
1998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::singlePathTo(BlockT *srcBlk, BlockT *dstBlk,
1999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     bool allowSideEntry) {
2000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(dstBlk);
2001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlk == dstBlk) {
2003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return SinglePath_InPath;
2004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (srcBlk && srcBlk->succ_size() == 1) {
2007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    srcBlk = *srcBlk->succ_begin();
2008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (srcBlk == dstBlk) {
2009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return SinglePath_InPath;
2010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!allowSideEntry && srcBlk->pred_size() > 1) {
2013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return Not_SinglePath;
2014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlk && srcBlk->succ_size()==0) {
2018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return SinglePath_NotInPath;
2019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return Not_SinglePath;
2022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //singlePathTo
2023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// If there is a single path from srcBlk to dstBlk, return the last block before
2025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// dstBlk If there is a single path from srcBlk->end without dstBlk, return the
2026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// last block in the path Otherwise, return NULL
2027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
2029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::singlePathEnd(BlockT *srcBlk, BlockT *dstBlk,
2030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      bool allowSideEntry) {
2031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(dstBlk);
2032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlk == dstBlk) {
2034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return srcBlk;
2035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlk->succ_size() == 0) {
2038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return srcBlk;
2039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (srcBlk && srcBlk->succ_size() == 1) {
2042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *preBlk = srcBlk;
2043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    srcBlk = *srcBlk->succ_begin();
2045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (srcBlk == NULL) {
2046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return preBlk;
2047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!allowSideEntry && srcBlk->pred_size() > 1) {
2050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
2051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlk && srcBlk->succ_size()==0) {
2055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return srcBlk;
2056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return NULL;
2059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //singlePathEnd
2061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::cloneOnSideEntryTo(BlockT *preBlk, BlockT *srcBlk,
2064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               BlockT *dstBlk) {
2065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int cloned = 0;
2066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(preBlk->isSuccessor(srcBlk));
2067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (srcBlk && srcBlk != dstBlk) {
2068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(srcBlk->succ_size() == 1);
2069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (srcBlk->pred_size() > 1) {
2070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      srcBlk = cloneBlockForPredecessor(srcBlk, preBlk);
2071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ++cloned;
2072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    preBlk = srcBlk;
2075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    srcBlk = *srcBlk->succ_begin();
2076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return cloned;
2079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //cloneOnSideEntryTo
2080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
2083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::cloneBlockForPredecessor(BlockT *curBlk,
2084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 BlockT *predBlk) {
2085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(predBlk->isSuccessor(curBlk) &&
2086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         "succBlk is not a prececessor of curBlk");
2087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *cloneBlk = CFGTraits::clone(curBlk);  //clone instructions
2089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::replaceInstrUseOfBlockWith(predBlk, curBlk, cloneBlk);
2090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //srcBlk, oldBlk, newBlk
2091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  predBlk->removeSuccessor(curBlk);
2093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  predBlk->addSuccessor(cloneBlk);
2094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // add all successor to cloneBlk
2096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::cloneSuccessorList(cloneBlk, curBlk);
2097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  numClonedInstr += curBlk->size();
2099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Cloned block: " << "BB"
2102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << curBlk->getNumber() << "size " << curBlk->size() << "\n";
2103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SHOWNEWBLK(cloneBlk, "result of Cloned block: ");
2106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return cloneBlk;
2108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //cloneBlockForPredecessor
2109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
2112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::exitingBlock2ExitBlock(LoopT *loopRep,
2113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               BlockT *exitingBlk) {
2114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *exitBlk = NULL;
2115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename BlockT::succ_iterator iterSucc = exitingBlk->succ_begin(),
2117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterSuccEnd = exitingBlk->succ_end();
2118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterSucc != iterSuccEnd; ++iterSucc) {
2119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curBlk = *iterSucc;
2120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!loopRep->contains(curBlk)) {
2121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(exitBlk == NULL);
2122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exitBlk = curBlk;
2123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(exitBlk != NULL);
2127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return exitBlk;
2129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //exitingBlock2ExitBlock
2130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::migrateInstruction(BlockT *srcBlk,
2133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                BlockT *dstBlk,
2134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                InstrIterator insertPos) {
2135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrIterator spliceEnd;
2136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //look for the input branchinstr, not the AMDGPU branchinstr
2137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrT *branchInstr = CFGTraits::getNormalBlockBranchInstr(srcBlk);
2138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (branchInstr == NULL) {
2139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
2140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "migrateInstruction don't see branch instr\n" ;
2141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    spliceEnd = srcBlk->end();
2143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } else {
2144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
2145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "migrateInstruction see branch instr\n" ;
2146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      branchInstr->dump();
2147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    spliceEnd = CFGTraits::getInstrPos(srcBlk, branchInstr);
2149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "migrateInstruction before splice dstSize = " << dstBlk->size()
2152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      << "srcSize = " << srcBlk->size() << "\n";
2153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //splice insert before insertPos
2156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  dstBlk->splice(insertPos, srcBlk, srcBlk->begin(), spliceEnd);
2157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "migrateInstruction after splice dstSize = " << dstBlk->size()
2160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      << "srcSize = " << srcBlk->size() << "\n";
2161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //migrateInstruction
2163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// normalizeInfiniteLoopExit change
2165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//   B1:
2166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//        uncond_br LoopHeader
2167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// to
2169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//   B1:
2170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//        cond_br 1 LoopHeader dummyExit
2171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// and return the newly added dummy exit block
2172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
2175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::normalizeInfiniteLoopExit(LoopT* LoopRep) {
2176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *loopHeader;
2177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *loopLatch;
2178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  loopHeader = LoopRep->getHeader();
2179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  loopLatch = LoopRep->getLoopLatch();
2180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *dummyExitBlk = NULL;
2181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);
2182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (loopHeader!=NULL && loopLatch!=NULL) {
2183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    InstrT *branchInstr = CFGTraits::getLoopendBlockBranchInstr(loopLatch);
2184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (branchInstr!=NULL && CFGTraits::isUncondBranch(branchInstr)) {
2185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dummyExitBlk = funcRep->CreateMachineBasicBlock();
2186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      funcRep->push_back(dummyExitBlk);  //insert to function
2187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SHOWNEWBLK(dummyExitBlk, "DummyExitBlock to normalize infiniteLoop: ");
2188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) errs() << "Old branch instr: " << *branchInstr << "\n";
2190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      typename BlockT::iterator insertPos =
2192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        CFGTraits::getInstrPos(loopLatch, branchInstr);
2193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned immReg =
2194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        funcRep->getRegInfo().createVirtualRegister(I32RC);
2195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::insertAssignInstrBefore(insertPos, passRep, immReg, 1);
2196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      InstrT *newInstr =
2197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        CFGTraits::insertInstrBefore(insertPos, AMDGPU::BRANCH_COND_i32, passRep);
2198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstrBuilder(newInstr).addMBB(loopHeader).addReg(immReg, false);
2199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SHOWNEWINSTR(newInstr);
2201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      branchInstr->eraseFromParent();
2203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      loopLatch->addSuccessor(dummyExitBlk);
2204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return dummyExitBlk;
2208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //normalizeInfiniteLoopExit
2209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::removeUnconditionalBranch(BlockT *srcBlk) {
2212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  InstrT *branchInstr;
2213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // I saw two unconditional branch in one basic block in example
2215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // test_fc_do_while_or.c need to fix the upstream on this to remove the loop.
2216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while ((branchInstr = CFGTraits::getLoopendBlockBranchInstr(srcBlk))
2217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && CFGTraits::isUncondBranch(branchInstr)) {
2218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
2219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          errs() << "Removing unconditional branch instruction" ;
2220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      branchInstr->dump();
2221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    branchInstr->eraseFromParent();
2223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //removeUnconditionalBranch
2225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::removeRedundantConditionalBranch(BlockT *srcBlk) {
2228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlk->succ_size() == 2) {
2229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *blk1 = *srcBlk->succ_begin();
2230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *blk2 = *(++srcBlk->succ_begin());
2231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (blk1 == blk2) {
2233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      InstrT *branchInstr = CFGTraits::getNormalBlockBranchInstr(srcBlk);
2234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(branchInstr && CFGTraits::isCondBranch(branchInstr));
2235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
2236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "Removing unneeded conditional branch instruction" ;
2237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        branchInstr->dump();
2238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      branchInstr->eraseFromParent();
2240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      SHOWNEWBLK(blk1, "Removing redundant successor");
2241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      srcBlk->removeSuccessor(blk1);
2242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //removeRedundantConditionalBranch
2245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addDummyExitBlock(SmallVector<BlockT*,
2248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                               DEFAULT_VEC_SLOTS> &retBlks) {
2249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *dummyExitBlk = funcRep->CreateMachineBasicBlock();
2250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  funcRep->push_back(dummyExitBlk);  //insert to function
2251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  CFGTraits::insertInstrEnd(dummyExitBlk, AMDGPU::RETURN, passRep);
2252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename SmallVector<BlockT *, DEFAULT_VEC_SLOTS>::iterator iter =
2254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         retBlks.begin(),
2255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       iterEnd = retBlks.end(); iter != iterEnd; ++iter) {
2256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curBlk = *iter;
2257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    InstrT *curInstr = CFGTraits::getReturnInstr(curBlk);
2258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (curInstr) {
2259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curInstr->eraseFromParent();
2260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if 0
2262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (curBlk->size()==0 && curBlk->pred_size() == 1) {
2263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
2264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "Replace empty block BB" <<  curBlk->getNumber()
2265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          << " with dummyExitBlock\n";
2266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *predb = *curBlk->pred_begin();
2268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      predb->removeSuccessor(curBlk);
2269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curBlk = predb;
2270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } //handle empty curBlk
2271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
2272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    curBlk->addSuccessor(dummyExitBlk);
2273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (DEBUGME) {
2274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "Add dummyExitBlock to BB" << curBlk->getNumber()
2275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             << " successors\n";
2276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //for
2278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SHOWNEWBLK(dummyExitBlk, "DummyExitBlock: ");
2280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //addDummyExitBlock
2281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::removeSuccessor(BlockT *srcBlk) {
2284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (srcBlk->succ_size()) {
2285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    srcBlk->removeSuccessor(*srcBlk->succ_begin());
2286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::recordSccnum(BlockT *srcBlk, int sccNum) {
2291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockInfo *&srcBlkInfo = blockInfoMap[srcBlk];
2292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlkInfo == NULL) {
2294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    srcBlkInfo = new BlockInfo();
2295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  srcBlkInfo->sccNum = sccNum;
2298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::getSCCNum(BlockT *srcBlk) {
2302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockInfo *srcBlkInfo = blockInfoMap[srcBlk];
2303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return srcBlkInfo ? srcBlkInfo->sccNum : INVALIDSCCNUM;
2304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::retireBlock(BlockT *dstBlk, BlockT *srcBlk) {
2308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "Retiring BB" << srcBlk->getNumber() << "\n";
2310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockInfo *&srcBlkInfo = blockInfoMap[srcBlk];
2313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (srcBlkInfo == NULL) {
2315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    srcBlkInfo = new BlockInfo();
2316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  srcBlkInfo->isRetired = true;
2319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //int i = srcBlk->succ_size();
2320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //int j = srcBlk->pred_size();
2321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(srcBlk->succ_size() == 0 && srcBlk->pred_size() == 0
2322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         && "can't retire block yet");
2323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::isRetiredBlock(BlockT *srcBlk) {
2327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockInfo *srcBlkInfo = blockInfoMap[srcBlk];
2328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return (srcBlkInfo && srcBlkInfo->isRetired);
2329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::isActiveLoophead(BlockT *curBlk) {
2333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopT *loopRep = loopInfo->getLoopFor(curBlk);
2334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (loopRep && loopRep->getHeader() == curBlk) {
2335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    LoopLandInfo *loopLand = getLoopLandInfo(loopRep);
2336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if(loopLand == NULL)
2338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
2339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *landBlk = loopLand->landBlk;
2341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(landBlk);
2342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!isRetiredBlock(landBlk)) {
2343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return true;
2344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    loopRep = loopRep->getParentLoop();
2347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return false;
2350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //isActiveLoophead
2351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::needMigrateBlock(BlockT *blk) {
2354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const unsigned blockSizeThreshold = 30;
2355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const unsigned cloneInstrThreshold = 100;
2356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool multiplePreds = blk && (blk->pred_size() > 1);
2358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if(!multiplePreds)
2360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return false;
2361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  unsigned blkSize = blk->size();
2363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return ((blkSize > blockSizeThreshold)
2364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          && (blkSize * (blk->pred_size() - 1) > cloneInstrThreshold));
2365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //needMigrateBlock
2366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
2369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::recordLoopLandBlock(LoopT *loopRep, BlockT *landBlk,
2370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            BlockTSmallerVector &exitBlks,
2371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                            std::set<BlockT *> &exitBlkSet) {
2372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  SmallVector<BlockT *, DEFAULT_VEC_SLOTS> inpathBlks;  //in exit path blocks
2373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (typename BlockT::pred_iterator predIter = landBlk->pred_begin(),
2375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       predIterEnd = landBlk->pred_end();
2376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       predIter != predIterEnd; ++predIter) {
2377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curBlk = *predIter;
2378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (loopRep->contains(curBlk) || exitBlkSet.count(curBlk)) {
2379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      inpathBlks.push_back(curBlk);
2380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //for
2382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //if landBlk has predecessors that are not in the given loop,
2384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //create a new block
2385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *newLandBlk = landBlk;
2386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (inpathBlks.size() != landBlk->pred_size()) {
2387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    newLandBlk = funcRep->CreateMachineBasicBlock();
2388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    funcRep->push_back(newLandBlk);  //insert to function
2389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    newLandBlk->addSuccessor(landBlk);
2390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (typename SmallVector<BlockT*, DEFAULT_VEC_SLOTS>::iterator iter =
2391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         inpathBlks.begin(),
2392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterEnd = inpathBlks.end(); iter != iterEnd; ++iter) {
2393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BlockT *curBlk = *iter;
2394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      CFGTraits::replaceInstrUseOfBlockWith(curBlk, landBlk, newLandBlk);
2395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      //srcBlk, oldBlk, newBlk
2396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curBlk->removeSuccessor(landBlk);
2397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      curBlk->addSuccessor(newLandBlk);
2398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (size_t i = 0, tot = exitBlks.size(); i < tot; ++i) {
2400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (exitBlks[i] == landBlk) {
2401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        exitBlks[i] = newLandBlk;
2402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWBLK(newLandBlk, "NewLandingBlock: ");
2405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  setLoopLandBlock(loopRep, newLandBlk);
2408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return newLandBlk;
2410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // recordLoopbreakLand
2411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::setLoopLandBlock(LoopT *loopRep, BlockT *blk) {
2414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (theEntry == NULL) {
2417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    theEntry = new LoopLandInfo();
2418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  assert(theEntry->landBlk == NULL);
2420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (blk == NULL) {
2422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk = funcRep->CreateMachineBasicBlock();
2423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    funcRep->push_back(blk);  //insert to function
2424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWBLK(blk, "DummyLandingBlock for loop without break: ");
2425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  theEntry->landBlk = blk;
2428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "setLoopLandBlock loop-header = BB"
2431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << loopRep->getHeader()->getNumber()
2432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << "  landing-block = BB" << blk->getNumber() << "\n";
2433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // setLoopLandBlock
2435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopBreakOnReg(LoopT *loopRep, RegiT regNum) {
2438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (theEntry == NULL) {
2441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    theEntry = new LoopLandInfo();
2442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  theEntry->breakOnRegs.insert(regNum);
2445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "addLoopBreakOnReg loop-header = BB"
2448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << loopRep->getHeader()->getNumber()
2449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << "  regNum = " << regNum << "\n";
2450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopBreakOnReg
2452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopContOnReg(LoopT *loopRep, RegiT regNum) {
2455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (theEntry == NULL) {
2458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    theEntry = new LoopLandInfo();
2459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  theEntry->contOnRegs.insert(regNum);
2461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "addLoopContOnReg loop-header = BB"
2464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << loopRep->getHeader()->getNumber()
2465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << "  regNum = " << regNum << "\n";
2466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopContOnReg
2468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopBreakInitReg(LoopT *loopRep, RegiT regNum) {
2471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (theEntry == NULL) {
2474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    theEntry = new LoopLandInfo();
2475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  theEntry->breakInitRegs.insert(regNum);
2477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "addLoopBreakInitReg loop-header = BB"
2480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << loopRep->getHeader()->getNumber()
2481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << "  regNum = " << regNum << "\n";
2482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopBreakInitReg
2484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopContInitReg(LoopT *loopRep, RegiT regNum) {
2487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (theEntry == NULL) {
2490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    theEntry = new LoopLandInfo();
2491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  theEntry->contInitRegs.insert(regNum);
2493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "addLoopContInitReg loop-header = BB"
2496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << loopRep->getHeader()->getNumber()
2497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           << "  regNum = " << regNum << "\n";
2498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopContInitReg
2500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid CFGStructurizer<PassT>::addLoopEndbranchInitReg(LoopT *loopRep,
2503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                     RegiT regNum) {
2504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (theEntry == NULL) {
2507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    theEntry = new LoopLandInfo();
2508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  theEntry->endbranchInitRegs.insert(regNum);
2510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME)
2512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
2513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "addLoopEndbranchInitReg loop-header = BB"
2514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      << loopRep->getHeader()->getNumber()
2515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      << "  regNum = " << regNum << "\n";
2516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // addLoopEndbranchInitReg
2518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::LoopLandInfo *
2521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::getLoopLandInfo(LoopT *loopRep) {
2522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return theEntry;
2525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // getLoopLandInfo
2526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
2529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::getLoopLandBlock(LoopT *loopRep) {
2530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopLandInfo *&theEntry = loopLandInfoMap[loopRep];
2531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return theEntry ? theEntry->landBlk : NULL;
2533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} // getLoopLandBlock
2534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool CFGStructurizer<PassT>::hasBackEdge(BlockT *curBlk) {
2538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  LoopT *loopRep = loopInfo->getLoopFor(curBlk);
2539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (loopRep == NULL)
2540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return false;
2541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *loopHeader = loopRep->getHeader();
2543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return curBlk->isSuccessor(loopHeader);
2545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //hasBackEdge
2547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned CFGStructurizer<PassT>::getLoopDepth(LoopT *loopRep) {
2550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return loopRep ? loopRep->getLoopDepth() : 0;
2551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //getLoopDepth
2552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint CFGStructurizer<PassT>::countActiveBlock
2555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org(typename SmallVector<BlockT*, DEFAULT_VEC_SLOTS>::const_iterator iterStart,
2556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org typename SmallVector<BlockT*, DEFAULT_VEC_SLOTS>::const_iterator iterEnd) {
2557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  int count = 0;
2558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (iterStart != iterEnd) {
2559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!isRetiredBlock(*iterStart)) {
2560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ++count;
2561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++iterStart;
2563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return count;
2566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //countActiveBlock
2567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This is work around solution for findNearestCommonDominator not avaiable to
2569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// post dom a proper fix should go to Dominators.h.
2570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT*
2573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::findNearestCommonPostDom(BlockT *blk1, BlockT *blk2) {
2574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (postDomTree->dominates(blk1, blk2)) {
2576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return blk1;
2577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (postDomTree->dominates(blk2, blk1)) {
2579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return blk2;
2580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DomTreeNodeT *node1 = postDomTree->getNode(blk1);
2583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  DomTreeNodeT *node2 = postDomTree->getNode(blk2);
2584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // Handle newly cloned node.
2586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (node1 == NULL && blk1->succ_size() == 1) {
2587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return findNearestCommonPostDom(*blk1->succ_begin(), blk2);
2588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (node2 == NULL && blk2->succ_size() == 1) {
2590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return findNearestCommonPostDom(blk1, *blk2->succ_begin());
2591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (node1 == NULL || node2 == NULL) {
2594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
2595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  node1 = node1->getIDom();
2598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  while (node1) {
2599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (postDomTree->dominates(node1, node2)) {
2600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return node1->getBlock();
2601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    node1 = node1->getIDom();
2603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return NULL;
2606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<class PassT>
2609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypename CFGStructurizer<PassT>::BlockT *
2610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgCFGStructurizer<PassT>::findNearestCommonPostDom
2611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org(typename std::set<BlockT *> &blks) {
2612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  BlockT *commonDom;
2613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typename std::set<BlockT *>::const_iterator iter = blks.begin();
2614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typename std::set<BlockT *>::const_iterator iterEnd = blks.end();
2615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  for (commonDom = *iter; iter != iterEnd && commonDom != NULL; ++iter) {
2616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    BlockT *curBlk = *iter;
2617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (curBlk != commonDom) {
2618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      commonDom = findNearestCommonPostDom(curBlk, commonDom);
2619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  if (DEBUGME) {
2623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    errs() << "Common post dominator for exit blocks is ";
2624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (commonDom) {
2625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          errs() << "BB" << commonDom->getNumber() << "\n";
2626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
2627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      errs() << "NULL\n";
2628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return commonDom;
2632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //findNearestCommonPostDom
2633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end namespace llvm
2635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//todo: move-end
2637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGStructurizer for AMDGPU
2642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvmCFGStruct;
2647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm
2649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUCFGStructurizer : public MachineFunctionPass
2651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachineInstr              InstructionType;
2654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachineFunction           FunctionType;
2655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachineBasicBlock         BlockType;
2656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachineLoopInfo           LoopinfoType;
2657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachineDominatorTree      DominatortreeType;
2658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachinePostDominatorTree  PostDominatortreeType;
2659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachineDomTreeNode        DomTreeNodeType;
2660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef MachineLoop               LoopType;
2661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprotected:
2663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TargetMachine &TM;
2664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetInstrInfo *TII;
2665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const AMDGPURegisterInfo *TRI;
2666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AMDGPUCFGStructurizer(char &pid, TargetMachine &tm);
2669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  const TargetInstrInfo *getTargetInstrInfo() const;
2670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //bool runOnMachineFunction(MachineFunction &F);
2671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
2673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};   //end of class AMDGPUCFGStructurizer
2675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2676f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//char AMDGPUCFGStructurizer::ID = 0;
2677f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm
2678f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUCFGStructurizer::AMDGPUCFGStructurizer(char &pid, TargetMachine &tm
2679f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          )
2680f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org: MachineFunctionPass(pid), TM(tm), TII(tm.getInstrInfo()),
2681f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  TRI(static_cast<const AMDGPURegisterInfo *>(tm.getRegisterInfo())
2682f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  ) {
2683f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2684f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2685f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst TargetInstrInfo *AMDGPUCFGStructurizer::getTargetInstrInfo() const {
2686f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return TII;
2687f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2688f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2689f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2690f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGPrepare
2691f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2692f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2693f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2694f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2695f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvmCFGStruct;
2696f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2697f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm
2698f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2699f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUCFGPrepare : public AMDGPUCFGStructurizer
2700f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2701f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2702f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static char ID;
2703f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2704f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2705f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AMDGPUCFGPrepare(TargetMachine &tm);
2706f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2707f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  virtual const char *getPassName() const;
2708f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
2709f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2710f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool runOnMachineFunction(MachineFunction &F);
2711f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2712f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
2713f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2714f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};   //end of class AMDGPUCFGPrepare
2715f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2716f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar AMDGPUCFGPrepare::ID = 0;
2717f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm
2718f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2719f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgAMDGPUCFGPrepare::AMDGPUCFGPrepare(TargetMachine &tm)
2720f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  : AMDGPUCFGStructurizer(ID, tm )
2721f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2722f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2723f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst char *AMDGPUCFGPrepare::getPassName() const {
2724f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return "AMD IL Control Flow Graph Preparation Pass";
2725f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2726f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2727f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid AMDGPUCFGPrepare::getAnalysisUsage(AnalysisUsage &AU) const {
2728f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addPreserved<MachineFunctionAnalysis>();
2729f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachineFunctionAnalysis>();
2730f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachineDominatorTree>();
2731f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachinePostDominatorTree>();
2732f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachineLoopInfo>();
2733f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2734f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2735f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2736f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2737f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGPerform
2738f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2739f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2740f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2741f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2742f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgusing namespace llvmCFGStruct;
2743f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2744f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm
2745f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2746f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AMDGPUCFGPerform : public AMDGPUCFGStructurizer
2747f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2748f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2749f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static char ID;
2750f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2751f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic:
2752f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AMDGPUCFGPerform(TargetMachine &tm);
2753f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  virtual const char *getPassName() const;
2754f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
2755f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  bool runOnMachineFunction(MachineFunction &F);
2756f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2757f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgprivate:
2758f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2759f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};   //end of class AMDGPUCFGPerform
2760f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2761f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgchar AMDGPUCFGPerform::ID = 0;
2762f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm
2763f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2764f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AMDGPUCFGPerform::AMDGPUCFGPerform(TargetMachine &tm)
2765f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org: AMDGPUCFGStructurizer(ID, tm)
2766f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2767f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2768f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2769f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgconst char *AMDGPUCFGPerform::getPassName() const {
2770f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return "AMD IL Control Flow Graph structurizer Pass";
2771f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2772f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2773f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid AMDGPUCFGPerform::getAnalysisUsage(AnalysisUsage &AU) const {
2774f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addPreserved<MachineFunctionAnalysis>();
2775f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachineFunctionAnalysis>();
2776f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachineDominatorTree>();
2777f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachinePostDominatorTree>();
2778f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  AU.addRequired<MachineLoopInfo>();
2779f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
2780f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2781f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2782f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2783f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// CFGStructTraits<AMDGPUCFGStructurizer>
2784f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//
2785f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===//
2786f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2787f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvmCFGStruct
2788f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2789f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// this class is tailor to the AMDGPU backend
2790f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate<>
2791f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct CFGStructTraits<AMDGPUCFGStructurizer>
2792f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
2793f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef int RegiT;
2794f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2795f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static int getBreakNzeroOpcode(int oldOpcode) {
2796f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(oldOpcode) {
2797f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::JUMP: return AMDGPU::BREAK_LOGICALNZ_i32;
2798f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
2799f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0 && "internal error");
2800f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    };
2801f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return -1;
2802f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2803f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2804f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static int getBreakZeroOpcode(int oldOpcode) {
2805f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(oldOpcode) {
2806f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::JUMP: return AMDGPU::BREAK_LOGICALZ_i32;
2807f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
2808f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0 && "internal error");
2809f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    };
2810f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return -1;
2811f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2812f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2813f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static int getBranchNzeroOpcode(int oldOpcode) {
2814f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(oldOpcode) {
2815f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case AMDGPU::JUMP: return AMDGPU::IF_LOGICALNZ_i32;
2816f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ExpandCaseToAllScalarReturn(AMDGPU::BRANCH_COND, AMDGPU::IF_LOGICALNZ);
2817f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::SI_IF_NZ: return AMDGPU::SI_IF_NZ;
2818f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
2819f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0 && "internal error");
2820f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    };
2821f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return -1;
2822f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2823f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2824f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static int getBranchZeroOpcode(int oldOpcode) {
2825f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(oldOpcode) {
2826f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case AMDGPU::JUMP: return AMDGPU::IF_LOGICALZ_i32;
2827f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ExpandCaseToAllScalarReturn(AMDGPU::BRANCH_COND, AMDGPU::IF_LOGICALZ);
2828f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::SI_IF_Z: return AMDGPU::SI_IF_Z;
2829f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
2830f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0 && "internal error");
2831f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    };
2832f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return -1;
2833f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2834f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2835f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static int getContinueNzeroOpcode(int oldOpcode)
2836f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  {
2837f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(oldOpcode) {
2838f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::JUMP: return AMDGPU::CONTINUE_LOGICALNZ_i32;
2839f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
2840f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert(0 && "internal error");
2841f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    };
2842f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return -1;
2843f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2844f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2845f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static int getContinueZeroOpcode(int oldOpcode) {
2846f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch(oldOpcode) {
2847f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::JUMP: return AMDGPU::CONTINUE_LOGICALZ_i32;
2848f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
2849f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0 && "internal error");
2850f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    };
2851f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return -1;
2852f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2853f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2854f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// the explicitly represented branch target is the true branch target
2855f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define getExplicitBranch getTrueBranch
2856f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define setExplicitBranch setTrueBranch
2857f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2858f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineBasicBlock *getTrueBranch(MachineInstr *instr) {
2859f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return instr->getOperand(0).getMBB();
2860f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2861f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2862f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void setTrueBranch(MachineInstr *instr, MachineBasicBlock *blk) {
2863f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    instr->getOperand(0).setMBB(blk);
2864f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2865f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2866f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineBasicBlock *
2867f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  getFalseBranch(MachineBasicBlock *blk, MachineInstr *instr) {
2868f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(blk->succ_size() == 2);
2869f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock *trueBranch = getTrueBranch(instr);
2870f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::succ_iterator iter = blk->succ_begin();
2871f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::succ_iterator iterNext = iter;
2872f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ++iterNext;
2873f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2874f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return (*iter == trueBranch) ? *iterNext : *iter;
2875f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2876f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2877f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static bool isCondBranch(MachineInstr *instr) {
2878f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (instr->getOpcode()) {
2879f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::JUMP:
2880f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return instr->getOperand(instr->findFirstPredOperandIdx()).getReg() != 0;
2881f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ExpandCaseToAllScalarTypes(AMDGPU::BRANCH_COND);
2882f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::SI_IF_NZ:
2883f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case AMDGPU::SI_IF_Z:
2884f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
2885f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
2886f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
2887f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2888f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return true;
2889f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2890f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2891f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static bool isUncondBranch(MachineInstr *instr) {
2892f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (instr->getOpcode()) {
2893f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case AMDGPU::JUMP:
2894f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return instr->getOperand(instr->findFirstPredOperandIdx()).getReg() == 0;
2895f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
2896f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return false;
2897f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2898f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return true;
2899f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2900f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2901f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static DebugLoc getLastDebugLocInBB(MachineBasicBlock *blk) {
2902f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //get DebugLoc from the first MachineBasicBlock instruction with debug info
2903f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    DebugLoc DL;
2904f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	for (MachineBasicBlock::iterator iter = blk->begin(); iter != blk->end(); ++iter) {
2905f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  MachineInstr *instr = &(*iter);
2906f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  if (instr->getDebugLoc().isUnknown() == false) {
2907f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	    DL = instr->getDebugLoc();
2908f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org	  }
2909f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2910f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return DL;
2911f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2912f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2913f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *getNormalBlockBranchInstr(MachineBasicBlock *blk) {
2914f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::reverse_iterator iter = blk->rbegin();
2915f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *instr = &*iter;
2916f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (instr && (isCondBranch(instr) || isUncondBranch(instr))) {
2917f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return instr;
2918f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2919f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
2920f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2921f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2922f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // The correct naming for this is getPossibleLoopendBlockBranchInstr.
2923f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //
2924f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // BB with backward-edge could have move instructions after the branch
2925f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  // instruction.  Such move instruction "belong to" the loop backward-edge.
2926f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //
2927f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *getLoopendBlockBranchInstr(MachineBasicBlock *blk) {
2928f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const AMDGPUInstrInfo * TII = static_cast<const AMDGPUInstrInfo *>(
2929f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  blk->getParent()->getTarget().getInstrInfo());
2930f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2931f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (MachineBasicBlock::reverse_iterator iter = blk->rbegin(),
2932f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterEnd = blk->rend(); iter != iterEnd; ++iter) {
2933f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      // FIXME: Simplify
2934f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *instr = &*iter;
2935f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (instr) {
2936f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (isCondBranch(instr) || isUncondBranch(instr)) {
2937f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          return instr;
2938f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else if (!TII->isMov(instr->getOpcode())) {
2939f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org          break;
2940f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
2941f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2942f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2943f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
2944f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2945f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2946f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *getReturnInstr(MachineBasicBlock *blk) {
2947f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::reverse_iterator iter = blk->rbegin();
2948f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (iter != blk->rend()) {
2949f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *instr = &(*iter);
2950f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (instr->getOpcode() == AMDGPU::RETURN) {
2951f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return instr;
2952f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2953f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2954f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
2955f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2956f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2957f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *getContinueInstr(MachineBasicBlock *blk) {
2958f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::reverse_iterator iter = blk->rbegin();
2959f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (iter != blk->rend()) {
2960f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *instr = &(*iter);
2961f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (instr->getOpcode() == AMDGPU::CONTINUE) {
2962f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return instr;
2963f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2964f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2965f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
2966f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2967f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2968f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *getLoopBreakInstr(MachineBasicBlock *blk) {
2969f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (MachineBasicBlock::iterator iter = blk->begin(); (iter != blk->end()); ++iter) {
2970f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *instr = &(*iter);
2971f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if ((instr->getOpcode() == AMDGPU::BREAK_LOGICALNZ_i32) || (instr->getOpcode() == AMDGPU::BREAK_LOGICALZ_i32)) {
2972f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return instr;
2973f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2974f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2975f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
2976f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2977f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2978f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static bool isReturnBlock(MachineBasicBlock *blk) {
2979f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *instr = getReturnInstr(blk);
2980f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    bool isReturn = (blk->succ_size() == 0);
2981f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (instr) {
2982f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(isReturn);
2983f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else if (isReturn) {
2984f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (DEBUGME) {
2985f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        errs() << "BB" << blk->getNumber()
2986f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               <<" is return block without RETURN instr\n";
2987f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
2988f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
2989f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2990f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return  isReturn;
2991f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
2992f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2993f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineBasicBlock::iterator
2994f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  getInstrPos(MachineBasicBlock *blk, MachineInstr *instr) {
2995f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(instr->getParent() == blk && "instruction doesn't belong to block");
2996f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::iterator iter = blk->begin();
2997f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::iterator iterEnd = blk->end();
2998f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    while (&(*iter) != instr && iter != iterEnd) {
2999f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ++iter;
3000f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3001f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3002f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert(iter != iterEnd);
3003f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return iter;
3004f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }//getInstrPos
3005f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3006f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *insertInstrBefore(MachineBasicBlock *blk, int newOpcode,
3007f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         AMDGPUCFGStructurizer *passRep) {
3008f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return insertInstrBefore(blk,newOpcode,passRep,DebugLoc());
3009f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertInstrBefore
3010f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3011f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *insertInstrBefore(MachineBasicBlock *blk, int newOpcode,
3012f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         AMDGPUCFGStructurizer *passRep, DebugLoc DL) {
3013f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
3014f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr =
3015f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->getParent()->CreateMachineInstr(tii->get(newOpcode), DL);
3016f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3017f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock::iterator res;
3018f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (blk->begin() != blk->end()) {
3019f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->insert(blk->begin(), newInstr);
3020f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
3021f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->push_back(newInstr);
3022f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3023f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3024f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3025f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3026f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return newInstr;
3027f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertInstrBefore
3028f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3029f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertInstrEnd(MachineBasicBlock *blk, int newOpcode,
3030f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             AMDGPUCFGStructurizer *passRep) {
3031f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    insertInstrEnd(blk,newOpcode,passRep,DebugLoc());
3032f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertInstrEnd
3033f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3034f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertInstrEnd(MachineBasicBlock *blk, int newOpcode,
3035f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             AMDGPUCFGStructurizer *passRep, DebugLoc DL) {
3036f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
3037f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   MachineInstr *newInstr = blk->getParent()
3038f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ->CreateMachineInstr(tii->get(newOpcode), DL);
3039f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3040f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk->push_back(newInstr);
3041f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //assume the instruction doesn't take any reg operand ...
3042f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3043f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3044f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertInstrEnd
3045f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3046f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineInstr *insertInstrBefore(MachineBasicBlock::iterator instrPos,
3047f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         int newOpcode,
3048f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         AMDGPUCFGStructurizer *passRep) {
3049f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *oldInstr = &(*instrPos);
3050f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
3051f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock *blk = oldInstr->getParent();
3052f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr =
3053f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->getParent()->CreateMachineInstr(tii->get(newOpcode),
3054f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           DebugLoc());
3055f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3056f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk->insert(instrPos, newInstr);
3057f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //assume the instruction doesn't take any reg operand ...
3058f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3059f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3060f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return newInstr;
3061f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertInstrBefore
3062f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3063f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertCondBranchBefore(MachineBasicBlock::iterator instrPos,
3064f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     int newOpcode,
3065f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     AMDGPUCFGStructurizer *passRep,
3066f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									 DebugLoc DL) {
3067f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *oldInstr = &(*instrPos);
3068f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
3069f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock *blk = oldInstr->getParent();
3070f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr =
3071f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->getParent()->CreateMachineInstr(tii->get(newOpcode),
3072f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                           DL);
3073f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3074f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk->insert(instrPos, newInstr);
3075f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstrBuilder(newInstr).addReg(oldInstr->getOperand(1).getReg(),
3076f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         false);
3077f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3078f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3079f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //erase later oldInstr->eraseFromParent();
3080f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertCondBranchBefore
3081f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3082f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertCondBranchBefore(MachineBasicBlock *blk,
3083f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     MachineBasicBlock::iterator insertPos,
3084f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     int newOpcode,
3085f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     AMDGPUCFGStructurizer *passRep,
3086f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                     RegiT regNum,
3087f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org									 DebugLoc DL) {
3088f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
3089f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3090f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr =
3091f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->getParent()->CreateMachineInstr(tii->get(newOpcode), DL);
3092f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3093f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //insert before
3094f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk->insert(insertPos, newInstr);
3095f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstrBuilder(newInstr).addReg(regNum, false);
3096f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3097f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3098f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertCondBranchBefore
3099f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertCondBranchEnd(MachineBasicBlock *blk,
3101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  int newOpcode,
3102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  AMDGPUCFGStructurizer *passRep,
3103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  RegiT regNum) {
3104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const TargetInstrInfo *tii = passRep->getTargetInstrInfo();
3105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr =
3106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->getParent()->CreateMachineInstr(tii->get(newOpcode), DebugLoc());
3107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk->push_back(newInstr);
3109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstrBuilder(newInstr).addReg(regNum, false);
3110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertCondBranchEnd
3113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertAssignInstrBefore(MachineBasicBlock::iterator instrPos,
3116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      AMDGPUCFGStructurizer *passRep,
3117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      RegiT regNum, int regVal) {
3118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *oldInstr = &(*instrPos);
3119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const AMDGPUInstrInfo *tii =
3120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo());
3121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock *blk = oldInstr->getParent();
3122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum,
3123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 regVal);
3124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk->insert(instrPos, newInstr);
3125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertAssignInstrBefore
3128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertAssignInstrBefore(MachineBasicBlock *blk,
3130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      AMDGPUCFGStructurizer *passRep,
3131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      RegiT regNum, int regVal) {
3132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const AMDGPUInstrInfo *tii =
3133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo());
3134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr = tii->getMovImmInstr(blk->getParent(), regNum,
3136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 regVal);
3137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (blk->begin() != blk->end()) {
3138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->insert(blk->begin(), newInstr);
3139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
3140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->push_back(newInstr);
3141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertInstrBefore
3146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void insertCompareInstrBefore(MachineBasicBlock *blk,
3148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       MachineBasicBlock::iterator instrPos,
3149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       AMDGPUCFGStructurizer *passRep,
3150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       RegiT dstReg, RegiT src1Reg,
3151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                       RegiT src2Reg) {
3152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    const AMDGPUInstrInfo *tii =
3153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             static_cast<const AMDGPUInstrInfo *>(passRep->getTargetInstrInfo());
3154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *newInstr =
3155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      blk->getParent()->CreateMachineInstr(tii->get(tii->getIEQOpcode()), DebugLoc());
3156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstrBuilder(newInstr).addReg(dstReg, RegState::Define); //set target
3158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstrBuilder(newInstr).addReg(src1Reg); //set src value
3159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstrBuilder(newInstr).addReg(src2Reg); //set src value
3160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    blk->insert(instrPos, newInstr);
3162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    SHOWNEWINSTR(newInstr);
3163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //insertCompareInstrBefore
3165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void cloneSuccessorList(MachineBasicBlock *dstBlk,
3167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 MachineBasicBlock *srcBlk) {
3168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (MachineBasicBlock::succ_iterator iter = srcBlk->succ_begin(),
3169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterEnd = srcBlk->succ_end(); iter != iterEnd; ++iter) {
3170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dstBlk->addSuccessor(*iter);  // *iter's predecessor is also taken care of
3171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //cloneSuccessorList
3173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineBasicBlock *clone(MachineBasicBlock *srcBlk) {
3175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineFunction *func = srcBlk->getParent();
3176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineBasicBlock *newBlk = func->CreateMachineBasicBlock();
3177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    func->push_back(newBlk);  //insert to function
3178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    //newBlk->setNumber(srcBlk->getNumber());
3179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    for (MachineBasicBlock::iterator iter = srcBlk->begin(),
3180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iterEnd = srcBlk->end();
3181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         iter != iterEnd; ++iter) {
3182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      MachineInstr *instr = func->CloneMachineInstr(iter);
3183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      newBlk->push_back(instr);
3184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return newBlk;
3186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //MachineBasicBlock::ReplaceUsesOfBlockWith doesn't serve the purpose because
3189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //the AMDGPU instruction is not recognized as terminator fix this and retire
3190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  //this routine
3191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void replaceInstrUseOfBlockWith(MachineBasicBlock *srcBlk,
3192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         MachineBasicBlock *oldBlk,
3193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         MachineBasicBlock *newBlk) {
3194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    MachineInstr *branchInstr = getLoopendBlockBranchInstr(srcBlk);
3195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (branchInstr && isCondBranch(branchInstr) &&
3196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        getExplicitBranch(branchInstr) == oldBlk) {
3197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      setExplicitBranch(branchInstr, newBlk);
3198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
3199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void wrapup(MachineBasicBlock *entryBlk) {
3202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    assert((!entryBlk->getParent()->getJumpTableInfo()
3203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            || entryBlk->getParent()->getJumpTableInfo()->isEmpty())
3204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           && "found a jump table");
3205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     //collect continue right before endloop
3207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     SmallVector<MachineInstr *, DEFAULT_VEC_SLOTS> contInstr;
3208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     MachineBasicBlock::iterator pre = entryBlk->begin();
3209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     MachineBasicBlock::iterator iterEnd = entryBlk->end();
3210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     MachineBasicBlock::iterator iter = pre;
3211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     while (iter != iterEnd) {
3212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       if (pre->getOpcode() == AMDGPU::CONTINUE
3213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org           && iter->getOpcode() == AMDGPU::ENDLOOP) {
3214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         contInstr.push_back(pre);
3215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       }
3216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       pre = iter;
3217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       ++iter;
3218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     } //end while
3219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     //delete continue right before endloop
3221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     for (unsigned i = 0; i < contInstr.size(); ++i) {
3222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        contInstr[i]->eraseFromParent();
3223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     }
3224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     // TODO to fix up jump table so later phase won't be confused.  if
3226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     // (jumpTableInfo->isEmpty() == false) { need to clean the jump table, but
3227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     // there isn't such an interface yet.  alternatively, replace all the other
3228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     // blocks in the jump table with the entryBlk //}
3229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  } //wrapup
3231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineDominatorTree *getDominatorTree(AMDGPUCFGStructurizer &pass) {
3233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return &pass.getAnalysis<MachineDominatorTree>();
3234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachinePostDominatorTree*
3237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  getPostDominatorTree(AMDGPUCFGStructurizer &pass) {
3238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return &pass.getAnalysis<MachinePostDominatorTree>();
3239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static MachineLoopInfo *getLoopInfo(AMDGPUCFGStructurizer &pass) {
3242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return &pass.getAnalysis<MachineLoopInfo>();
3243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
3244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; // template class CFGStructTraits
3245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} //end of namespace llvm
3246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// createAMDGPUCFGPreparationPass- Returns a pass
3248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFunctionPass *llvm::createAMDGPUCFGPreparationPass(TargetMachine &tm
3249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                 ) {
3250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return new AMDGPUCFGPrepare(tm );
3251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUCFGPrepare::runOnMachineFunction(MachineFunction &func) {
3254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return llvmCFGStruct::CFGStructurizer<AMDGPUCFGStructurizer>().prepare(func,
3255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                                        *this,
3256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                                        TRI);
3257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// createAMDGPUCFGStructurizerPass- Returns a pass
3260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgFunctionPass *llvm::createAMDGPUCFGStructurizerPass(TargetMachine &tm
3261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                  ) {
3262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return new AMDGPUCFGPerform(tm );
3263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgbool AMDGPUCFGPerform::runOnMachineFunction(MachineFunction &func) {
3266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  return llvmCFGStruct::CFGStructurizer<AMDGPUCFGStructurizer>().run(func,
3267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                                    *this,
3268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                                                    TRI);
3269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
3270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//end of file newline goes below
3272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
3273