xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonEarlyIfConv.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--- HexagonEarlyIfConv.cpp -------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This implements a Hexagon-specific if-conversion pass that runs on the
11*9880d681SAndroid Build Coastguard Worker // SSA form.
12*9880d681SAndroid Build Coastguard Worker // In SSA it is not straightforward to represent instructions that condi-
13*9880d681SAndroid Build Coastguard Worker // tionally define registers, since a conditionally-defined register may
14*9880d681SAndroid Build Coastguard Worker // only be used under the same condition on which the definition was based.
15*9880d681SAndroid Build Coastguard Worker // To avoid complications of this nature, this patch will only generate
16*9880d681SAndroid Build Coastguard Worker // predicated stores, and speculate other instructions from the "if-conver-
17*9880d681SAndroid Build Coastguard Worker // ted" block.
18*9880d681SAndroid Build Coastguard Worker // The code will recognize CFG patterns where a block with a conditional
19*9880d681SAndroid Build Coastguard Worker // branch "splits" into a "true block" and a "false block". Either of these
20*9880d681SAndroid Build Coastguard Worker // could be omitted (in case of a triangle, for example).
21*9880d681SAndroid Build Coastguard Worker // If after conversion of the side block(s) the CFG allows it, the resul-
22*9880d681SAndroid Build Coastguard Worker // ting blocks may be merged. If the "join" block contained PHI nodes, they
23*9880d681SAndroid Build Coastguard Worker // will be replaced with MUX (or MUX-like) instructions to maintain the
24*9880d681SAndroid Build Coastguard Worker // semantics of the PHI.
25*9880d681SAndroid Build Coastguard Worker //
26*9880d681SAndroid Build Coastguard Worker // Example:
27*9880d681SAndroid Build Coastguard Worker //
28*9880d681SAndroid Build Coastguard Worker //         %vreg40<def> = L2_loadrub_io %vreg39<kill>, 1
29*9880d681SAndroid Build Coastguard Worker //         %vreg41<def> = S2_tstbit_i %vreg40<kill>, 0
30*9880d681SAndroid Build Coastguard Worker //         J2_jumpt %vreg41<kill>, <BB#5>, %PC<imp-def,dead>
31*9880d681SAndroid Build Coastguard Worker //         J2_jump <BB#4>, %PC<imp-def,dead>
32*9880d681SAndroid Build Coastguard Worker //     Successors according to CFG: BB#4(62) BB#5(62)
33*9880d681SAndroid Build Coastguard Worker //
34*9880d681SAndroid Build Coastguard Worker // BB#4: derived from LLVM BB %if.then
35*9880d681SAndroid Build Coastguard Worker //     Predecessors according to CFG: BB#3
36*9880d681SAndroid Build Coastguard Worker //         %vreg11<def> = A2_addp %vreg6, %vreg10
37*9880d681SAndroid Build Coastguard Worker //         S2_storerd_io %vreg32, 16, %vreg11
38*9880d681SAndroid Build Coastguard Worker //     Successors according to CFG: BB#5
39*9880d681SAndroid Build Coastguard Worker //
40*9880d681SAndroid Build Coastguard Worker // BB#5: derived from LLVM BB %if.end
41*9880d681SAndroid Build Coastguard Worker //     Predecessors according to CFG: BB#3 BB#4
42*9880d681SAndroid Build Coastguard Worker //         %vreg12<def> = PHI %vreg6, <BB#3>, %vreg11, <BB#4>
43*9880d681SAndroid Build Coastguard Worker //         %vreg13<def> = A2_addp %vreg7, %vreg12
44*9880d681SAndroid Build Coastguard Worker //         %vreg42<def> = C2_cmpeqi %vreg9, 10
45*9880d681SAndroid Build Coastguard Worker //         J2_jumpf %vreg42<kill>, <BB#3>, %PC<imp-def,dead>
46*9880d681SAndroid Build Coastguard Worker //         J2_jump <BB#6>, %PC<imp-def,dead>
47*9880d681SAndroid Build Coastguard Worker //     Successors according to CFG: BB#6(4) BB#3(124)
48*9880d681SAndroid Build Coastguard Worker //
49*9880d681SAndroid Build Coastguard Worker // would become:
50*9880d681SAndroid Build Coastguard Worker //
51*9880d681SAndroid Build Coastguard Worker //         %vreg40<def> = L2_loadrub_io %vreg39<kill>, 1
52*9880d681SAndroid Build Coastguard Worker //         %vreg41<def> = S2_tstbit_i %vreg40<kill>, 0
53*9880d681SAndroid Build Coastguard Worker // spec->  %vreg11<def> = A2_addp %vreg6, %vreg10
54*9880d681SAndroid Build Coastguard Worker // pred->  S2_pstorerdf_io %vreg41, %vreg32, 16, %vreg11
55*9880d681SAndroid Build Coastguard Worker //         %vreg46<def> = MUX64_rr %vreg41, %vreg6, %vreg11
56*9880d681SAndroid Build Coastguard Worker //         %vreg13<def> = A2_addp %vreg7, %vreg46
57*9880d681SAndroid Build Coastguard Worker //         %vreg42<def> = C2_cmpeqi %vreg9, 10
58*9880d681SAndroid Build Coastguard Worker //         J2_jumpf %vreg42<kill>, <BB#3>, %PC<imp-def,dead>
59*9880d681SAndroid Build Coastguard Worker //         J2_jump <BB#6>, %PC<imp-def,dead>
60*9880d681SAndroid Build Coastguard Worker //     Successors according to CFG: BB#6 BB#3
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "hexagon-eif"
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseSet.h"
65*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
66*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
67*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
68*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
69*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
70*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
71*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
72*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
73*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
74*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
75*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
76*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
77*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetMachine.h"
78*9880d681SAndroid Build Coastguard Worker #include "HexagonTargetMachine.h"
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker #include <functional>
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker using namespace llvm;
83*9880d681SAndroid Build Coastguard Worker 
84*9880d681SAndroid Build Coastguard Worker namespace llvm {
85*9880d681SAndroid Build Coastguard Worker   FunctionPass *createHexagonEarlyIfConversion();
86*9880d681SAndroid Build Coastguard Worker   void initializeHexagonEarlyIfConversionPass(PassRegistry& Registry);
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker namespace {
90*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> EnableHexagonBP("enable-hexagon-br-prob", cl::Hidden,
91*9880d681SAndroid Build Coastguard Worker     cl::init(false), cl::desc("Enable branch probability info"));
92*9880d681SAndroid Build Coastguard Worker   cl::opt<unsigned> SizeLimit("eif-limit", cl::init(6), cl::Hidden,
93*9880d681SAndroid Build Coastguard Worker     cl::desc("Size limit in Hexagon early if-conversion"));
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   struct PrintMB {
PrintMB__anon319f89630111::PrintMB96*9880d681SAndroid Build Coastguard Worker     PrintMB(const MachineBasicBlock *B) : MB(B) {}
97*9880d681SAndroid Build Coastguard Worker     const MachineBasicBlock *MB;
98*9880d681SAndroid Build Coastguard Worker   };
operator <<(raw_ostream & OS,const PrintMB & P)99*9880d681SAndroid Build Coastguard Worker   raw_ostream &operator<< (raw_ostream &OS, const PrintMB &P) {
100*9880d681SAndroid Build Coastguard Worker     if (!P.MB)
101*9880d681SAndroid Build Coastguard Worker       return OS << "<none>";
102*9880d681SAndroid Build Coastguard Worker     return OS << '#' << P.MB->getNumber();
103*9880d681SAndroid Build Coastguard Worker   }
104*9880d681SAndroid Build Coastguard Worker 
105*9880d681SAndroid Build Coastguard Worker   struct FlowPattern {
FlowPattern__anon319f89630111::FlowPattern106*9880d681SAndroid Build Coastguard Worker     FlowPattern() : SplitB(0), TrueB(0), FalseB(0), JoinB(0), PredR(0) {}
FlowPattern__anon319f89630111::FlowPattern107*9880d681SAndroid Build Coastguard Worker     FlowPattern(MachineBasicBlock *B, unsigned PR, MachineBasicBlock *TB,
108*9880d681SAndroid Build Coastguard Worker           MachineBasicBlock *FB, MachineBasicBlock *JB)
109*9880d681SAndroid Build Coastguard Worker       : SplitB(B), TrueB(TB), FalseB(FB), JoinB(JB), PredR(PR) {}
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *SplitB;
112*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *TrueB, *FalseB, *JoinB;
113*9880d681SAndroid Build Coastguard Worker     unsigned PredR;
114*9880d681SAndroid Build Coastguard Worker   };
115*9880d681SAndroid Build Coastguard Worker   struct PrintFP {
PrintFP__anon319f89630111::PrintFP116*9880d681SAndroid Build Coastguard Worker     PrintFP(const FlowPattern &P, const TargetRegisterInfo &T)
117*9880d681SAndroid Build Coastguard Worker       : FP(P), TRI(T) {}
118*9880d681SAndroid Build Coastguard Worker     const FlowPattern &FP;
119*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo &TRI;
120*9880d681SAndroid Build Coastguard Worker     friend raw_ostream &operator<< (raw_ostream &OS, const PrintFP &P);
121*9880d681SAndroid Build Coastguard Worker   };
122*9880d681SAndroid Build Coastguard Worker   raw_ostream &operator<<(raw_ostream &OS,
123*9880d681SAndroid Build Coastguard Worker                           const PrintFP &P) LLVM_ATTRIBUTE_UNUSED;
operator <<(raw_ostream & OS,const PrintFP & P)124*9880d681SAndroid Build Coastguard Worker   raw_ostream &operator<<(raw_ostream &OS, const PrintFP &P) {
125*9880d681SAndroid Build Coastguard Worker     OS << "{ SplitB:" << PrintMB(P.FP.SplitB)
126*9880d681SAndroid Build Coastguard Worker        << ", PredR:" << PrintReg(P.FP.PredR, &P.TRI)
127*9880d681SAndroid Build Coastguard Worker        << ", TrueB:" << PrintMB(P.FP.TrueB) << ", FalseB:"
128*9880d681SAndroid Build Coastguard Worker        << PrintMB(P.FP.FalseB)
129*9880d681SAndroid Build Coastguard Worker        << ", JoinB:" << PrintMB(P.FP.JoinB) << " }";
130*9880d681SAndroid Build Coastguard Worker     return OS;
131*9880d681SAndroid Build Coastguard Worker   }
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker   class HexagonEarlyIfConversion : public MachineFunctionPass {
134*9880d681SAndroid Build Coastguard Worker   public:
135*9880d681SAndroid Build Coastguard Worker     static char ID;
HexagonEarlyIfConversion()136*9880d681SAndroid Build Coastguard Worker     HexagonEarlyIfConversion() : MachineFunctionPass(ID),
137*9880d681SAndroid Build Coastguard Worker         TII(0), TRI(0), MFN(0), MRI(0), MDT(0), MLI(0) {
138*9880d681SAndroid Build Coastguard Worker       initializeHexagonEarlyIfConversionPass(*PassRegistry::getPassRegistry());
139*9880d681SAndroid Build Coastguard Worker     }
getPassName() const140*9880d681SAndroid Build Coastguard Worker     const char *getPassName() const override {
141*9880d681SAndroid Build Coastguard Worker       return "Hexagon early if conversion";
142*9880d681SAndroid Build Coastguard Worker     }
getAnalysisUsage(AnalysisUsage & AU) const143*9880d681SAndroid Build Coastguard Worker     void getAnalysisUsage(AnalysisUsage &AU) const override {
144*9880d681SAndroid Build Coastguard Worker       AU.addRequired<MachineBranchProbabilityInfo>();
145*9880d681SAndroid Build Coastguard Worker       AU.addRequired<MachineDominatorTree>();
146*9880d681SAndroid Build Coastguard Worker       AU.addPreserved<MachineDominatorTree>();
147*9880d681SAndroid Build Coastguard Worker       AU.addRequired<MachineLoopInfo>();
148*9880d681SAndroid Build Coastguard Worker       MachineFunctionPass::getAnalysisUsage(AU);
149*9880d681SAndroid Build Coastguard Worker     }
150*9880d681SAndroid Build Coastguard Worker     bool runOnMachineFunction(MachineFunction &MF) override;
151*9880d681SAndroid Build Coastguard Worker 
152*9880d681SAndroid Build Coastguard Worker   private:
153*9880d681SAndroid Build Coastguard Worker     typedef DenseSet<MachineBasicBlock*> BlockSetType;
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker     bool isPreheader(const MachineBasicBlock *B) const;
156*9880d681SAndroid Build Coastguard Worker     bool matchFlowPattern(MachineBasicBlock *B, MachineLoop *L,
157*9880d681SAndroid Build Coastguard Worker           FlowPattern &FP);
158*9880d681SAndroid Build Coastguard Worker     bool visitBlock(MachineBasicBlock *B, MachineLoop *L);
159*9880d681SAndroid Build Coastguard Worker     bool visitLoop(MachineLoop *L);
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker     bool hasEHLabel(const MachineBasicBlock *B) const;
162*9880d681SAndroid Build Coastguard Worker     bool hasUncondBranch(const MachineBasicBlock *B) const;
163*9880d681SAndroid Build Coastguard Worker     bool isValidCandidate(const MachineBasicBlock *B) const;
164*9880d681SAndroid Build Coastguard Worker     bool usesUndefVReg(const MachineInstr *MI) const;
165*9880d681SAndroid Build Coastguard Worker     bool isValid(const FlowPattern &FP) const;
166*9880d681SAndroid Build Coastguard Worker     unsigned countPredicateDefs(const MachineBasicBlock *B) const;
167*9880d681SAndroid Build Coastguard Worker     unsigned computePhiCost(MachineBasicBlock *B) const;
168*9880d681SAndroid Build Coastguard Worker     bool isProfitable(const FlowPattern &FP) const;
169*9880d681SAndroid Build Coastguard Worker     bool isPredicableStore(const MachineInstr *MI) const;
170*9880d681SAndroid Build Coastguard Worker     bool isSafeToSpeculate(const MachineInstr *MI) const;
171*9880d681SAndroid Build Coastguard Worker 
172*9880d681SAndroid Build Coastguard Worker     unsigned getCondStoreOpcode(unsigned Opc, bool IfTrue) const;
173*9880d681SAndroid Build Coastguard Worker     void predicateInstr(MachineBasicBlock *ToB, MachineBasicBlock::iterator At,
174*9880d681SAndroid Build Coastguard Worker           MachineInstr *MI, unsigned PredR, bool IfTrue);
175*9880d681SAndroid Build Coastguard Worker     void predicateBlockNB(MachineBasicBlock *ToB,
176*9880d681SAndroid Build Coastguard Worker           MachineBasicBlock::iterator At, MachineBasicBlock *FromB,
177*9880d681SAndroid Build Coastguard Worker           unsigned PredR, bool IfTrue);
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker     void updatePhiNodes(MachineBasicBlock *WhereB, const FlowPattern &FP);
180*9880d681SAndroid Build Coastguard Worker     void convert(const FlowPattern &FP);
181*9880d681SAndroid Build Coastguard Worker 
182*9880d681SAndroid Build Coastguard Worker     void removeBlock(MachineBasicBlock *B);
183*9880d681SAndroid Build Coastguard Worker     void eliminatePhis(MachineBasicBlock *B);
184*9880d681SAndroid Build Coastguard Worker     void replacePhiEdges(MachineBasicBlock *OldB, MachineBasicBlock *NewB);
185*9880d681SAndroid Build Coastguard Worker     void mergeBlocks(MachineBasicBlock *PredB, MachineBasicBlock *SuccB);
186*9880d681SAndroid Build Coastguard Worker     void simplifyFlowGraph(const FlowPattern &FP);
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker     const TargetInstrInfo *TII;
189*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI;
190*9880d681SAndroid Build Coastguard Worker     MachineFunction *MFN;
191*9880d681SAndroid Build Coastguard Worker     MachineRegisterInfo *MRI;
192*9880d681SAndroid Build Coastguard Worker     MachineDominatorTree *MDT;
193*9880d681SAndroid Build Coastguard Worker     MachineLoopInfo *MLI;
194*9880d681SAndroid Build Coastguard Worker     BlockSetType Deleted;
195*9880d681SAndroid Build Coastguard Worker     const MachineBranchProbabilityInfo *MBPI;
196*9880d681SAndroid Build Coastguard Worker   };
197*9880d681SAndroid Build Coastguard Worker 
198*9880d681SAndroid Build Coastguard Worker   char HexagonEarlyIfConversion::ID = 0;
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(HexagonEarlyIfConversion, "hexagon-eif",
202*9880d681SAndroid Build Coastguard Worker   "Hexagon early if conversion", false, false)
203*9880d681SAndroid Build Coastguard Worker 
isPreheader(const MachineBasicBlock * B) const204*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::isPreheader(const MachineBasicBlock *B) const {
205*9880d681SAndroid Build Coastguard Worker   if (B->succ_size() != 1)
206*9880d681SAndroid Build Coastguard Worker     return false;
207*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *SB = *B->succ_begin();
208*9880d681SAndroid Build Coastguard Worker   MachineLoop *L = MLI->getLoopFor(SB);
209*9880d681SAndroid Build Coastguard Worker   return L && SB == L->getHeader();
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker 
212*9880d681SAndroid Build Coastguard Worker 
matchFlowPattern(MachineBasicBlock * B,MachineLoop * L,FlowPattern & FP)213*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::matchFlowPattern(MachineBasicBlock *B,
214*9880d681SAndroid Build Coastguard Worker     MachineLoop *L, FlowPattern &FP) {
215*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Checking flow pattern at BB#" << B->getNumber() << "\n");
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker   // Interested only in conditional branches, no .new, no new-value, etc.
218*9880d681SAndroid Build Coastguard Worker   // Check the terminators directly, it's easier than handling all responses
219*9880d681SAndroid Build Coastguard Worker   // from AnalyzeBranch.
220*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *TB = 0, *FB = 0;
221*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator T1I = B->getFirstTerminator();
222*9880d681SAndroid Build Coastguard Worker   if (T1I == B->end())
223*9880d681SAndroid Build Coastguard Worker     return false;
224*9880d681SAndroid Build Coastguard Worker   unsigned Opc = T1I->getOpcode();
225*9880d681SAndroid Build Coastguard Worker   if (Opc != Hexagon::J2_jumpt && Opc != Hexagon::J2_jumpf)
226*9880d681SAndroid Build Coastguard Worker     return false;
227*9880d681SAndroid Build Coastguard Worker   unsigned PredR = T1I->getOperand(0).getReg();
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker   // Get the layout successor, or 0 if B does not have one.
230*9880d681SAndroid Build Coastguard Worker   MachineFunction::iterator NextBI = std::next(MachineFunction::iterator(B));
231*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *NextB = (NextBI != MFN->end()) ? &*NextBI : 0;
232*9880d681SAndroid Build Coastguard Worker 
233*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *T1B = T1I->getOperand(1).getMBB();
234*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator T2I = std::next(T1I);
235*9880d681SAndroid Build Coastguard Worker   // The second terminator should be an unconditional branch.
236*9880d681SAndroid Build Coastguard Worker   assert(T2I == B->end() || T2I->getOpcode() == Hexagon::J2_jump);
237*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *T2B = (T2I == B->end()) ? NextB
238*9880d681SAndroid Build Coastguard Worker                                              : T2I->getOperand(0).getMBB();
239*9880d681SAndroid Build Coastguard Worker   if (T1B == T2B) {
240*9880d681SAndroid Build Coastguard Worker     // XXX merge if T1B == NextB, or convert branch to unconditional.
241*9880d681SAndroid Build Coastguard Worker     // mark as diamond with both sides equal?
242*9880d681SAndroid Build Coastguard Worker     return false;
243*9880d681SAndroid Build Coastguard Worker   }
244*9880d681SAndroid Build Coastguard Worker   // Loop could be null for both.
245*9880d681SAndroid Build Coastguard Worker   if (MLI->getLoopFor(T1B) != L || MLI->getLoopFor(T2B) != L)
246*9880d681SAndroid Build Coastguard Worker     return false;
247*9880d681SAndroid Build Coastguard Worker 
248*9880d681SAndroid Build Coastguard Worker   // Record the true/false blocks in such a way that "true" means "if (PredR)",
249*9880d681SAndroid Build Coastguard Worker   // and "false" means "if (!PredR)".
250*9880d681SAndroid Build Coastguard Worker   if (Opc == Hexagon::J2_jumpt)
251*9880d681SAndroid Build Coastguard Worker     TB = T1B, FB = T2B;
252*9880d681SAndroid Build Coastguard Worker   else
253*9880d681SAndroid Build Coastguard Worker     TB = T2B, FB = T1B;
254*9880d681SAndroid Build Coastguard Worker 
255*9880d681SAndroid Build Coastguard Worker   if (!MDT->properlyDominates(B, TB) || !MDT->properlyDominates(B, FB))
256*9880d681SAndroid Build Coastguard Worker     return false;
257*9880d681SAndroid Build Coastguard Worker 
258*9880d681SAndroid Build Coastguard Worker   // Detect triangle first. In case of a triangle, one of the blocks TB/FB
259*9880d681SAndroid Build Coastguard Worker   // can fall through into the other, in other words, it will be executed
260*9880d681SAndroid Build Coastguard Worker   // in both cases. We only want to predicate the block that is executed
261*9880d681SAndroid Build Coastguard Worker   // conditionally.
262*9880d681SAndroid Build Coastguard Worker   unsigned TNP = TB->pred_size(), FNP = FB->pred_size();
263*9880d681SAndroid Build Coastguard Worker   unsigned TNS = TB->succ_size(), FNS = FB->succ_size();
264*9880d681SAndroid Build Coastguard Worker 
265*9880d681SAndroid Build Coastguard Worker   // A block is predicable if it has one predecessor (it must be B), and
266*9880d681SAndroid Build Coastguard Worker   // it has a single successor. In fact, the block has to end either with
267*9880d681SAndroid Build Coastguard Worker   // an unconditional branch (which can be predicated), or with a fall-
268*9880d681SAndroid Build Coastguard Worker   // through.
269*9880d681SAndroid Build Coastguard Worker   bool TOk = (TNP == 1) && (TNS == 1);
270*9880d681SAndroid Build Coastguard Worker   bool FOk = (FNP == 1) && (FNS == 1);
271*9880d681SAndroid Build Coastguard Worker 
272*9880d681SAndroid Build Coastguard Worker   // If neither is predicable, there is nothing interesting.
273*9880d681SAndroid Build Coastguard Worker   if (!TOk && !FOk)
274*9880d681SAndroid Build Coastguard Worker     return false;
275*9880d681SAndroid Build Coastguard Worker 
276*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *TSB = (TNS > 0) ? *TB->succ_begin() : 0;
277*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *FSB = (FNS > 0) ? *FB->succ_begin() : 0;
278*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *JB = 0;
279*9880d681SAndroid Build Coastguard Worker 
280*9880d681SAndroid Build Coastguard Worker   if (TOk) {
281*9880d681SAndroid Build Coastguard Worker     if (FOk) {
282*9880d681SAndroid Build Coastguard Worker       if (TSB == FSB)
283*9880d681SAndroid Build Coastguard Worker         JB = TSB;
284*9880d681SAndroid Build Coastguard Worker       // Diamond: "if (P) then TB; else FB;".
285*9880d681SAndroid Build Coastguard Worker     } else {
286*9880d681SAndroid Build Coastguard Worker       // TOk && !FOk
287*9880d681SAndroid Build Coastguard Worker       if (TSB == FB) {
288*9880d681SAndroid Build Coastguard Worker         JB = FB;
289*9880d681SAndroid Build Coastguard Worker         FB = 0;
290*9880d681SAndroid Build Coastguard Worker       }
291*9880d681SAndroid Build Coastguard Worker     }
292*9880d681SAndroid Build Coastguard Worker   } else {
293*9880d681SAndroid Build Coastguard Worker     // !TOk && FOk  (at least one must be true by now).
294*9880d681SAndroid Build Coastguard Worker     if (FSB == TB) {
295*9880d681SAndroid Build Coastguard Worker       JB = TB;
296*9880d681SAndroid Build Coastguard Worker       TB = 0;
297*9880d681SAndroid Build Coastguard Worker     }
298*9880d681SAndroid Build Coastguard Worker   }
299*9880d681SAndroid Build Coastguard Worker   // Don't try to predicate loop preheaders.
300*9880d681SAndroid Build Coastguard Worker   if ((TB && isPreheader(TB)) || (FB && isPreheader(FB))) {
301*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "One of blocks " << PrintMB(TB) << ", " << PrintMB(FB)
302*9880d681SAndroid Build Coastguard Worker                  << " is a loop preheader. Skipping.\n");
303*9880d681SAndroid Build Coastguard Worker     return false;
304*9880d681SAndroid Build Coastguard Worker   }
305*9880d681SAndroid Build Coastguard Worker 
306*9880d681SAndroid Build Coastguard Worker   FP = FlowPattern(B, PredR, TB, FB, JB);
307*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Detected " << PrintFP(FP, *TRI) << "\n");
308*9880d681SAndroid Build Coastguard Worker   return true;
309*9880d681SAndroid Build Coastguard Worker }
310*9880d681SAndroid Build Coastguard Worker 
311*9880d681SAndroid Build Coastguard Worker 
312*9880d681SAndroid Build Coastguard Worker // KLUDGE: HexagonInstrInfo::AnalyzeBranch won't work on a block that
313*9880d681SAndroid Build Coastguard Worker // contains EH_LABEL.
hasEHLabel(const MachineBasicBlock * B) const314*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::hasEHLabel(const MachineBasicBlock *B) const {
315*9880d681SAndroid Build Coastguard Worker   for (auto &I : *B)
316*9880d681SAndroid Build Coastguard Worker     if (I.isEHLabel())
317*9880d681SAndroid Build Coastguard Worker       return true;
318*9880d681SAndroid Build Coastguard Worker   return false;
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker 
321*9880d681SAndroid Build Coastguard Worker 
322*9880d681SAndroid Build Coastguard Worker // KLUDGE: HexagonInstrInfo::AnalyzeBranch may be unable to recognize
323*9880d681SAndroid Build Coastguard Worker // that a block can never fall-through.
hasUncondBranch(const MachineBasicBlock * B) const324*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::hasUncondBranch(const MachineBasicBlock *B)
325*9880d681SAndroid Build Coastguard Worker       const {
326*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
327*9880d681SAndroid Build Coastguard Worker   while (I != E) {
328*9880d681SAndroid Build Coastguard Worker     if (I->isBarrier())
329*9880d681SAndroid Build Coastguard Worker       return true;
330*9880d681SAndroid Build Coastguard Worker     ++I;
331*9880d681SAndroid Build Coastguard Worker   }
332*9880d681SAndroid Build Coastguard Worker   return false;
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker 
335*9880d681SAndroid Build Coastguard Worker 
isValidCandidate(const MachineBasicBlock * B) const336*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::isValidCandidate(const MachineBasicBlock *B)
337*9880d681SAndroid Build Coastguard Worker       const {
338*9880d681SAndroid Build Coastguard Worker   if (!B)
339*9880d681SAndroid Build Coastguard Worker     return true;
340*9880d681SAndroid Build Coastguard Worker   if (B->isEHPad() || B->hasAddressTaken())
341*9880d681SAndroid Build Coastguard Worker     return false;
342*9880d681SAndroid Build Coastguard Worker   if (B->succ_size() == 0)
343*9880d681SAndroid Build Coastguard Worker     return false;
344*9880d681SAndroid Build Coastguard Worker 
345*9880d681SAndroid Build Coastguard Worker   for (auto &MI : *B) {
346*9880d681SAndroid Build Coastguard Worker     if (MI.isDebugValue())
347*9880d681SAndroid Build Coastguard Worker       continue;
348*9880d681SAndroid Build Coastguard Worker     if (MI.isConditionalBranch())
349*9880d681SAndroid Build Coastguard Worker       return false;
350*9880d681SAndroid Build Coastguard Worker     unsigned Opc = MI.getOpcode();
351*9880d681SAndroid Build Coastguard Worker     bool IsJMP = (Opc == Hexagon::J2_jump);
352*9880d681SAndroid Build Coastguard Worker     if (!isPredicableStore(&MI) && !IsJMP && !isSafeToSpeculate(&MI))
353*9880d681SAndroid Build Coastguard Worker       return false;
354*9880d681SAndroid Build Coastguard Worker     // Look for predicate registers defined by this instruction. It's ok
355*9880d681SAndroid Build Coastguard Worker     // to speculate such an instruction, but the predicate register cannot
356*9880d681SAndroid Build Coastguard Worker     // be used outside of this block (or else it won't be possible to
357*9880d681SAndroid Build Coastguard Worker     // update the use of it after predication). PHI uses will be updated
358*9880d681SAndroid Build Coastguard Worker     // to use a result of a MUX, and a MUX cannot be created for predicate
359*9880d681SAndroid Build Coastguard Worker     // registers.
360*9880d681SAndroid Build Coastguard Worker     for (ConstMIOperands MO(MI); MO.isValid(); ++MO) {
361*9880d681SAndroid Build Coastguard Worker       if (!MO->isReg() || !MO->isDef())
362*9880d681SAndroid Build Coastguard Worker         continue;
363*9880d681SAndroid Build Coastguard Worker       unsigned R = MO->getReg();
364*9880d681SAndroid Build Coastguard Worker       if (!TargetRegisterInfo::isVirtualRegister(R))
365*9880d681SAndroid Build Coastguard Worker         continue;
366*9880d681SAndroid Build Coastguard Worker       if (MRI->getRegClass(R) != &Hexagon::PredRegsRegClass)
367*9880d681SAndroid Build Coastguard Worker         continue;
368*9880d681SAndroid Build Coastguard Worker       for (auto U = MRI->use_begin(R); U != MRI->use_end(); ++U)
369*9880d681SAndroid Build Coastguard Worker         if (U->getParent()->isPHI())
370*9880d681SAndroid Build Coastguard Worker           return false;
371*9880d681SAndroid Build Coastguard Worker     }
372*9880d681SAndroid Build Coastguard Worker   }
373*9880d681SAndroid Build Coastguard Worker   return true;
374*9880d681SAndroid Build Coastguard Worker }
375*9880d681SAndroid Build Coastguard Worker 
376*9880d681SAndroid Build Coastguard Worker 
usesUndefVReg(const MachineInstr * MI) const377*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::usesUndefVReg(const MachineInstr *MI) const {
378*9880d681SAndroid Build Coastguard Worker   for (ConstMIOperands MO(*MI); MO.isValid(); ++MO) {
379*9880d681SAndroid Build Coastguard Worker     if (!MO->isReg() || !MO->isUse())
380*9880d681SAndroid Build Coastguard Worker       continue;
381*9880d681SAndroid Build Coastguard Worker     unsigned R = MO->getReg();
382*9880d681SAndroid Build Coastguard Worker     if (!TargetRegisterInfo::isVirtualRegister(R))
383*9880d681SAndroid Build Coastguard Worker       continue;
384*9880d681SAndroid Build Coastguard Worker     const MachineInstr *DefI = MRI->getVRegDef(R);
385*9880d681SAndroid Build Coastguard Worker     // "Undefined" virtual registers are actually defined via IMPLICIT_DEF.
386*9880d681SAndroid Build Coastguard Worker     assert(DefI && "Expecting a reaching def in MRI");
387*9880d681SAndroid Build Coastguard Worker     if (DefI->isImplicitDef())
388*9880d681SAndroid Build Coastguard Worker       return true;
389*9880d681SAndroid Build Coastguard Worker   }
390*9880d681SAndroid Build Coastguard Worker   return false;
391*9880d681SAndroid Build Coastguard Worker }
392*9880d681SAndroid Build Coastguard Worker 
393*9880d681SAndroid Build Coastguard Worker 
isValid(const FlowPattern & FP) const394*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::isValid(const FlowPattern &FP) const {
395*9880d681SAndroid Build Coastguard Worker   if (hasEHLabel(FP.SplitB))  // KLUDGE: see function definition
396*9880d681SAndroid Build Coastguard Worker     return false;
397*9880d681SAndroid Build Coastguard Worker   if (FP.TrueB && !isValidCandidate(FP.TrueB))
398*9880d681SAndroid Build Coastguard Worker     return false;
399*9880d681SAndroid Build Coastguard Worker   if (FP.FalseB && !isValidCandidate(FP.FalseB))
400*9880d681SAndroid Build Coastguard Worker     return false;
401*9880d681SAndroid Build Coastguard Worker   // Check the PHIs in the join block. If any of them use a register
402*9880d681SAndroid Build Coastguard Worker   // that is defined as IMPLICIT_DEF, do not convert this. This can
403*9880d681SAndroid Build Coastguard Worker   // legitimately happen if one side of the split never executes, but
404*9880d681SAndroid Build Coastguard Worker   // the compiler is unable to prove it. That side may then seem to
405*9880d681SAndroid Build Coastguard Worker   // provide an "undef" value to the join block, however it will never
406*9880d681SAndroid Build Coastguard Worker   // execute at run-time. If we convert this case, the "undef" will
407*9880d681SAndroid Build Coastguard Worker   // be used in a MUX instruction, and that may seem like actually
408*9880d681SAndroid Build Coastguard Worker   // using an undefined value to other optimizations. This could lead
409*9880d681SAndroid Build Coastguard Worker   // to trouble further down the optimization stream, cause assertions
410*9880d681SAndroid Build Coastguard Worker   // to fail, etc.
411*9880d681SAndroid Build Coastguard Worker   if (FP.JoinB) {
412*9880d681SAndroid Build Coastguard Worker     const MachineBasicBlock &B = *FP.JoinB;
413*9880d681SAndroid Build Coastguard Worker     for (auto &MI : B) {
414*9880d681SAndroid Build Coastguard Worker       if (!MI.isPHI())
415*9880d681SAndroid Build Coastguard Worker         break;
416*9880d681SAndroid Build Coastguard Worker       if (usesUndefVReg(&MI))
417*9880d681SAndroid Build Coastguard Worker         return false;
418*9880d681SAndroid Build Coastguard Worker       unsigned DefR = MI.getOperand(0).getReg();
419*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass *RC = MRI->getRegClass(DefR);
420*9880d681SAndroid Build Coastguard Worker       if (RC == &Hexagon::PredRegsRegClass)
421*9880d681SAndroid Build Coastguard Worker         return false;
422*9880d681SAndroid Build Coastguard Worker     }
423*9880d681SAndroid Build Coastguard Worker   }
424*9880d681SAndroid Build Coastguard Worker   return true;
425*9880d681SAndroid Build Coastguard Worker }
426*9880d681SAndroid Build Coastguard Worker 
427*9880d681SAndroid Build Coastguard Worker 
computePhiCost(MachineBasicBlock * B) const428*9880d681SAndroid Build Coastguard Worker unsigned HexagonEarlyIfConversion::computePhiCost(MachineBasicBlock *B) const {
429*9880d681SAndroid Build Coastguard Worker   assert(B->pred_size() <= 2);
430*9880d681SAndroid Build Coastguard Worker   if (B->pred_size() < 2)
431*9880d681SAndroid Build Coastguard Worker     return 0;
432*9880d681SAndroid Build Coastguard Worker 
433*9880d681SAndroid Build Coastguard Worker   unsigned Cost = 0;
434*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator I, E = B->getFirstNonPHI();
435*9880d681SAndroid Build Coastguard Worker   for (I = B->begin(); I != E; ++I) {
436*9880d681SAndroid Build Coastguard Worker     const MachineOperand &RO1 = I->getOperand(1);
437*9880d681SAndroid Build Coastguard Worker     const MachineOperand &RO3 = I->getOperand(3);
438*9880d681SAndroid Build Coastguard Worker     assert(RO1.isReg() && RO3.isReg());
439*9880d681SAndroid Build Coastguard Worker     // Must have a MUX if the phi uses a subregister.
440*9880d681SAndroid Build Coastguard Worker     if (RO1.getSubReg() != 0 || RO3.getSubReg() != 0) {
441*9880d681SAndroid Build Coastguard Worker       Cost++;
442*9880d681SAndroid Build Coastguard Worker       continue;
443*9880d681SAndroid Build Coastguard Worker     }
444*9880d681SAndroid Build Coastguard Worker     MachineInstr *Def1 = MRI->getVRegDef(RO1.getReg());
445*9880d681SAndroid Build Coastguard Worker     MachineInstr *Def3 = MRI->getVRegDef(RO3.getReg());
446*9880d681SAndroid Build Coastguard Worker     if (!TII->isPredicable(*Def1) || !TII->isPredicable(*Def3))
447*9880d681SAndroid Build Coastguard Worker       Cost++;
448*9880d681SAndroid Build Coastguard Worker   }
449*9880d681SAndroid Build Coastguard Worker   return Cost;
450*9880d681SAndroid Build Coastguard Worker }
451*9880d681SAndroid Build Coastguard Worker 
452*9880d681SAndroid Build Coastguard Worker 
countPredicateDefs(const MachineBasicBlock * B) const453*9880d681SAndroid Build Coastguard Worker unsigned HexagonEarlyIfConversion::countPredicateDefs(
454*9880d681SAndroid Build Coastguard Worker       const MachineBasicBlock *B) const {
455*9880d681SAndroid Build Coastguard Worker   unsigned PredDefs = 0;
456*9880d681SAndroid Build Coastguard Worker   for (auto &MI : *B) {
457*9880d681SAndroid Build Coastguard Worker     for (ConstMIOperands MO(MI); MO.isValid(); ++MO) {
458*9880d681SAndroid Build Coastguard Worker       if (!MO->isReg() || !MO->isDef())
459*9880d681SAndroid Build Coastguard Worker         continue;
460*9880d681SAndroid Build Coastguard Worker       unsigned R = MO->getReg();
461*9880d681SAndroid Build Coastguard Worker       if (!TargetRegisterInfo::isVirtualRegister(R))
462*9880d681SAndroid Build Coastguard Worker         continue;
463*9880d681SAndroid Build Coastguard Worker       if (MRI->getRegClass(R) == &Hexagon::PredRegsRegClass)
464*9880d681SAndroid Build Coastguard Worker         PredDefs++;
465*9880d681SAndroid Build Coastguard Worker     }
466*9880d681SAndroid Build Coastguard Worker   }
467*9880d681SAndroid Build Coastguard Worker   return PredDefs;
468*9880d681SAndroid Build Coastguard Worker }
469*9880d681SAndroid Build Coastguard Worker 
470*9880d681SAndroid Build Coastguard Worker 
isProfitable(const FlowPattern & FP) const471*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::isProfitable(const FlowPattern &FP) const {
472*9880d681SAndroid Build Coastguard Worker   if (FP.TrueB && FP.FalseB) {
473*9880d681SAndroid Build Coastguard Worker 
474*9880d681SAndroid Build Coastguard Worker     // Do not IfCovert if the branch is one sided.
475*9880d681SAndroid Build Coastguard Worker     if (MBPI) {
476*9880d681SAndroid Build Coastguard Worker       BranchProbability Prob(9, 10);
477*9880d681SAndroid Build Coastguard Worker       if (MBPI->getEdgeProbability(FP.SplitB, FP.TrueB) > Prob)
478*9880d681SAndroid Build Coastguard Worker         return false;
479*9880d681SAndroid Build Coastguard Worker       if (MBPI->getEdgeProbability(FP.SplitB, FP.FalseB) > Prob)
480*9880d681SAndroid Build Coastguard Worker         return false;
481*9880d681SAndroid Build Coastguard Worker     }
482*9880d681SAndroid Build Coastguard Worker 
483*9880d681SAndroid Build Coastguard Worker     // If both sides are predicable, convert them if they join, and the
484*9880d681SAndroid Build Coastguard Worker     // join block has no other predecessors.
485*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *TSB = *FP.TrueB->succ_begin();
486*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *FSB = *FP.FalseB->succ_begin();
487*9880d681SAndroid Build Coastguard Worker     if (TSB != FSB)
488*9880d681SAndroid Build Coastguard Worker       return false;
489*9880d681SAndroid Build Coastguard Worker     if (TSB->pred_size() != 2)
490*9880d681SAndroid Build Coastguard Worker       return false;
491*9880d681SAndroid Build Coastguard Worker   }
492*9880d681SAndroid Build Coastguard Worker 
493*9880d681SAndroid Build Coastguard Worker   // Calculate the total size of the predicated blocks.
494*9880d681SAndroid Build Coastguard Worker   // Assume instruction counts without branches to be the approximation of
495*9880d681SAndroid Build Coastguard Worker   // the code size. If the predicated blocks are smaller than a packet size,
496*9880d681SAndroid Build Coastguard Worker   // approximate the spare room in the packet that could be filled with the
497*9880d681SAndroid Build Coastguard Worker   // predicated/speculated instructions.
498*9880d681SAndroid Build Coastguard Worker   unsigned TS = 0, FS = 0, Spare = 0;
499*9880d681SAndroid Build Coastguard Worker   if (FP.TrueB) {
500*9880d681SAndroid Build Coastguard Worker     TS = std::distance(FP.TrueB->begin(), FP.TrueB->getFirstTerminator());
501*9880d681SAndroid Build Coastguard Worker     if (TS < HEXAGON_PACKET_SIZE)
502*9880d681SAndroid Build Coastguard Worker       Spare += HEXAGON_PACKET_SIZE-TS;
503*9880d681SAndroid Build Coastguard Worker   }
504*9880d681SAndroid Build Coastguard Worker   if (FP.FalseB) {
505*9880d681SAndroid Build Coastguard Worker     FS = std::distance(FP.FalseB->begin(), FP.FalseB->getFirstTerminator());
506*9880d681SAndroid Build Coastguard Worker     if (FS < HEXAGON_PACKET_SIZE)
507*9880d681SAndroid Build Coastguard Worker       Spare += HEXAGON_PACKET_SIZE-TS;
508*9880d681SAndroid Build Coastguard Worker   }
509*9880d681SAndroid Build Coastguard Worker   unsigned TotalIn = TS+FS;
510*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Total number of instructions to be predicated/speculated: "
511*9880d681SAndroid Build Coastguard Worker                << TotalIn << ", spare room: " << Spare << "\n");
512*9880d681SAndroid Build Coastguard Worker   if (TotalIn >= SizeLimit+Spare)
513*9880d681SAndroid Build Coastguard Worker     return false;
514*9880d681SAndroid Build Coastguard Worker 
515*9880d681SAndroid Build Coastguard Worker   // Count the number of PHI nodes that will need to be updated (converted
516*9880d681SAndroid Build Coastguard Worker   // to MUX). Those can be later converted to predicated instructions, so
517*9880d681SAndroid Build Coastguard Worker   // they aren't always adding extra cost.
518*9880d681SAndroid Build Coastguard Worker   // KLUDGE: Also, count the number of predicate register definitions in
519*9880d681SAndroid Build Coastguard Worker   // each block. The scheduler may increase the pressure of these and cause
520*9880d681SAndroid Build Coastguard Worker   // expensive spills (e.g. bitmnp01).
521*9880d681SAndroid Build Coastguard Worker   unsigned TotalPh = 0;
522*9880d681SAndroid Build Coastguard Worker   unsigned PredDefs = countPredicateDefs(FP.SplitB);
523*9880d681SAndroid Build Coastguard Worker   if (FP.JoinB) {
524*9880d681SAndroid Build Coastguard Worker     TotalPh = computePhiCost(FP.JoinB);
525*9880d681SAndroid Build Coastguard Worker     PredDefs += countPredicateDefs(FP.JoinB);
526*9880d681SAndroid Build Coastguard Worker   } else {
527*9880d681SAndroid Build Coastguard Worker     if (FP.TrueB && FP.TrueB->succ_size() > 0) {
528*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *SB = *FP.TrueB->succ_begin();
529*9880d681SAndroid Build Coastguard Worker       TotalPh += computePhiCost(SB);
530*9880d681SAndroid Build Coastguard Worker       PredDefs += countPredicateDefs(SB);
531*9880d681SAndroid Build Coastguard Worker     }
532*9880d681SAndroid Build Coastguard Worker     if (FP.FalseB && FP.FalseB->succ_size() > 0) {
533*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *SB = *FP.FalseB->succ_begin();
534*9880d681SAndroid Build Coastguard Worker       TotalPh += computePhiCost(SB);
535*9880d681SAndroid Build Coastguard Worker       PredDefs += countPredicateDefs(SB);
536*9880d681SAndroid Build Coastguard Worker     }
537*9880d681SAndroid Build Coastguard Worker   }
538*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Total number of extra muxes from converted phis: "
539*9880d681SAndroid Build Coastguard Worker                << TotalPh << "\n");
540*9880d681SAndroid Build Coastguard Worker   if (TotalIn+TotalPh >= SizeLimit+Spare)
541*9880d681SAndroid Build Coastguard Worker     return false;
542*9880d681SAndroid Build Coastguard Worker 
543*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Total number of predicate registers: " << PredDefs << "\n");
544*9880d681SAndroid Build Coastguard Worker   if (PredDefs > 4)
545*9880d681SAndroid Build Coastguard Worker     return false;
546*9880d681SAndroid Build Coastguard Worker 
547*9880d681SAndroid Build Coastguard Worker   return true;
548*9880d681SAndroid Build Coastguard Worker }
549*9880d681SAndroid Build Coastguard Worker 
550*9880d681SAndroid Build Coastguard Worker 
visitBlock(MachineBasicBlock * B,MachineLoop * L)551*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::visitBlock(MachineBasicBlock *B,
552*9880d681SAndroid Build Coastguard Worker       MachineLoop *L) {
553*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
554*9880d681SAndroid Build Coastguard Worker 
555*9880d681SAndroid Build Coastguard Worker   // Visit all dominated blocks from the same loop first, then process B.
556*9880d681SAndroid Build Coastguard Worker   MachineDomTreeNode *N = MDT->getNode(B);
557*9880d681SAndroid Build Coastguard Worker   typedef GraphTraits<MachineDomTreeNode*> GTN;
558*9880d681SAndroid Build Coastguard Worker   // We will change CFG/DT during this traversal, so take precautions to
559*9880d681SAndroid Build Coastguard Worker   // avoid problems related to invalidated iterators. In fact, processing
560*9880d681SAndroid Build Coastguard Worker   // a child C of B cannot cause another child to be removed, but it can
561*9880d681SAndroid Build Coastguard Worker   // cause a new child to be added (which was a child of C before C itself
562*9880d681SAndroid Build Coastguard Worker   // was removed. This new child C, however, would have been processed
563*9880d681SAndroid Build Coastguard Worker   // prior to processing B, so there is no need to process it again.
564*9880d681SAndroid Build Coastguard Worker   // Simply keep a list of children of B, and traverse that list.
565*9880d681SAndroid Build Coastguard Worker   typedef SmallVector<MachineDomTreeNode*,4> DTNodeVectType;
566*9880d681SAndroid Build Coastguard Worker   DTNodeVectType Cn(GTN::child_begin(N), GTN::child_end(N));
567*9880d681SAndroid Build Coastguard Worker   for (DTNodeVectType::iterator I = Cn.begin(), E = Cn.end(); I != E; ++I) {
568*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *SB = (*I)->getBlock();
569*9880d681SAndroid Build Coastguard Worker     if (!Deleted.count(SB))
570*9880d681SAndroid Build Coastguard Worker       Changed |= visitBlock(SB, L);
571*9880d681SAndroid Build Coastguard Worker   }
572*9880d681SAndroid Build Coastguard Worker   // When walking down the dominator tree, we want to traverse through
573*9880d681SAndroid Build Coastguard Worker   // blocks from nested (other) loops, because they can dominate blocks
574*9880d681SAndroid Build Coastguard Worker   // that are in L. Skip the non-L blocks only after the tree traversal.
575*9880d681SAndroid Build Coastguard Worker   if (MLI->getLoopFor(B) != L)
576*9880d681SAndroid Build Coastguard Worker     return Changed;
577*9880d681SAndroid Build Coastguard Worker 
578*9880d681SAndroid Build Coastguard Worker   FlowPattern FP;
579*9880d681SAndroid Build Coastguard Worker   if (!matchFlowPattern(B, L, FP))
580*9880d681SAndroid Build Coastguard Worker     return Changed;
581*9880d681SAndroid Build Coastguard Worker 
582*9880d681SAndroid Build Coastguard Worker   if (!isValid(FP)) {
583*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Conversion is not valid\n");
584*9880d681SAndroid Build Coastguard Worker     return Changed;
585*9880d681SAndroid Build Coastguard Worker   }
586*9880d681SAndroid Build Coastguard Worker   if (!isProfitable(FP)) {
587*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Conversion is not profitable\n");
588*9880d681SAndroid Build Coastguard Worker     return Changed;
589*9880d681SAndroid Build Coastguard Worker   }
590*9880d681SAndroid Build Coastguard Worker 
591*9880d681SAndroid Build Coastguard Worker   convert(FP);
592*9880d681SAndroid Build Coastguard Worker   simplifyFlowGraph(FP);
593*9880d681SAndroid Build Coastguard Worker   return true;
594*9880d681SAndroid Build Coastguard Worker }
595*9880d681SAndroid Build Coastguard Worker 
596*9880d681SAndroid Build Coastguard Worker 
visitLoop(MachineLoop * L)597*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::visitLoop(MachineLoop *L) {
598*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *HB = L ? L->getHeader() : 0;
599*9880d681SAndroid Build Coastguard Worker   DEBUG((L ? dbgs() << "Visiting loop H:" << PrintMB(HB)
600*9880d681SAndroid Build Coastguard Worker            : dbgs() << "Visiting function") << "\n");
601*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
602*9880d681SAndroid Build Coastguard Worker   if (L) {
603*9880d681SAndroid Build Coastguard Worker     for (MachineLoop::iterator I = L->begin(), E = L->end(); I != E; ++I)
604*9880d681SAndroid Build Coastguard Worker       Changed |= visitLoop(*I);
605*9880d681SAndroid Build Coastguard Worker   }
606*9880d681SAndroid Build Coastguard Worker 
607*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *EntryB = GraphTraits<MachineFunction*>::getEntryNode(MFN);
608*9880d681SAndroid Build Coastguard Worker   Changed |= visitBlock(L ? HB : EntryB, L);
609*9880d681SAndroid Build Coastguard Worker   return Changed;
610*9880d681SAndroid Build Coastguard Worker }
611*9880d681SAndroid Build Coastguard Worker 
612*9880d681SAndroid Build Coastguard Worker 
isPredicableStore(const MachineInstr * MI) const613*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::isPredicableStore(const MachineInstr *MI)
614*9880d681SAndroid Build Coastguard Worker       const {
615*9880d681SAndroid Build Coastguard Worker   // Exclude post-increment stores. Those return a value, so we cannot
616*9880d681SAndroid Build Coastguard Worker   // predicate them.
617*9880d681SAndroid Build Coastguard Worker   unsigned Opc = MI->getOpcode();
618*9880d681SAndroid Build Coastguard Worker   using namespace Hexagon;
619*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
620*9880d681SAndroid Build Coastguard Worker     // Store byte:
621*9880d681SAndroid Build Coastguard Worker     case S2_storerb_io: case S4_storerb_rr:
622*9880d681SAndroid Build Coastguard Worker     case S2_storerbabs: case S4_storeirb_io:  case S2_storerbgp:
623*9880d681SAndroid Build Coastguard Worker     // Store halfword:
624*9880d681SAndroid Build Coastguard Worker     case S2_storerh_io: case S4_storerh_rr:
625*9880d681SAndroid Build Coastguard Worker     case S2_storerhabs: case S4_storeirh_io:  case S2_storerhgp:
626*9880d681SAndroid Build Coastguard Worker     // Store upper halfword:
627*9880d681SAndroid Build Coastguard Worker     case S2_storerf_io: case S4_storerf_rr:
628*9880d681SAndroid Build Coastguard Worker     case S2_storerfabs: case S2_storerfgp:
629*9880d681SAndroid Build Coastguard Worker     // Store word:
630*9880d681SAndroid Build Coastguard Worker     case S2_storeri_io: case S4_storeri_rr:
631*9880d681SAndroid Build Coastguard Worker     case S2_storeriabs: case S4_storeiri_io:  case S2_storerigp:
632*9880d681SAndroid Build Coastguard Worker     // Store doubleword:
633*9880d681SAndroid Build Coastguard Worker     case S2_storerd_io: case S4_storerd_rr:
634*9880d681SAndroid Build Coastguard Worker     case S2_storerdabs: case S2_storerdgp:
635*9880d681SAndroid Build Coastguard Worker       return true;
636*9880d681SAndroid Build Coastguard Worker   }
637*9880d681SAndroid Build Coastguard Worker   return false;
638*9880d681SAndroid Build Coastguard Worker }
639*9880d681SAndroid Build Coastguard Worker 
640*9880d681SAndroid Build Coastguard Worker 
isSafeToSpeculate(const MachineInstr * MI) const641*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::isSafeToSpeculate(const MachineInstr *MI)
642*9880d681SAndroid Build Coastguard Worker       const {
643*9880d681SAndroid Build Coastguard Worker   if (MI->mayLoad() || MI->mayStore())
644*9880d681SAndroid Build Coastguard Worker     return false;
645*9880d681SAndroid Build Coastguard Worker   if (MI->isCall() || MI->isBarrier() || MI->isBranch())
646*9880d681SAndroid Build Coastguard Worker     return false;
647*9880d681SAndroid Build Coastguard Worker   if (MI->hasUnmodeledSideEffects())
648*9880d681SAndroid Build Coastguard Worker     return false;
649*9880d681SAndroid Build Coastguard Worker 
650*9880d681SAndroid Build Coastguard Worker   return true;
651*9880d681SAndroid Build Coastguard Worker }
652*9880d681SAndroid Build Coastguard Worker 
653*9880d681SAndroid Build Coastguard Worker 
getCondStoreOpcode(unsigned Opc,bool IfTrue) const654*9880d681SAndroid Build Coastguard Worker unsigned HexagonEarlyIfConversion::getCondStoreOpcode(unsigned Opc,
655*9880d681SAndroid Build Coastguard Worker       bool IfTrue) const {
656*9880d681SAndroid Build Coastguard Worker   // Exclude post-increment stores.
657*9880d681SAndroid Build Coastguard Worker   using namespace Hexagon;
658*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
659*9880d681SAndroid Build Coastguard Worker     case S2_storerb_io:
660*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S2_pstorerbt_io : S2_pstorerbf_io;
661*9880d681SAndroid Build Coastguard Worker     case S4_storerb_rr:
662*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerbt_rr : S4_pstorerbf_rr;
663*9880d681SAndroid Build Coastguard Worker     case S2_storerbabs:
664*9880d681SAndroid Build Coastguard Worker     case S2_storerbgp:
665*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerbt_abs : S4_pstorerbf_abs;
666*9880d681SAndroid Build Coastguard Worker     case S4_storeirb_io:
667*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_storeirbt_io : S4_storeirbf_io;
668*9880d681SAndroid Build Coastguard Worker     case S2_storerh_io:
669*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S2_pstorerht_io : S2_pstorerhf_io;
670*9880d681SAndroid Build Coastguard Worker     case S4_storerh_rr:
671*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerht_rr : S4_pstorerhf_rr;
672*9880d681SAndroid Build Coastguard Worker     case S2_storerhabs:
673*9880d681SAndroid Build Coastguard Worker     case S2_storerhgp:
674*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerht_abs : S4_pstorerhf_abs;
675*9880d681SAndroid Build Coastguard Worker     case S2_storerf_io:
676*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S2_pstorerft_io : S2_pstorerff_io;
677*9880d681SAndroid Build Coastguard Worker     case S4_storerf_rr:
678*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerft_rr : S4_pstorerff_rr;
679*9880d681SAndroid Build Coastguard Worker     case S2_storerfabs:
680*9880d681SAndroid Build Coastguard Worker     case S2_storerfgp:
681*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerft_abs : S4_pstorerff_abs;
682*9880d681SAndroid Build Coastguard Worker     case S4_storeirh_io:
683*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_storeirht_io : S4_storeirhf_io;
684*9880d681SAndroid Build Coastguard Worker     case S2_storeri_io:
685*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S2_pstorerit_io : S2_pstorerif_io;
686*9880d681SAndroid Build Coastguard Worker     case S4_storeri_rr:
687*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerit_rr : S4_pstorerif_rr;
688*9880d681SAndroid Build Coastguard Worker     case S2_storeriabs:
689*9880d681SAndroid Build Coastguard Worker     case S2_storerigp:
690*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerit_abs : S4_pstorerif_abs;
691*9880d681SAndroid Build Coastguard Worker     case S4_storeiri_io:
692*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_storeirit_io : S4_storeirif_io;
693*9880d681SAndroid Build Coastguard Worker     case S2_storerd_io:
694*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S2_pstorerdt_io : S2_pstorerdf_io;
695*9880d681SAndroid Build Coastguard Worker     case S4_storerd_rr:
696*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerdt_rr : S4_pstorerdf_rr;
697*9880d681SAndroid Build Coastguard Worker     case S2_storerdabs:
698*9880d681SAndroid Build Coastguard Worker     case S2_storerdgp:
699*9880d681SAndroid Build Coastguard Worker       return IfTrue ? S4_pstorerdt_abs : S4_pstorerdf_abs;
700*9880d681SAndroid Build Coastguard Worker   }
701*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unexpected opcode");
702*9880d681SAndroid Build Coastguard Worker   return 0;
703*9880d681SAndroid Build Coastguard Worker }
704*9880d681SAndroid Build Coastguard Worker 
705*9880d681SAndroid Build Coastguard Worker 
predicateInstr(MachineBasicBlock * ToB,MachineBasicBlock::iterator At,MachineInstr * MI,unsigned PredR,bool IfTrue)706*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::predicateInstr(MachineBasicBlock *ToB,
707*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::iterator At, MachineInstr *MI,
708*9880d681SAndroid Build Coastguard Worker       unsigned PredR, bool IfTrue) {
709*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
710*9880d681SAndroid Build Coastguard Worker   if (At != ToB->end())
711*9880d681SAndroid Build Coastguard Worker     DL = At->getDebugLoc();
712*9880d681SAndroid Build Coastguard Worker   else if (!ToB->empty())
713*9880d681SAndroid Build Coastguard Worker     DL = ToB->back().getDebugLoc();
714*9880d681SAndroid Build Coastguard Worker 
715*9880d681SAndroid Build Coastguard Worker   unsigned Opc = MI->getOpcode();
716*9880d681SAndroid Build Coastguard Worker 
717*9880d681SAndroid Build Coastguard Worker   if (isPredicableStore(MI)) {
718*9880d681SAndroid Build Coastguard Worker     unsigned COpc = getCondStoreOpcode(Opc, IfTrue);
719*9880d681SAndroid Build Coastguard Worker     assert(COpc);
720*9880d681SAndroid Build Coastguard Worker     MachineInstrBuilder MIB = BuildMI(*ToB, At, DL, TII->get(COpc))
721*9880d681SAndroid Build Coastguard Worker       .addReg(PredR);
722*9880d681SAndroid Build Coastguard Worker     for (MIOperands MO(*MI); MO.isValid(); ++MO)
723*9880d681SAndroid Build Coastguard Worker       MIB.addOperand(*MO);
724*9880d681SAndroid Build Coastguard Worker 
725*9880d681SAndroid Build Coastguard Worker     // Set memory references.
726*9880d681SAndroid Build Coastguard Worker     MachineInstr::mmo_iterator MMOBegin = MI->memoperands_begin();
727*9880d681SAndroid Build Coastguard Worker     MachineInstr::mmo_iterator MMOEnd = MI->memoperands_end();
728*9880d681SAndroid Build Coastguard Worker     MIB.setMemRefs(MMOBegin, MMOEnd);
729*9880d681SAndroid Build Coastguard Worker 
730*9880d681SAndroid Build Coastguard Worker     MI->eraseFromParent();
731*9880d681SAndroid Build Coastguard Worker     return;
732*9880d681SAndroid Build Coastguard Worker   }
733*9880d681SAndroid Build Coastguard Worker 
734*9880d681SAndroid Build Coastguard Worker   if (Opc == Hexagon::J2_jump) {
735*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *TB = MI->getOperand(0).getMBB();
736*9880d681SAndroid Build Coastguard Worker     const MCInstrDesc &D = TII->get(IfTrue ? Hexagon::J2_jumpt
737*9880d681SAndroid Build Coastguard Worker                                            : Hexagon::J2_jumpf);
738*9880d681SAndroid Build Coastguard Worker     BuildMI(*ToB, At, DL, D)
739*9880d681SAndroid Build Coastguard Worker       .addReg(PredR)
740*9880d681SAndroid Build Coastguard Worker       .addMBB(TB);
741*9880d681SAndroid Build Coastguard Worker     MI->eraseFromParent();
742*9880d681SAndroid Build Coastguard Worker     return;
743*9880d681SAndroid Build Coastguard Worker   }
744*9880d681SAndroid Build Coastguard Worker 
745*9880d681SAndroid Build Coastguard Worker   // Print the offending instruction unconditionally as we are about to
746*9880d681SAndroid Build Coastguard Worker   // abort.
747*9880d681SAndroid Build Coastguard Worker   dbgs() << *MI;
748*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unexpected instruction");
749*9880d681SAndroid Build Coastguard Worker }
750*9880d681SAndroid Build Coastguard Worker 
751*9880d681SAndroid Build Coastguard Worker 
752*9880d681SAndroid Build Coastguard Worker // Predicate/speculate non-branch instructions from FromB into block ToB.
753*9880d681SAndroid Build Coastguard Worker // Leave the branches alone, they will be handled later. Btw, at this point
754*9880d681SAndroid Build Coastguard Worker // FromB should have at most one branch, and it should be unconditional.
predicateBlockNB(MachineBasicBlock * ToB,MachineBasicBlock::iterator At,MachineBasicBlock * FromB,unsigned PredR,bool IfTrue)755*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::predicateBlockNB(MachineBasicBlock *ToB,
756*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::iterator At, MachineBasicBlock *FromB,
757*9880d681SAndroid Build Coastguard Worker       unsigned PredR, bool IfTrue) {
758*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Predicating block " << PrintMB(FromB) << "\n");
759*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator End = FromB->getFirstTerminator();
760*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I, NextI;
761*9880d681SAndroid Build Coastguard Worker 
762*9880d681SAndroid Build Coastguard Worker   for (I = FromB->begin(); I != End; I = NextI) {
763*9880d681SAndroid Build Coastguard Worker     assert(!I->isPHI());
764*9880d681SAndroid Build Coastguard Worker     NextI = std::next(I);
765*9880d681SAndroid Build Coastguard Worker     if (isSafeToSpeculate(&*I))
766*9880d681SAndroid Build Coastguard Worker       ToB->splice(At, FromB, I);
767*9880d681SAndroid Build Coastguard Worker     else
768*9880d681SAndroid Build Coastguard Worker       predicateInstr(ToB, At, &*I, PredR, IfTrue);
769*9880d681SAndroid Build Coastguard Worker   }
770*9880d681SAndroid Build Coastguard Worker }
771*9880d681SAndroid Build Coastguard Worker 
772*9880d681SAndroid Build Coastguard Worker 
updatePhiNodes(MachineBasicBlock * WhereB,const FlowPattern & FP)773*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::updatePhiNodes(MachineBasicBlock *WhereB,
774*9880d681SAndroid Build Coastguard Worker       const FlowPattern &FP) {
775*9880d681SAndroid Build Coastguard Worker   // Visit all PHI nodes in the WhereB block and generate MUX instructions
776*9880d681SAndroid Build Coastguard Worker   // in the split block. Update the PHI nodes with the values of the MUX.
777*9880d681SAndroid Build Coastguard Worker   auto NonPHI = WhereB->getFirstNonPHI();
778*9880d681SAndroid Build Coastguard Worker   for (auto I = WhereB->begin(); I != NonPHI; ++I) {
779*9880d681SAndroid Build Coastguard Worker     MachineInstr *PN = &*I;
780*9880d681SAndroid Build Coastguard Worker     // Registers and subregisters corresponding to TrueB, FalseB and SplitB.
781*9880d681SAndroid Build Coastguard Worker     unsigned TR = 0, TSR = 0, FR = 0, FSR = 0, SR = 0, SSR = 0;
782*9880d681SAndroid Build Coastguard Worker     for (int i = PN->getNumOperands()-2; i > 0; i -= 2) {
783*9880d681SAndroid Build Coastguard Worker       const MachineOperand &RO = PN->getOperand(i), &BO = PN->getOperand(i+1);
784*9880d681SAndroid Build Coastguard Worker       if (BO.getMBB() == FP.SplitB)
785*9880d681SAndroid Build Coastguard Worker         SR = RO.getReg(), SSR = RO.getSubReg();
786*9880d681SAndroid Build Coastguard Worker       else if (BO.getMBB() == FP.TrueB)
787*9880d681SAndroid Build Coastguard Worker         TR = RO.getReg(), TSR = RO.getSubReg();
788*9880d681SAndroid Build Coastguard Worker       else if (BO.getMBB() == FP.FalseB)
789*9880d681SAndroid Build Coastguard Worker         FR = RO.getReg(), FSR = RO.getSubReg();
790*9880d681SAndroid Build Coastguard Worker       else
791*9880d681SAndroid Build Coastguard Worker         continue;
792*9880d681SAndroid Build Coastguard Worker       PN->RemoveOperand(i+1);
793*9880d681SAndroid Build Coastguard Worker       PN->RemoveOperand(i);
794*9880d681SAndroid Build Coastguard Worker     }
795*9880d681SAndroid Build Coastguard Worker     if (TR == 0)
796*9880d681SAndroid Build Coastguard Worker       TR = SR, TSR = SSR;
797*9880d681SAndroid Build Coastguard Worker     else if (FR == 0)
798*9880d681SAndroid Build Coastguard Worker       FR = SR, FSR = SSR;
799*9880d681SAndroid Build Coastguard Worker     assert(TR && FR);
800*9880d681SAndroid Build Coastguard Worker 
801*9880d681SAndroid Build Coastguard Worker     using namespace Hexagon;
802*9880d681SAndroid Build Coastguard Worker     unsigned DR = PN->getOperand(0).getReg();
803*9880d681SAndroid Build Coastguard Worker     const TargetRegisterClass *RC = MRI->getRegClass(DR);
804*9880d681SAndroid Build Coastguard Worker     const MCInstrDesc &D = RC == &IntRegsRegClass ? TII->get(C2_mux)
805*9880d681SAndroid Build Coastguard Worker                                                   : TII->get(MUX64_rr);
806*9880d681SAndroid Build Coastguard Worker 
807*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator MuxAt = FP.SplitB->getFirstTerminator();
808*9880d681SAndroid Build Coastguard Worker     DebugLoc DL;
809*9880d681SAndroid Build Coastguard Worker     if (MuxAt != FP.SplitB->end())
810*9880d681SAndroid Build Coastguard Worker       DL = MuxAt->getDebugLoc();
811*9880d681SAndroid Build Coastguard Worker     unsigned MuxR = MRI->createVirtualRegister(RC);
812*9880d681SAndroid Build Coastguard Worker     BuildMI(*FP.SplitB, MuxAt, DL, D, MuxR)
813*9880d681SAndroid Build Coastguard Worker       .addReg(FP.PredR)
814*9880d681SAndroid Build Coastguard Worker       .addReg(TR, 0, TSR)
815*9880d681SAndroid Build Coastguard Worker       .addReg(FR, 0, FSR);
816*9880d681SAndroid Build Coastguard Worker 
817*9880d681SAndroid Build Coastguard Worker     PN->addOperand(MachineOperand::CreateReg(MuxR, false));
818*9880d681SAndroid Build Coastguard Worker     PN->addOperand(MachineOperand::CreateMBB(FP.SplitB));
819*9880d681SAndroid Build Coastguard Worker   }
820*9880d681SAndroid Build Coastguard Worker }
821*9880d681SAndroid Build Coastguard Worker 
822*9880d681SAndroid Build Coastguard Worker 
convert(const FlowPattern & FP)823*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::convert(const FlowPattern &FP) {
824*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *TSB = 0, *FSB = 0;
825*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator OldTI = FP.SplitB->getFirstTerminator();
826*9880d681SAndroid Build Coastguard Worker   assert(OldTI != FP.SplitB->end());
827*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = OldTI->getDebugLoc();
828*9880d681SAndroid Build Coastguard Worker 
829*9880d681SAndroid Build Coastguard Worker   if (FP.TrueB) {
830*9880d681SAndroid Build Coastguard Worker     TSB = *FP.TrueB->succ_begin();
831*9880d681SAndroid Build Coastguard Worker     predicateBlockNB(FP.SplitB, OldTI, FP.TrueB, FP.PredR, true);
832*9880d681SAndroid Build Coastguard Worker   }
833*9880d681SAndroid Build Coastguard Worker   if (FP.FalseB) {
834*9880d681SAndroid Build Coastguard Worker     FSB = *FP.FalseB->succ_begin();
835*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator At = FP.SplitB->getFirstTerminator();
836*9880d681SAndroid Build Coastguard Worker     predicateBlockNB(FP.SplitB, At, FP.FalseB, FP.PredR, false);
837*9880d681SAndroid Build Coastguard Worker   }
838*9880d681SAndroid Build Coastguard Worker 
839*9880d681SAndroid Build Coastguard Worker   // Regenerate new terminators in the split block and update the successors.
840*9880d681SAndroid Build Coastguard Worker   // First, remember any information that may be needed later and remove the
841*9880d681SAndroid Build Coastguard Worker   // existing terminators/successors from the split block.
842*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *SSB = 0;
843*9880d681SAndroid Build Coastguard Worker   FP.SplitB->erase(OldTI, FP.SplitB->end());
844*9880d681SAndroid Build Coastguard Worker   while (FP.SplitB->succ_size() > 0) {
845*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *T = *FP.SplitB->succ_begin();
846*9880d681SAndroid Build Coastguard Worker     // It's possible that the split block had a successor that is not a pre-
847*9880d681SAndroid Build Coastguard Worker     // dicated block. This could only happen if there was only one block to
848*9880d681SAndroid Build Coastguard Worker     // be predicated. Example:
849*9880d681SAndroid Build Coastguard Worker     //   split_b:
850*9880d681SAndroid Build Coastguard Worker     //     if (p) jump true_b
851*9880d681SAndroid Build Coastguard Worker     //     jump unrelated2_b
852*9880d681SAndroid Build Coastguard Worker     //   unrelated1_b:
853*9880d681SAndroid Build Coastguard Worker     //     ...
854*9880d681SAndroid Build Coastguard Worker     //   unrelated2_b:  ; can have other predecessors, so it's not "false_b"
855*9880d681SAndroid Build Coastguard Worker     //     jump other_b
856*9880d681SAndroid Build Coastguard Worker     //   true_b:        ; only reachable from split_b, can be predicated
857*9880d681SAndroid Build Coastguard Worker     //     ...
858*9880d681SAndroid Build Coastguard Worker     //
859*9880d681SAndroid Build Coastguard Worker     // Find this successor (SSB) if it exists.
860*9880d681SAndroid Build Coastguard Worker     if (T != FP.TrueB && T != FP.FalseB) {
861*9880d681SAndroid Build Coastguard Worker       assert(!SSB);
862*9880d681SAndroid Build Coastguard Worker       SSB = T;
863*9880d681SAndroid Build Coastguard Worker     }
864*9880d681SAndroid Build Coastguard Worker     FP.SplitB->removeSuccessor(FP.SplitB->succ_begin());
865*9880d681SAndroid Build Coastguard Worker   }
866*9880d681SAndroid Build Coastguard Worker 
867*9880d681SAndroid Build Coastguard Worker   // Insert new branches and update the successors of the split block. This
868*9880d681SAndroid Build Coastguard Worker   // may create unconditional branches to the layout successor, etc., but
869*9880d681SAndroid Build Coastguard Worker   // that will be cleaned up later. For now, make sure that correct code is
870*9880d681SAndroid Build Coastguard Worker   // generated.
871*9880d681SAndroid Build Coastguard Worker   if (FP.JoinB) {
872*9880d681SAndroid Build Coastguard Worker     assert(!SSB || SSB == FP.JoinB);
873*9880d681SAndroid Build Coastguard Worker     BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jump))
874*9880d681SAndroid Build Coastguard Worker       .addMBB(FP.JoinB);
875*9880d681SAndroid Build Coastguard Worker     FP.SplitB->addSuccessor(FP.JoinB);
876*9880d681SAndroid Build Coastguard Worker   } else {
877*9880d681SAndroid Build Coastguard Worker     bool HasBranch = false;
878*9880d681SAndroid Build Coastguard Worker     if (TSB) {
879*9880d681SAndroid Build Coastguard Worker       BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jumpt))
880*9880d681SAndroid Build Coastguard Worker         .addReg(FP.PredR)
881*9880d681SAndroid Build Coastguard Worker         .addMBB(TSB);
882*9880d681SAndroid Build Coastguard Worker       FP.SplitB->addSuccessor(TSB);
883*9880d681SAndroid Build Coastguard Worker       HasBranch = true;
884*9880d681SAndroid Build Coastguard Worker     }
885*9880d681SAndroid Build Coastguard Worker     if (FSB) {
886*9880d681SAndroid Build Coastguard Worker       const MCInstrDesc &D = HasBranch ? TII->get(Hexagon::J2_jump)
887*9880d681SAndroid Build Coastguard Worker                                        : TII->get(Hexagon::J2_jumpf);
888*9880d681SAndroid Build Coastguard Worker       MachineInstrBuilder MIB = BuildMI(*FP.SplitB, FP.SplitB->end(), DL, D);
889*9880d681SAndroid Build Coastguard Worker       if (!HasBranch)
890*9880d681SAndroid Build Coastguard Worker         MIB.addReg(FP.PredR);
891*9880d681SAndroid Build Coastguard Worker       MIB.addMBB(FSB);
892*9880d681SAndroid Build Coastguard Worker       FP.SplitB->addSuccessor(FSB);
893*9880d681SAndroid Build Coastguard Worker     }
894*9880d681SAndroid Build Coastguard Worker     if (SSB) {
895*9880d681SAndroid Build Coastguard Worker       // This cannot happen if both TSB and FSB are set. [TF]SB are the
896*9880d681SAndroid Build Coastguard Worker       // successor blocks of the TrueB and FalseB (or null of the TrueB
897*9880d681SAndroid Build Coastguard Worker       // or FalseB block is null). SSB is the potential successor block
898*9880d681SAndroid Build Coastguard Worker       // of the SplitB that is neither TrueB nor FalseB.
899*9880d681SAndroid Build Coastguard Worker       BuildMI(*FP.SplitB, FP.SplitB->end(), DL, TII->get(Hexagon::J2_jump))
900*9880d681SAndroid Build Coastguard Worker         .addMBB(SSB);
901*9880d681SAndroid Build Coastguard Worker       FP.SplitB->addSuccessor(SSB);
902*9880d681SAndroid Build Coastguard Worker     }
903*9880d681SAndroid Build Coastguard Worker   }
904*9880d681SAndroid Build Coastguard Worker 
905*9880d681SAndroid Build Coastguard Worker   // What is left to do is to update the PHI nodes that could have entries
906*9880d681SAndroid Build Coastguard Worker   // referring to predicated blocks.
907*9880d681SAndroid Build Coastguard Worker   if (FP.JoinB) {
908*9880d681SAndroid Build Coastguard Worker     updatePhiNodes(FP.JoinB, FP);
909*9880d681SAndroid Build Coastguard Worker   } else {
910*9880d681SAndroid Build Coastguard Worker     if (TSB)
911*9880d681SAndroid Build Coastguard Worker       updatePhiNodes(TSB, FP);
912*9880d681SAndroid Build Coastguard Worker     if (FSB)
913*9880d681SAndroid Build Coastguard Worker       updatePhiNodes(FSB, FP);
914*9880d681SAndroid Build Coastguard Worker     // Nothing to update in SSB, since SSB's predecessors haven't changed.
915*9880d681SAndroid Build Coastguard Worker   }
916*9880d681SAndroid Build Coastguard Worker }
917*9880d681SAndroid Build Coastguard Worker 
918*9880d681SAndroid Build Coastguard Worker 
removeBlock(MachineBasicBlock * B)919*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::removeBlock(MachineBasicBlock *B) {
920*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Removing block " << PrintMB(B) << "\n");
921*9880d681SAndroid Build Coastguard Worker 
922*9880d681SAndroid Build Coastguard Worker   // Transfer the immediate dominator information from B to its descendants.
923*9880d681SAndroid Build Coastguard Worker   MachineDomTreeNode *N = MDT->getNode(B);
924*9880d681SAndroid Build Coastguard Worker   MachineDomTreeNode *IDN = N->getIDom();
925*9880d681SAndroid Build Coastguard Worker   if (IDN) {
926*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *IDB = IDN->getBlock();
927*9880d681SAndroid Build Coastguard Worker     typedef GraphTraits<MachineDomTreeNode*> GTN;
928*9880d681SAndroid Build Coastguard Worker     typedef SmallVector<MachineDomTreeNode*,4> DTNodeVectType;
929*9880d681SAndroid Build Coastguard Worker     DTNodeVectType Cn(GTN::child_begin(N), GTN::child_end(N));
930*9880d681SAndroid Build Coastguard Worker     for (DTNodeVectType::iterator I = Cn.begin(), E = Cn.end(); I != E; ++I) {
931*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *SB = (*I)->getBlock();
932*9880d681SAndroid Build Coastguard Worker       MDT->changeImmediateDominator(SB, IDB);
933*9880d681SAndroid Build Coastguard Worker     }
934*9880d681SAndroid Build Coastguard Worker   }
935*9880d681SAndroid Build Coastguard Worker 
936*9880d681SAndroid Build Coastguard Worker   while (B->succ_size() > 0)
937*9880d681SAndroid Build Coastguard Worker     B->removeSuccessor(B->succ_begin());
938*9880d681SAndroid Build Coastguard Worker 
939*9880d681SAndroid Build Coastguard Worker   for (auto I = B->pred_begin(), E = B->pred_end(); I != E; ++I)
940*9880d681SAndroid Build Coastguard Worker     (*I)->removeSuccessor(B, true);
941*9880d681SAndroid Build Coastguard Worker 
942*9880d681SAndroid Build Coastguard Worker   Deleted.insert(B);
943*9880d681SAndroid Build Coastguard Worker   MDT->eraseNode(B);
944*9880d681SAndroid Build Coastguard Worker   MFN->erase(B->getIterator());
945*9880d681SAndroid Build Coastguard Worker }
946*9880d681SAndroid Build Coastguard Worker 
947*9880d681SAndroid Build Coastguard Worker 
eliminatePhis(MachineBasicBlock * B)948*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::eliminatePhis(MachineBasicBlock *B) {
949*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Removing phi nodes from block " << PrintMB(B) << "\n");
950*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I, NextI, NonPHI = B->getFirstNonPHI();
951*9880d681SAndroid Build Coastguard Worker   for (I = B->begin(); I != NonPHI; I = NextI) {
952*9880d681SAndroid Build Coastguard Worker     NextI = std::next(I);
953*9880d681SAndroid Build Coastguard Worker     MachineInstr *PN = &*I;
954*9880d681SAndroid Build Coastguard Worker     assert(PN->getNumOperands() == 3 && "Invalid phi node");
955*9880d681SAndroid Build Coastguard Worker     MachineOperand &UO = PN->getOperand(1);
956*9880d681SAndroid Build Coastguard Worker     unsigned UseR = UO.getReg(), UseSR = UO.getSubReg();
957*9880d681SAndroid Build Coastguard Worker     unsigned DefR = PN->getOperand(0).getReg();
958*9880d681SAndroid Build Coastguard Worker     unsigned NewR = UseR;
959*9880d681SAndroid Build Coastguard Worker     if (UseSR) {
960*9880d681SAndroid Build Coastguard Worker       // MRI.replaceVregUsesWith does not allow to update the subregister,
961*9880d681SAndroid Build Coastguard Worker       // so instead of doing the use-iteration here, create a copy into a
962*9880d681SAndroid Build Coastguard Worker       // "non-subregistered" register.
963*9880d681SAndroid Build Coastguard Worker       const DebugLoc &DL = PN->getDebugLoc();
964*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass *RC = MRI->getRegClass(DefR);
965*9880d681SAndroid Build Coastguard Worker       NewR = MRI->createVirtualRegister(RC);
966*9880d681SAndroid Build Coastguard Worker       NonPHI = BuildMI(*B, NonPHI, DL, TII->get(TargetOpcode::COPY), NewR)
967*9880d681SAndroid Build Coastguard Worker         .addReg(UseR, 0, UseSR);
968*9880d681SAndroid Build Coastguard Worker     }
969*9880d681SAndroid Build Coastguard Worker     MRI->replaceRegWith(DefR, NewR);
970*9880d681SAndroid Build Coastguard Worker     B->erase(I);
971*9880d681SAndroid Build Coastguard Worker   }
972*9880d681SAndroid Build Coastguard Worker }
973*9880d681SAndroid Build Coastguard Worker 
974*9880d681SAndroid Build Coastguard Worker 
replacePhiEdges(MachineBasicBlock * OldB,MachineBasicBlock * NewB)975*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::replacePhiEdges(MachineBasicBlock *OldB,
976*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *NewB) {
977*9880d681SAndroid Build Coastguard Worker   for (auto I = OldB->succ_begin(), E = OldB->succ_end(); I != E; ++I) {
978*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock *SB = *I;
979*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock::iterator P, N = SB->getFirstNonPHI();
980*9880d681SAndroid Build Coastguard Worker     for (P = SB->begin(); P != N; ++P) {
981*9880d681SAndroid Build Coastguard Worker       MachineInstr &PN = *P;
982*9880d681SAndroid Build Coastguard Worker       for (MIOperands MO(PN); MO.isValid(); ++MO)
983*9880d681SAndroid Build Coastguard Worker         if (MO->isMBB() && MO->getMBB() == OldB)
984*9880d681SAndroid Build Coastguard Worker           MO->setMBB(NewB);
985*9880d681SAndroid Build Coastguard Worker     }
986*9880d681SAndroid Build Coastguard Worker   }
987*9880d681SAndroid Build Coastguard Worker }
988*9880d681SAndroid Build Coastguard Worker 
989*9880d681SAndroid Build Coastguard Worker 
mergeBlocks(MachineBasicBlock * PredB,MachineBasicBlock * SuccB)990*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::mergeBlocks(MachineBasicBlock *PredB,
991*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *SuccB) {
992*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "Merging blocks " << PrintMB(PredB) << " and "
993*9880d681SAndroid Build Coastguard Worker                << PrintMB(SuccB) << "\n");
994*9880d681SAndroid Build Coastguard Worker   bool TermOk = hasUncondBranch(SuccB);
995*9880d681SAndroid Build Coastguard Worker   eliminatePhis(SuccB);
996*9880d681SAndroid Build Coastguard Worker   TII->RemoveBranch(*PredB);
997*9880d681SAndroid Build Coastguard Worker   PredB->removeSuccessor(SuccB);
998*9880d681SAndroid Build Coastguard Worker   PredB->splice(PredB->end(), SuccB, SuccB->begin(), SuccB->end());
999*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::succ_iterator I, E = SuccB->succ_end();
1000*9880d681SAndroid Build Coastguard Worker   for (I = SuccB->succ_begin(); I != E; ++I)
1001*9880d681SAndroid Build Coastguard Worker     PredB->addSuccessor(*I);
1002*9880d681SAndroid Build Coastguard Worker   PredB->normalizeSuccProbs();
1003*9880d681SAndroid Build Coastguard Worker   replacePhiEdges(SuccB, PredB);
1004*9880d681SAndroid Build Coastguard Worker   removeBlock(SuccB);
1005*9880d681SAndroid Build Coastguard Worker   if (!TermOk)
1006*9880d681SAndroid Build Coastguard Worker     PredB->updateTerminator();
1007*9880d681SAndroid Build Coastguard Worker }
1008*9880d681SAndroid Build Coastguard Worker 
1009*9880d681SAndroid Build Coastguard Worker 
simplifyFlowGraph(const FlowPattern & FP)1010*9880d681SAndroid Build Coastguard Worker void HexagonEarlyIfConversion::simplifyFlowGraph(const FlowPattern &FP) {
1011*9880d681SAndroid Build Coastguard Worker   if (FP.TrueB)
1012*9880d681SAndroid Build Coastguard Worker     removeBlock(FP.TrueB);
1013*9880d681SAndroid Build Coastguard Worker   if (FP.FalseB)
1014*9880d681SAndroid Build Coastguard Worker     removeBlock(FP.FalseB);
1015*9880d681SAndroid Build Coastguard Worker 
1016*9880d681SAndroid Build Coastguard Worker   FP.SplitB->updateTerminator();
1017*9880d681SAndroid Build Coastguard Worker   if (FP.SplitB->succ_size() != 1)
1018*9880d681SAndroid Build Coastguard Worker     return;
1019*9880d681SAndroid Build Coastguard Worker 
1020*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *SB = *FP.SplitB->succ_begin();
1021*9880d681SAndroid Build Coastguard Worker   if (SB->pred_size() != 1)
1022*9880d681SAndroid Build Coastguard Worker     return;
1023*9880d681SAndroid Build Coastguard Worker 
1024*9880d681SAndroid Build Coastguard Worker   // By now, the split block has only one successor (SB), and SB has only
1025*9880d681SAndroid Build Coastguard Worker   // one predecessor. We can try to merge them. We will need to update ter-
1026*9880d681SAndroid Build Coastguard Worker   // minators in FP.Split+SB, and that requires working AnalyzeBranch, which
1027*9880d681SAndroid Build Coastguard Worker   // fails on Hexagon for blocks that have EH_LABELs. However, if SB ends
1028*9880d681SAndroid Build Coastguard Worker   // with an unconditional branch, we won't need to touch the terminators.
1029*9880d681SAndroid Build Coastguard Worker   if (!hasEHLabel(SB) || hasUncondBranch(SB))
1030*9880d681SAndroid Build Coastguard Worker     mergeBlocks(FP.SplitB, SB);
1031*9880d681SAndroid Build Coastguard Worker }
1032*9880d681SAndroid Build Coastguard Worker 
1033*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(MachineFunction & MF)1034*9880d681SAndroid Build Coastguard Worker bool HexagonEarlyIfConversion::runOnMachineFunction(MachineFunction &MF) {
1035*9880d681SAndroid Build Coastguard Worker   if (skipFunction(*MF.getFunction()))
1036*9880d681SAndroid Build Coastguard Worker     return false;
1037*9880d681SAndroid Build Coastguard Worker 
1038*9880d681SAndroid Build Coastguard Worker   auto &ST = MF.getSubtarget();
1039*9880d681SAndroid Build Coastguard Worker   TII = ST.getInstrInfo();
1040*9880d681SAndroid Build Coastguard Worker   TRI = ST.getRegisterInfo();
1041*9880d681SAndroid Build Coastguard Worker   MFN = &MF;
1042*9880d681SAndroid Build Coastguard Worker   MRI = &MF.getRegInfo();
1043*9880d681SAndroid Build Coastguard Worker   MDT = &getAnalysis<MachineDominatorTree>();
1044*9880d681SAndroid Build Coastguard Worker   MLI = &getAnalysis<MachineLoopInfo>();
1045*9880d681SAndroid Build Coastguard Worker   MBPI = EnableHexagonBP ? &getAnalysis<MachineBranchProbabilityInfo>() :
1046*9880d681SAndroid Build Coastguard Worker     nullptr;
1047*9880d681SAndroid Build Coastguard Worker 
1048*9880d681SAndroid Build Coastguard Worker   Deleted.clear();
1049*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
1050*9880d681SAndroid Build Coastguard Worker 
1051*9880d681SAndroid Build Coastguard Worker   for (MachineLoopInfo::iterator I = MLI->begin(), E = MLI->end(); I != E; ++I)
1052*9880d681SAndroid Build Coastguard Worker     Changed |= visitLoop(*I);
1053*9880d681SAndroid Build Coastguard Worker   Changed |= visitLoop(0);
1054*9880d681SAndroid Build Coastguard Worker 
1055*9880d681SAndroid Build Coastguard Worker   return Changed;
1056*9880d681SAndroid Build Coastguard Worker }
1057*9880d681SAndroid Build Coastguard Worker 
1058*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
1059*9880d681SAndroid Build Coastguard Worker //                         Public Constructor Functions
1060*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
createHexagonEarlyIfConversion()1061*9880d681SAndroid Build Coastguard Worker FunctionPass *llvm::createHexagonEarlyIfConversion() {
1062*9880d681SAndroid Build Coastguard Worker   return new HexagonEarlyIfConversion();
1063*9880d681SAndroid Build Coastguard Worker }
1064*9880d681SAndroid Build Coastguard Worker 
1065