1*9880d681SAndroid Build Coastguard Worker //===-- EarlyIfConversion.cpp - If-conversion on SSA form machine code ----===//
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 // Early if-conversion is for out-of-order CPUs that don't have a lot of
11*9880d681SAndroid Build Coastguard Worker // predicable instructions. The goal is to eliminate conditional branches that
12*9880d681SAndroid Build Coastguard Worker // may mispredict.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker // Instructions from both sides of the branch are executed specutatively, and a
15*9880d681SAndroid Build Coastguard Worker // cmov instruction selects the result.
16*9880d681SAndroid Build Coastguard Worker //
17*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/BitVector.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/PostOrderIterator.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SparseSet.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineDominators.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineLoopInfo.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineTraceMetrics.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/Passes.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
37*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
38*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
39*9880d681SAndroid Build Coastguard Worker
40*9880d681SAndroid Build Coastguard Worker using namespace llvm;
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "early-ifcvt"
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker // Absolute maximum number of instructions allowed per speculated block.
45*9880d681SAndroid Build Coastguard Worker // This bypasses all other heuristics, so it should be set fairly high.
46*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned>
47*9880d681SAndroid Build Coastguard Worker BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden,
48*9880d681SAndroid Build Coastguard Worker cl::desc("Maximum number of instructions per speculated block."));
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker // Stress testing mode - disable heuristics.
51*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> Stress("stress-early-ifcvt", cl::Hidden,
52*9880d681SAndroid Build Coastguard Worker cl::desc("Turn all knobs to 11"));
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker STATISTIC(NumDiamondsSeen, "Number of diamonds");
55*9880d681SAndroid Build Coastguard Worker STATISTIC(NumDiamondsConv, "Number of diamonds converted");
56*9880d681SAndroid Build Coastguard Worker STATISTIC(NumTrianglesSeen, "Number of triangles");
57*9880d681SAndroid Build Coastguard Worker STATISTIC(NumTrianglesConv, "Number of triangles converted");
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
60*9880d681SAndroid Build Coastguard Worker // SSAIfConv
61*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
62*9880d681SAndroid Build Coastguard Worker //
63*9880d681SAndroid Build Coastguard Worker // The SSAIfConv class performs if-conversion on SSA form machine code after
64*9880d681SAndroid Build Coastguard Worker // determining if it is possible. The class contains no heuristics; external
65*9880d681SAndroid Build Coastguard Worker // code should be used to determine when if-conversion is a good idea.
66*9880d681SAndroid Build Coastguard Worker //
67*9880d681SAndroid Build Coastguard Worker // SSAIfConv can convert both triangles and diamonds:
68*9880d681SAndroid Build Coastguard Worker //
69*9880d681SAndroid Build Coastguard Worker // Triangle: Head Diamond: Head
70*9880d681SAndroid Build Coastguard Worker // | \ / \_
71*9880d681SAndroid Build Coastguard Worker // | \ / |
72*9880d681SAndroid Build Coastguard Worker // | [TF]BB FBB TBB
73*9880d681SAndroid Build Coastguard Worker // | / \ /
74*9880d681SAndroid Build Coastguard Worker // | / \ /
75*9880d681SAndroid Build Coastguard Worker // Tail Tail
76*9880d681SAndroid Build Coastguard Worker //
77*9880d681SAndroid Build Coastguard Worker // Instructions in the conditional blocks TBB and/or FBB are spliced into the
78*9880d681SAndroid Build Coastguard Worker // Head block, and phis in the Tail block are converted to select instructions.
79*9880d681SAndroid Build Coastguard Worker //
80*9880d681SAndroid Build Coastguard Worker namespace {
81*9880d681SAndroid Build Coastguard Worker class SSAIfConv {
82*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII;
83*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI;
84*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo *MRI;
85*9880d681SAndroid Build Coastguard Worker
86*9880d681SAndroid Build Coastguard Worker public:
87*9880d681SAndroid Build Coastguard Worker /// The block containing the conditional branch.
88*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Head;
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker /// The block containing phis after the if-then-else.
91*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Tail;
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker /// The 'true' conditional block as determined by AnalyzeBranch.
94*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TBB;
95*9880d681SAndroid Build Coastguard Worker
96*9880d681SAndroid Build Coastguard Worker /// The 'false' conditional block as determined by AnalyzeBranch.
97*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *FBB;
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker /// isTriangle - When there is no 'else' block, either TBB or FBB will be
100*9880d681SAndroid Build Coastguard Worker /// equal to Tail.
isTriangle() const101*9880d681SAndroid Build Coastguard Worker bool isTriangle() const { return TBB == Tail || FBB == Tail; }
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker /// Returns the Tail predecessor for the True side.
getTPred() const104*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *getTPred() const { return TBB == Tail ? Head : TBB; }
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker /// Returns the Tail predecessor for the False side.
getFPred() const107*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *getFPred() const { return FBB == Tail ? Head : FBB; }
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker /// Information about each phi in the Tail block.
110*9880d681SAndroid Build Coastguard Worker struct PHIInfo {
111*9880d681SAndroid Build Coastguard Worker MachineInstr *PHI;
112*9880d681SAndroid Build Coastguard Worker unsigned TReg, FReg;
113*9880d681SAndroid Build Coastguard Worker // Latencies from Cond+Branch, TReg, and FReg to DstReg.
114*9880d681SAndroid Build Coastguard Worker int CondCycles, TCycles, FCycles;
115*9880d681SAndroid Build Coastguard Worker
PHIInfo__anonb1e552be0111::SSAIfConv::PHIInfo116*9880d681SAndroid Build Coastguard Worker PHIInfo(MachineInstr *phi)
117*9880d681SAndroid Build Coastguard Worker : PHI(phi), TReg(0), FReg(0), CondCycles(0), TCycles(0), FCycles(0) {}
118*9880d681SAndroid Build Coastguard Worker };
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker SmallVector<PHIInfo, 8> PHIs;
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker private:
123*9880d681SAndroid Build Coastguard Worker /// The branch condition determined by AnalyzeBranch.
124*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand, 4> Cond;
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker /// Instructions in Head that define values used by the conditional blocks.
127*9880d681SAndroid Build Coastguard Worker /// The hoisted instructions must be inserted after these instructions.
128*9880d681SAndroid Build Coastguard Worker SmallPtrSet<MachineInstr*, 8> InsertAfter;
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker /// Register units clobbered by the conditional blocks.
131*9880d681SAndroid Build Coastguard Worker BitVector ClobberedRegUnits;
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker // Scratch pad for findInsertionPoint.
134*9880d681SAndroid Build Coastguard Worker SparseSet<unsigned> LiveRegUnits;
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker /// Insertion point in Head for speculatively executed instructions form TBB
137*9880d681SAndroid Build Coastguard Worker /// and FBB.
138*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator InsertionPoint;
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker /// Return true if all non-terminator instructions in MBB can be safely
141*9880d681SAndroid Build Coastguard Worker /// speculated.
142*9880d681SAndroid Build Coastguard Worker bool canSpeculateInstrs(MachineBasicBlock *MBB);
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker /// Find a valid insertion point in Head.
145*9880d681SAndroid Build Coastguard Worker bool findInsertionPoint();
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker /// Replace PHI instructions in Tail with selects.
148*9880d681SAndroid Build Coastguard Worker void replacePHIInstrs();
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker /// Insert selects and rewrite PHI operands to use them.
151*9880d681SAndroid Build Coastguard Worker void rewritePHIOperands();
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker public:
154*9880d681SAndroid Build Coastguard Worker /// runOnMachineFunction - Initialize per-function data structures.
runOnMachineFunction(MachineFunction & MF)155*9880d681SAndroid Build Coastguard Worker void runOnMachineFunction(MachineFunction &MF) {
156*9880d681SAndroid Build Coastguard Worker TII = MF.getSubtarget().getInstrInfo();
157*9880d681SAndroid Build Coastguard Worker TRI = MF.getSubtarget().getRegisterInfo();
158*9880d681SAndroid Build Coastguard Worker MRI = &MF.getRegInfo();
159*9880d681SAndroid Build Coastguard Worker LiveRegUnits.clear();
160*9880d681SAndroid Build Coastguard Worker LiveRegUnits.setUniverse(TRI->getNumRegUnits());
161*9880d681SAndroid Build Coastguard Worker ClobberedRegUnits.clear();
162*9880d681SAndroid Build Coastguard Worker ClobberedRegUnits.resize(TRI->getNumRegUnits());
163*9880d681SAndroid Build Coastguard Worker }
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker /// canConvertIf - If the sub-CFG headed by MBB can be if-converted,
166*9880d681SAndroid Build Coastguard Worker /// initialize the internal state, and return true.
167*9880d681SAndroid Build Coastguard Worker bool canConvertIf(MachineBasicBlock *MBB);
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Worker /// convertIf - If-convert the last block passed to canConvertIf(), assuming
170*9880d681SAndroid Build Coastguard Worker /// it is possible. Add any erased blocks to RemovedBlocks.
171*9880d681SAndroid Build Coastguard Worker void convertIf(SmallVectorImpl<MachineBasicBlock*> &RemovedBlocks);
172*9880d681SAndroid Build Coastguard Worker };
173*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker /// canSpeculateInstrs - Returns true if all the instructions in MBB can safely
177*9880d681SAndroid Build Coastguard Worker /// be speculated. The terminators are not considered.
178*9880d681SAndroid Build Coastguard Worker ///
179*9880d681SAndroid Build Coastguard Worker /// If instructions use any values that are defined in the head basic block,
180*9880d681SAndroid Build Coastguard Worker /// the defining instructions are added to InsertAfter.
181*9880d681SAndroid Build Coastguard Worker ///
182*9880d681SAndroid Build Coastguard Worker /// Any clobbered regunits are added to ClobberedRegUnits.
183*9880d681SAndroid Build Coastguard Worker ///
canSpeculateInstrs(MachineBasicBlock * MBB)184*9880d681SAndroid Build Coastguard Worker bool SSAIfConv::canSpeculateInstrs(MachineBasicBlock *MBB) {
185*9880d681SAndroid Build Coastguard Worker // Reject any live-in physregs. It's probably CPSR/EFLAGS, and very hard to
186*9880d681SAndroid Build Coastguard Worker // get right.
187*9880d681SAndroid Build Coastguard Worker if (!MBB->livein_empty()) {
188*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "BB#" << MBB->getNumber() << " has live-ins.\n");
189*9880d681SAndroid Build Coastguard Worker return false;
190*9880d681SAndroid Build Coastguard Worker }
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker unsigned InstrCount = 0;
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker // Check all instructions, except the terminators. It is assumed that
195*9880d681SAndroid Build Coastguard Worker // terminators never have side effects or define any used register values.
196*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator I = MBB->begin(),
197*9880d681SAndroid Build Coastguard Worker E = MBB->getFirstTerminator(); I != E; ++I) {
198*9880d681SAndroid Build Coastguard Worker if (I->isDebugValue())
199*9880d681SAndroid Build Coastguard Worker continue;
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker if (++InstrCount > BlockInstrLimit && !Stress) {
202*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "BB#" << MBB->getNumber() << " has more than "
203*9880d681SAndroid Build Coastguard Worker << BlockInstrLimit << " instructions.\n");
204*9880d681SAndroid Build Coastguard Worker return false;
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker // There shouldn't normally be any phis in a single-predecessor block.
208*9880d681SAndroid Build Coastguard Worker if (I->isPHI()) {
209*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Can't hoist: " << *I);
210*9880d681SAndroid Build Coastguard Worker return false;
211*9880d681SAndroid Build Coastguard Worker }
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker // Don't speculate loads. Note that it may be possible and desirable to
214*9880d681SAndroid Build Coastguard Worker // speculate GOT or constant pool loads that are guaranteed not to trap,
215*9880d681SAndroid Build Coastguard Worker // but we don't support that for now.
216*9880d681SAndroid Build Coastguard Worker if (I->mayLoad()) {
217*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Won't speculate load: " << *I);
218*9880d681SAndroid Build Coastguard Worker return false;
219*9880d681SAndroid Build Coastguard Worker }
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker // We never speculate stores, so an AA pointer isn't necessary.
222*9880d681SAndroid Build Coastguard Worker bool DontMoveAcrossStore = true;
223*9880d681SAndroid Build Coastguard Worker if (!I->isSafeToMove(nullptr, DontMoveAcrossStore)) {
224*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Can't speculate: " << *I);
225*9880d681SAndroid Build Coastguard Worker return false;
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker // Check for any dependencies on Head instructions.
229*9880d681SAndroid Build Coastguard Worker for (const MachineOperand &MO : I->operands()) {
230*9880d681SAndroid Build Coastguard Worker if (MO.isRegMask()) {
231*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Won't speculate regmask: " << *I);
232*9880d681SAndroid Build Coastguard Worker return false;
233*9880d681SAndroid Build Coastguard Worker }
234*9880d681SAndroid Build Coastguard Worker if (!MO.isReg())
235*9880d681SAndroid Build Coastguard Worker continue;
236*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO.getReg();
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker // Remember clobbered regunits.
239*9880d681SAndroid Build Coastguard Worker if (MO.isDef() && TargetRegisterInfo::isPhysicalRegister(Reg))
240*9880d681SAndroid Build Coastguard Worker for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
241*9880d681SAndroid Build Coastguard Worker ClobberedRegUnits.set(*Units);
242*9880d681SAndroid Build Coastguard Worker
243*9880d681SAndroid Build Coastguard Worker if (!MO.readsReg() || !TargetRegisterInfo::isVirtualRegister(Reg))
244*9880d681SAndroid Build Coastguard Worker continue;
245*9880d681SAndroid Build Coastguard Worker MachineInstr *DefMI = MRI->getVRegDef(Reg);
246*9880d681SAndroid Build Coastguard Worker if (!DefMI || DefMI->getParent() != Head)
247*9880d681SAndroid Build Coastguard Worker continue;
248*9880d681SAndroid Build Coastguard Worker if (InsertAfter.insert(DefMI).second)
249*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "BB#" << MBB->getNumber() << " depends on " << *DefMI);
250*9880d681SAndroid Build Coastguard Worker if (DefMI->isTerminator()) {
251*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Can't insert instructions below terminator.\n");
252*9880d681SAndroid Build Coastguard Worker return false;
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker }
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker return true;
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker /// Find an insertion point in Head for the speculated instructions. The
261*9880d681SAndroid Build Coastguard Worker /// insertion point must be:
262*9880d681SAndroid Build Coastguard Worker ///
263*9880d681SAndroid Build Coastguard Worker /// 1. Before any terminators.
264*9880d681SAndroid Build Coastguard Worker /// 2. After any instructions in InsertAfter.
265*9880d681SAndroid Build Coastguard Worker /// 3. Not have any clobbered regunits live.
266*9880d681SAndroid Build Coastguard Worker ///
267*9880d681SAndroid Build Coastguard Worker /// This function sets InsertionPoint and returns true when successful, it
268*9880d681SAndroid Build Coastguard Worker /// returns false if no valid insertion point could be found.
269*9880d681SAndroid Build Coastguard Worker ///
findInsertionPoint()270*9880d681SAndroid Build Coastguard Worker bool SSAIfConv::findInsertionPoint() {
271*9880d681SAndroid Build Coastguard Worker // Keep track of live regunits before the current position.
272*9880d681SAndroid Build Coastguard Worker // Only track RegUnits that are also in ClobberedRegUnits.
273*9880d681SAndroid Build Coastguard Worker LiveRegUnits.clear();
274*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 8> Reads;
275*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
276*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator I = Head->end();
277*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator B = Head->begin();
278*9880d681SAndroid Build Coastguard Worker while (I != B) {
279*9880d681SAndroid Build Coastguard Worker --I;
280*9880d681SAndroid Build Coastguard Worker // Some of the conditional code depends in I.
281*9880d681SAndroid Build Coastguard Worker if (InsertAfter.count(&*I)) {
282*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Can't insert code after " << *I);
283*9880d681SAndroid Build Coastguard Worker return false;
284*9880d681SAndroid Build Coastguard Worker }
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker // Update live regunits.
287*9880d681SAndroid Build Coastguard Worker for (const MachineOperand &MO : I->operands()) {
288*9880d681SAndroid Build Coastguard Worker // We're ignoring regmask operands. That is conservatively correct.
289*9880d681SAndroid Build Coastguard Worker if (!MO.isReg())
290*9880d681SAndroid Build Coastguard Worker continue;
291*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO.getReg();
292*9880d681SAndroid Build Coastguard Worker if (!TargetRegisterInfo::isPhysicalRegister(Reg))
293*9880d681SAndroid Build Coastguard Worker continue;
294*9880d681SAndroid Build Coastguard Worker // I clobbers Reg, so it isn't live before I.
295*9880d681SAndroid Build Coastguard Worker if (MO.isDef())
296*9880d681SAndroid Build Coastguard Worker for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
297*9880d681SAndroid Build Coastguard Worker LiveRegUnits.erase(*Units);
298*9880d681SAndroid Build Coastguard Worker // Unless I reads Reg.
299*9880d681SAndroid Build Coastguard Worker if (MO.readsReg())
300*9880d681SAndroid Build Coastguard Worker Reads.push_back(Reg);
301*9880d681SAndroid Build Coastguard Worker }
302*9880d681SAndroid Build Coastguard Worker // Anything read by I is live before I.
303*9880d681SAndroid Build Coastguard Worker while (!Reads.empty())
304*9880d681SAndroid Build Coastguard Worker for (MCRegUnitIterator Units(Reads.pop_back_val(), TRI); Units.isValid();
305*9880d681SAndroid Build Coastguard Worker ++Units)
306*9880d681SAndroid Build Coastguard Worker if (ClobberedRegUnits.test(*Units))
307*9880d681SAndroid Build Coastguard Worker LiveRegUnits.insert(*Units);
308*9880d681SAndroid Build Coastguard Worker
309*9880d681SAndroid Build Coastguard Worker // We can't insert before a terminator.
310*9880d681SAndroid Build Coastguard Worker if (I != FirstTerm && I->isTerminator())
311*9880d681SAndroid Build Coastguard Worker continue;
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker // Some of the clobbered registers are live before I, not a valid insertion
314*9880d681SAndroid Build Coastguard Worker // point.
315*9880d681SAndroid Build Coastguard Worker if (!LiveRegUnits.empty()) {
316*9880d681SAndroid Build Coastguard Worker DEBUG({
317*9880d681SAndroid Build Coastguard Worker dbgs() << "Would clobber";
318*9880d681SAndroid Build Coastguard Worker for (SparseSet<unsigned>::const_iterator
319*9880d681SAndroid Build Coastguard Worker i = LiveRegUnits.begin(), e = LiveRegUnits.end(); i != e; ++i)
320*9880d681SAndroid Build Coastguard Worker dbgs() << ' ' << PrintRegUnit(*i, TRI);
321*9880d681SAndroid Build Coastguard Worker dbgs() << " live before " << *I;
322*9880d681SAndroid Build Coastguard Worker });
323*9880d681SAndroid Build Coastguard Worker continue;
324*9880d681SAndroid Build Coastguard Worker }
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker // This is a valid insertion point.
327*9880d681SAndroid Build Coastguard Worker InsertionPoint = I;
328*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Can insert before " << *I);
329*9880d681SAndroid Build Coastguard Worker return true;
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "No legal insertion point found.\n");
332*9880d681SAndroid Build Coastguard Worker return false;
333*9880d681SAndroid Build Coastguard Worker }
334*9880d681SAndroid Build Coastguard Worker
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker /// canConvertIf - analyze the sub-cfg rooted in MBB, and return true if it is
338*9880d681SAndroid Build Coastguard Worker /// a potential candidate for if-conversion. Fill out the internal state.
339*9880d681SAndroid Build Coastguard Worker ///
canConvertIf(MachineBasicBlock * MBB)340*9880d681SAndroid Build Coastguard Worker bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) {
341*9880d681SAndroid Build Coastguard Worker Head = MBB;
342*9880d681SAndroid Build Coastguard Worker TBB = FBB = Tail = nullptr;
343*9880d681SAndroid Build Coastguard Worker
344*9880d681SAndroid Build Coastguard Worker if (Head->succ_size() != 2)
345*9880d681SAndroid Build Coastguard Worker return false;
346*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Succ0 = Head->succ_begin()[0];
347*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *Succ1 = Head->succ_begin()[1];
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker // Canonicalize so Succ0 has MBB as its single predecessor.
350*9880d681SAndroid Build Coastguard Worker if (Succ0->pred_size() != 1)
351*9880d681SAndroid Build Coastguard Worker std::swap(Succ0, Succ1);
352*9880d681SAndroid Build Coastguard Worker
353*9880d681SAndroid Build Coastguard Worker if (Succ0->pred_size() != 1 || Succ0->succ_size() != 1)
354*9880d681SAndroid Build Coastguard Worker return false;
355*9880d681SAndroid Build Coastguard Worker
356*9880d681SAndroid Build Coastguard Worker Tail = Succ0->succ_begin()[0];
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker // This is not a triangle.
359*9880d681SAndroid Build Coastguard Worker if (Tail != Succ1) {
360*9880d681SAndroid Build Coastguard Worker // Check for a diamond. We won't deal with any critical edges.
361*9880d681SAndroid Build Coastguard Worker if (Succ1->pred_size() != 1 || Succ1->succ_size() != 1 ||
362*9880d681SAndroid Build Coastguard Worker Succ1->succ_begin()[0] != Tail)
363*9880d681SAndroid Build Coastguard Worker return false;
364*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\nDiamond: BB#" << Head->getNumber()
365*9880d681SAndroid Build Coastguard Worker << " -> BB#" << Succ0->getNumber()
366*9880d681SAndroid Build Coastguard Worker << "/BB#" << Succ1->getNumber()
367*9880d681SAndroid Build Coastguard Worker << " -> BB#" << Tail->getNumber() << '\n');
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker // Live-in physregs are tricky to get right when speculating code.
370*9880d681SAndroid Build Coastguard Worker if (!Tail->livein_empty()) {
371*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Tail has live-ins.\n");
372*9880d681SAndroid Build Coastguard Worker return false;
373*9880d681SAndroid Build Coastguard Worker }
374*9880d681SAndroid Build Coastguard Worker } else {
375*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "\nTriangle: BB#" << Head->getNumber()
376*9880d681SAndroid Build Coastguard Worker << " -> BB#" << Succ0->getNumber()
377*9880d681SAndroid Build Coastguard Worker << " -> BB#" << Tail->getNumber() << '\n');
378*9880d681SAndroid Build Coastguard Worker }
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker // This is a triangle or a diamond.
381*9880d681SAndroid Build Coastguard Worker // If Tail doesn't have any phis, there must be side effects.
382*9880d681SAndroid Build Coastguard Worker if (Tail->empty() || !Tail->front().isPHI()) {
383*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "No phis in tail.\n");
384*9880d681SAndroid Build Coastguard Worker return false;
385*9880d681SAndroid Build Coastguard Worker }
386*9880d681SAndroid Build Coastguard Worker
387*9880d681SAndroid Build Coastguard Worker // The branch we're looking to eliminate must be analyzable.
388*9880d681SAndroid Build Coastguard Worker Cond.clear();
389*9880d681SAndroid Build Coastguard Worker if (TII->analyzeBranch(*Head, TBB, FBB, Cond)) {
390*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Branch not analyzable.\n");
391*9880d681SAndroid Build Coastguard Worker return false;
392*9880d681SAndroid Build Coastguard Worker }
393*9880d681SAndroid Build Coastguard Worker
394*9880d681SAndroid Build Coastguard Worker // This is weird, probably some sort of degenerate CFG.
395*9880d681SAndroid Build Coastguard Worker if (!TBB) {
396*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "AnalyzeBranch didn't find conditional branch.\n");
397*9880d681SAndroid Build Coastguard Worker return false;
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker // AnalyzeBranch doesn't set FBB on a fall-through branch.
401*9880d681SAndroid Build Coastguard Worker // Make sure it is always set.
402*9880d681SAndroid Build Coastguard Worker FBB = TBB == Succ0 ? Succ1 : Succ0;
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Worker // Any phis in the tail block must be convertible to selects.
405*9880d681SAndroid Build Coastguard Worker PHIs.clear();
406*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *TPred = getTPred();
407*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *FPred = getFPred();
408*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator I = Tail->begin(), E = Tail->end();
409*9880d681SAndroid Build Coastguard Worker I != E && I->isPHI(); ++I) {
410*9880d681SAndroid Build Coastguard Worker PHIs.push_back(&*I);
411*9880d681SAndroid Build Coastguard Worker PHIInfo &PI = PHIs.back();
412*9880d681SAndroid Build Coastguard Worker // Find PHI operands corresponding to TPred and FPred.
413*9880d681SAndroid Build Coastguard Worker for (unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
414*9880d681SAndroid Build Coastguard Worker if (PI.PHI->getOperand(i+1).getMBB() == TPred)
415*9880d681SAndroid Build Coastguard Worker PI.TReg = PI.PHI->getOperand(i).getReg();
416*9880d681SAndroid Build Coastguard Worker if (PI.PHI->getOperand(i+1).getMBB() == FPred)
417*9880d681SAndroid Build Coastguard Worker PI.FReg = PI.PHI->getOperand(i).getReg();
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker assert(TargetRegisterInfo::isVirtualRegister(PI.TReg) && "Bad PHI");
420*9880d681SAndroid Build Coastguard Worker assert(TargetRegisterInfo::isVirtualRegister(PI.FReg) && "Bad PHI");
421*9880d681SAndroid Build Coastguard Worker
422*9880d681SAndroid Build Coastguard Worker // Get target information.
423*9880d681SAndroid Build Coastguard Worker if (!TII->canInsertSelect(*Head, Cond, PI.TReg, PI.FReg,
424*9880d681SAndroid Build Coastguard Worker PI.CondCycles, PI.TCycles, PI.FCycles)) {
425*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Can't convert: " << *PI.PHI);
426*9880d681SAndroid Build Coastguard Worker return false;
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker }
429*9880d681SAndroid Build Coastguard Worker
430*9880d681SAndroid Build Coastguard Worker // Check that the conditional instructions can be speculated.
431*9880d681SAndroid Build Coastguard Worker InsertAfter.clear();
432*9880d681SAndroid Build Coastguard Worker ClobberedRegUnits.reset();
433*9880d681SAndroid Build Coastguard Worker if (TBB != Tail && !canSpeculateInstrs(TBB))
434*9880d681SAndroid Build Coastguard Worker return false;
435*9880d681SAndroid Build Coastguard Worker if (FBB != Tail && !canSpeculateInstrs(FBB))
436*9880d681SAndroid Build Coastguard Worker return false;
437*9880d681SAndroid Build Coastguard Worker
438*9880d681SAndroid Build Coastguard Worker // Try to find a valid insertion point for the speculated instructions in the
439*9880d681SAndroid Build Coastguard Worker // head basic block.
440*9880d681SAndroid Build Coastguard Worker if (!findInsertionPoint())
441*9880d681SAndroid Build Coastguard Worker return false;
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker if (isTriangle())
444*9880d681SAndroid Build Coastguard Worker ++NumTrianglesSeen;
445*9880d681SAndroid Build Coastguard Worker else
446*9880d681SAndroid Build Coastguard Worker ++NumDiamondsSeen;
447*9880d681SAndroid Build Coastguard Worker return true;
448*9880d681SAndroid Build Coastguard Worker }
449*9880d681SAndroid Build Coastguard Worker
450*9880d681SAndroid Build Coastguard Worker /// replacePHIInstrs - Completely replace PHI instructions with selects.
451*9880d681SAndroid Build Coastguard Worker /// This is possible when the only Tail predecessors are the if-converted
452*9880d681SAndroid Build Coastguard Worker /// blocks.
replacePHIInstrs()453*9880d681SAndroid Build Coastguard Worker void SSAIfConv::replacePHIInstrs() {
454*9880d681SAndroid Build Coastguard Worker assert(Tail->pred_size() == 2 && "Cannot replace PHIs");
455*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
456*9880d681SAndroid Build Coastguard Worker assert(FirstTerm != Head->end() && "No terminators");
457*9880d681SAndroid Build Coastguard Worker DebugLoc HeadDL = FirstTerm->getDebugLoc();
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker // Convert all PHIs to select instructions inserted before FirstTerm.
460*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = PHIs.size(); i != e; ++i) {
461*9880d681SAndroid Build Coastguard Worker PHIInfo &PI = PHIs[i];
462*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "If-converting " << *PI.PHI);
463*9880d681SAndroid Build Coastguard Worker unsigned DstReg = PI.PHI->getOperand(0).getReg();
464*9880d681SAndroid Build Coastguard Worker TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg);
465*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << " --> " << *std::prev(FirstTerm));
466*9880d681SAndroid Build Coastguard Worker PI.PHI->eraseFromParent();
467*9880d681SAndroid Build Coastguard Worker PI.PHI = nullptr;
468*9880d681SAndroid Build Coastguard Worker }
469*9880d681SAndroid Build Coastguard Worker }
470*9880d681SAndroid Build Coastguard Worker
471*9880d681SAndroid Build Coastguard Worker /// rewritePHIOperands - When there are additional Tail predecessors, insert
472*9880d681SAndroid Build Coastguard Worker /// select instructions in Head and rewrite PHI operands to use the selects.
473*9880d681SAndroid Build Coastguard Worker /// Keep the PHI instructions in Tail to handle the other predecessors.
rewritePHIOperands()474*9880d681SAndroid Build Coastguard Worker void SSAIfConv::rewritePHIOperands() {
475*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
476*9880d681SAndroid Build Coastguard Worker assert(FirstTerm != Head->end() && "No terminators");
477*9880d681SAndroid Build Coastguard Worker DebugLoc HeadDL = FirstTerm->getDebugLoc();
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Worker // Convert all PHIs to select instructions inserted before FirstTerm.
480*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = PHIs.size(); i != e; ++i) {
481*9880d681SAndroid Build Coastguard Worker PHIInfo &PI = PHIs[i];
482*9880d681SAndroid Build Coastguard Worker unsigned DstReg = 0;
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "If-converting " << *PI.PHI);
485*9880d681SAndroid Build Coastguard Worker if (PI.TReg == PI.FReg) {
486*9880d681SAndroid Build Coastguard Worker // We do not need the select instruction if both incoming values are
487*9880d681SAndroid Build Coastguard Worker // equal.
488*9880d681SAndroid Build Coastguard Worker DstReg = PI.TReg;
489*9880d681SAndroid Build Coastguard Worker } else {
490*9880d681SAndroid Build Coastguard Worker unsigned PHIDst = PI.PHI->getOperand(0).getReg();
491*9880d681SAndroid Build Coastguard Worker DstReg = MRI->createVirtualRegister(MRI->getRegClass(PHIDst));
492*9880d681SAndroid Build Coastguard Worker TII->insertSelect(*Head, FirstTerm, HeadDL,
493*9880d681SAndroid Build Coastguard Worker DstReg, Cond, PI.TReg, PI.FReg);
494*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << " --> " << *std::prev(FirstTerm));
495*9880d681SAndroid Build Coastguard Worker }
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker // Rewrite PHI operands TPred -> (DstReg, Head), remove FPred.
498*9880d681SAndroid Build Coastguard Worker for (unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
499*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *MBB = PI.PHI->getOperand(i-1).getMBB();
500*9880d681SAndroid Build Coastguard Worker if (MBB == getTPred()) {
501*9880d681SAndroid Build Coastguard Worker PI.PHI->getOperand(i-1).setMBB(Head);
502*9880d681SAndroid Build Coastguard Worker PI.PHI->getOperand(i-2).setReg(DstReg);
503*9880d681SAndroid Build Coastguard Worker } else if (MBB == getFPred()) {
504*9880d681SAndroid Build Coastguard Worker PI.PHI->RemoveOperand(i-1);
505*9880d681SAndroid Build Coastguard Worker PI.PHI->RemoveOperand(i-2);
506*9880d681SAndroid Build Coastguard Worker }
507*9880d681SAndroid Build Coastguard Worker }
508*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << " --> " << *PI.PHI);
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker }
511*9880d681SAndroid Build Coastguard Worker
512*9880d681SAndroid Build Coastguard Worker /// convertIf - Execute the if conversion after canConvertIf has determined the
513*9880d681SAndroid Build Coastguard Worker /// feasibility.
514*9880d681SAndroid Build Coastguard Worker ///
515*9880d681SAndroid Build Coastguard Worker /// Any basic blocks erased will be added to RemovedBlocks.
516*9880d681SAndroid Build Coastguard Worker ///
convertIf(SmallVectorImpl<MachineBasicBlock * > & RemovedBlocks)517*9880d681SAndroid Build Coastguard Worker void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock*> &RemovedBlocks) {
518*9880d681SAndroid Build Coastguard Worker assert(Head && Tail && TBB && FBB && "Call canConvertIf first.");
519*9880d681SAndroid Build Coastguard Worker
520*9880d681SAndroid Build Coastguard Worker // Update statistics.
521*9880d681SAndroid Build Coastguard Worker if (isTriangle())
522*9880d681SAndroid Build Coastguard Worker ++NumTrianglesConv;
523*9880d681SAndroid Build Coastguard Worker else
524*9880d681SAndroid Build Coastguard Worker ++NumDiamondsConv;
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker // Move all instructions into Head, except for the terminators.
527*9880d681SAndroid Build Coastguard Worker if (TBB != Tail)
528*9880d681SAndroid Build Coastguard Worker Head->splice(InsertionPoint, TBB, TBB->begin(), TBB->getFirstTerminator());
529*9880d681SAndroid Build Coastguard Worker if (FBB != Tail)
530*9880d681SAndroid Build Coastguard Worker Head->splice(InsertionPoint, FBB, FBB->begin(), FBB->getFirstTerminator());
531*9880d681SAndroid Build Coastguard Worker
532*9880d681SAndroid Build Coastguard Worker // Are there extra Tail predecessors?
533*9880d681SAndroid Build Coastguard Worker bool ExtraPreds = Tail->pred_size() != 2;
534*9880d681SAndroid Build Coastguard Worker if (ExtraPreds)
535*9880d681SAndroid Build Coastguard Worker rewritePHIOperands();
536*9880d681SAndroid Build Coastguard Worker else
537*9880d681SAndroid Build Coastguard Worker replacePHIInstrs();
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Worker // Fix up the CFG, temporarily leave Head without any successors.
540*9880d681SAndroid Build Coastguard Worker Head->removeSuccessor(TBB);
541*9880d681SAndroid Build Coastguard Worker Head->removeSuccessor(FBB, true);
542*9880d681SAndroid Build Coastguard Worker if (TBB != Tail)
543*9880d681SAndroid Build Coastguard Worker TBB->removeSuccessor(Tail, true);
544*9880d681SAndroid Build Coastguard Worker if (FBB != Tail)
545*9880d681SAndroid Build Coastguard Worker FBB->removeSuccessor(Tail, true);
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker // Fix up Head's terminators.
548*9880d681SAndroid Build Coastguard Worker // It should become a single branch or a fallthrough.
549*9880d681SAndroid Build Coastguard Worker DebugLoc HeadDL = Head->getFirstTerminator()->getDebugLoc();
550*9880d681SAndroid Build Coastguard Worker TII->RemoveBranch(*Head);
551*9880d681SAndroid Build Coastguard Worker
552*9880d681SAndroid Build Coastguard Worker // Erase the now empty conditional blocks. It is likely that Head can fall
553*9880d681SAndroid Build Coastguard Worker // through to Tail, and we can join the two blocks.
554*9880d681SAndroid Build Coastguard Worker if (TBB != Tail) {
555*9880d681SAndroid Build Coastguard Worker RemovedBlocks.push_back(TBB);
556*9880d681SAndroid Build Coastguard Worker TBB->eraseFromParent();
557*9880d681SAndroid Build Coastguard Worker }
558*9880d681SAndroid Build Coastguard Worker if (FBB != Tail) {
559*9880d681SAndroid Build Coastguard Worker RemovedBlocks.push_back(FBB);
560*9880d681SAndroid Build Coastguard Worker FBB->eraseFromParent();
561*9880d681SAndroid Build Coastguard Worker }
562*9880d681SAndroid Build Coastguard Worker
563*9880d681SAndroid Build Coastguard Worker assert(Head->succ_empty() && "Additional head successors?");
564*9880d681SAndroid Build Coastguard Worker if (!ExtraPreds && Head->isLayoutSuccessor(Tail)) {
565*9880d681SAndroid Build Coastguard Worker // Splice Tail onto the end of Head.
566*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Joining tail BB#" << Tail->getNumber()
567*9880d681SAndroid Build Coastguard Worker << " into head BB#" << Head->getNumber() << '\n');
568*9880d681SAndroid Build Coastguard Worker Head->splice(Head->end(), Tail,
569*9880d681SAndroid Build Coastguard Worker Tail->begin(), Tail->end());
570*9880d681SAndroid Build Coastguard Worker Head->transferSuccessorsAndUpdatePHIs(Tail);
571*9880d681SAndroid Build Coastguard Worker RemovedBlocks.push_back(Tail);
572*9880d681SAndroid Build Coastguard Worker Tail->eraseFromParent();
573*9880d681SAndroid Build Coastguard Worker } else {
574*9880d681SAndroid Build Coastguard Worker // We need a branch to Tail, let code placement work it out later.
575*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Converting to unconditional branch.\n");
576*9880d681SAndroid Build Coastguard Worker SmallVector<MachineOperand, 0> EmptyCond;
577*9880d681SAndroid Build Coastguard Worker TII->InsertBranch(*Head, Tail, nullptr, EmptyCond, HeadDL);
578*9880d681SAndroid Build Coastguard Worker Head->addSuccessor(Tail);
579*9880d681SAndroid Build Coastguard Worker }
580*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << *Head);
581*9880d681SAndroid Build Coastguard Worker }
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Worker
584*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
585*9880d681SAndroid Build Coastguard Worker // EarlyIfConverter Pass
586*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
587*9880d681SAndroid Build Coastguard Worker
588*9880d681SAndroid Build Coastguard Worker namespace {
589*9880d681SAndroid Build Coastguard Worker class EarlyIfConverter : public MachineFunctionPass {
590*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII;
591*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI;
592*9880d681SAndroid Build Coastguard Worker MCSchedModel SchedModel;
593*9880d681SAndroid Build Coastguard Worker MachineRegisterInfo *MRI;
594*9880d681SAndroid Build Coastguard Worker MachineDominatorTree *DomTree;
595*9880d681SAndroid Build Coastguard Worker MachineLoopInfo *Loops;
596*9880d681SAndroid Build Coastguard Worker MachineTraceMetrics *Traces;
597*9880d681SAndroid Build Coastguard Worker MachineTraceMetrics::Ensemble *MinInstr;
598*9880d681SAndroid Build Coastguard Worker SSAIfConv IfConv;
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Worker public:
601*9880d681SAndroid Build Coastguard Worker static char ID;
EarlyIfConverter()602*9880d681SAndroid Build Coastguard Worker EarlyIfConverter() : MachineFunctionPass(ID) {}
603*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override;
604*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
getPassName() const605*9880d681SAndroid Build Coastguard Worker const char *getPassName() const override { return "Early If-Conversion"; }
606*9880d681SAndroid Build Coastguard Worker
607*9880d681SAndroid Build Coastguard Worker private:
608*9880d681SAndroid Build Coastguard Worker bool tryConvertIf(MachineBasicBlock*);
609*9880d681SAndroid Build Coastguard Worker void updateDomTree(ArrayRef<MachineBasicBlock*> Removed);
610*9880d681SAndroid Build Coastguard Worker void updateLoops(ArrayRef<MachineBasicBlock*> Removed);
611*9880d681SAndroid Build Coastguard Worker void invalidateTraces();
612*9880d681SAndroid Build Coastguard Worker bool shouldConvertIf();
613*9880d681SAndroid Build Coastguard Worker };
614*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
615*9880d681SAndroid Build Coastguard Worker
616*9880d681SAndroid Build Coastguard Worker char EarlyIfConverter::ID = 0;
617*9880d681SAndroid Build Coastguard Worker char &llvm::EarlyIfConverterID = EarlyIfConverter::ID;
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_BEGIN(EarlyIfConverter,
620*9880d681SAndroid Build Coastguard Worker "early-ifcvt", "Early If Converter", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)621*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
622*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
623*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_DEPENDENCY(MachineTraceMetrics)
624*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS_END(EarlyIfConverter,
625*9880d681SAndroid Build Coastguard Worker "early-ifcvt", "Early If Converter", false, false)
626*9880d681SAndroid Build Coastguard Worker
627*9880d681SAndroid Build Coastguard Worker void EarlyIfConverter::getAnalysisUsage(AnalysisUsage &AU) const {
628*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineBranchProbabilityInfo>();
629*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineDominatorTree>();
630*9880d681SAndroid Build Coastguard Worker AU.addPreserved<MachineDominatorTree>();
631*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineLoopInfo>();
632*9880d681SAndroid Build Coastguard Worker AU.addPreserved<MachineLoopInfo>();
633*9880d681SAndroid Build Coastguard Worker AU.addRequired<MachineTraceMetrics>();
634*9880d681SAndroid Build Coastguard Worker AU.addPreserved<MachineTraceMetrics>();
635*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
636*9880d681SAndroid Build Coastguard Worker }
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker /// Update the dominator tree after if-conversion erased some blocks.
updateDomTree(ArrayRef<MachineBasicBlock * > Removed)639*9880d681SAndroid Build Coastguard Worker void EarlyIfConverter::updateDomTree(ArrayRef<MachineBasicBlock*> Removed) {
640*9880d681SAndroid Build Coastguard Worker // convertIf can remove TBB, FBB, and Tail can be merged into Head.
641*9880d681SAndroid Build Coastguard Worker // TBB and FBB should not dominate any blocks.
642*9880d681SAndroid Build Coastguard Worker // Tail children should be transferred to Head.
643*9880d681SAndroid Build Coastguard Worker MachineDomTreeNode *HeadNode = DomTree->getNode(IfConv.Head);
644*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Removed.size(); i != e; ++i) {
645*9880d681SAndroid Build Coastguard Worker MachineDomTreeNode *Node = DomTree->getNode(Removed[i]);
646*9880d681SAndroid Build Coastguard Worker assert(Node != HeadNode && "Cannot erase the head node");
647*9880d681SAndroid Build Coastguard Worker while (Node->getNumChildren()) {
648*9880d681SAndroid Build Coastguard Worker assert(Node->getBlock() == IfConv.Tail && "Unexpected children");
649*9880d681SAndroid Build Coastguard Worker DomTree->changeImmediateDominator(Node->getChildren().back(), HeadNode);
650*9880d681SAndroid Build Coastguard Worker }
651*9880d681SAndroid Build Coastguard Worker DomTree->eraseNode(Removed[i]);
652*9880d681SAndroid Build Coastguard Worker }
653*9880d681SAndroid Build Coastguard Worker }
654*9880d681SAndroid Build Coastguard Worker
655*9880d681SAndroid Build Coastguard Worker /// Update LoopInfo after if-conversion.
updateLoops(ArrayRef<MachineBasicBlock * > Removed)656*9880d681SAndroid Build Coastguard Worker void EarlyIfConverter::updateLoops(ArrayRef<MachineBasicBlock*> Removed) {
657*9880d681SAndroid Build Coastguard Worker if (!Loops)
658*9880d681SAndroid Build Coastguard Worker return;
659*9880d681SAndroid Build Coastguard Worker // If-conversion doesn't change loop structure, and it doesn't mess with back
660*9880d681SAndroid Build Coastguard Worker // edges, so updating LoopInfo is simply removing the dead blocks.
661*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Removed.size(); i != e; ++i)
662*9880d681SAndroid Build Coastguard Worker Loops->removeBlock(Removed[i]);
663*9880d681SAndroid Build Coastguard Worker }
664*9880d681SAndroid Build Coastguard Worker
665*9880d681SAndroid Build Coastguard Worker /// Invalidate MachineTraceMetrics before if-conversion.
invalidateTraces()666*9880d681SAndroid Build Coastguard Worker void EarlyIfConverter::invalidateTraces() {
667*9880d681SAndroid Build Coastguard Worker Traces->verifyAnalysis();
668*9880d681SAndroid Build Coastguard Worker Traces->invalidate(IfConv.Head);
669*9880d681SAndroid Build Coastguard Worker Traces->invalidate(IfConv.Tail);
670*9880d681SAndroid Build Coastguard Worker Traces->invalidate(IfConv.TBB);
671*9880d681SAndroid Build Coastguard Worker Traces->invalidate(IfConv.FBB);
672*9880d681SAndroid Build Coastguard Worker Traces->verifyAnalysis();
673*9880d681SAndroid Build Coastguard Worker }
674*9880d681SAndroid Build Coastguard Worker
675*9880d681SAndroid Build Coastguard Worker // Adjust cycles with downward saturation.
adjCycles(unsigned Cyc,int Delta)676*9880d681SAndroid Build Coastguard Worker static unsigned adjCycles(unsigned Cyc, int Delta) {
677*9880d681SAndroid Build Coastguard Worker if (Delta < 0 && Cyc + Delta > Cyc)
678*9880d681SAndroid Build Coastguard Worker return 0;
679*9880d681SAndroid Build Coastguard Worker return Cyc + Delta;
680*9880d681SAndroid Build Coastguard Worker }
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Worker /// Apply cost model and heuristics to the if-conversion in IfConv.
683*9880d681SAndroid Build Coastguard Worker /// Return true if the conversion is a good idea.
684*9880d681SAndroid Build Coastguard Worker ///
shouldConvertIf()685*9880d681SAndroid Build Coastguard Worker bool EarlyIfConverter::shouldConvertIf() {
686*9880d681SAndroid Build Coastguard Worker // Stress testing mode disables all cost considerations.
687*9880d681SAndroid Build Coastguard Worker if (Stress)
688*9880d681SAndroid Build Coastguard Worker return true;
689*9880d681SAndroid Build Coastguard Worker
690*9880d681SAndroid Build Coastguard Worker if (!MinInstr)
691*9880d681SAndroid Build Coastguard Worker MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
692*9880d681SAndroid Build Coastguard Worker
693*9880d681SAndroid Build Coastguard Worker MachineTraceMetrics::Trace TBBTrace = MinInstr->getTrace(IfConv.getTPred());
694*9880d681SAndroid Build Coastguard Worker MachineTraceMetrics::Trace FBBTrace = MinInstr->getTrace(IfConv.getFPred());
695*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "TBB: " << TBBTrace << "FBB: " << FBBTrace);
696*9880d681SAndroid Build Coastguard Worker unsigned MinCrit = std::min(TBBTrace.getCriticalPath(),
697*9880d681SAndroid Build Coastguard Worker FBBTrace.getCriticalPath());
698*9880d681SAndroid Build Coastguard Worker
699*9880d681SAndroid Build Coastguard Worker // Set a somewhat arbitrary limit on the critical path extension we accept.
700*9880d681SAndroid Build Coastguard Worker unsigned CritLimit = SchedModel.MispredictPenalty/2;
701*9880d681SAndroid Build Coastguard Worker
702*9880d681SAndroid Build Coastguard Worker // If-conversion only makes sense when there is unexploited ILP. Compute the
703*9880d681SAndroid Build Coastguard Worker // maximum-ILP resource length of the trace after if-conversion. Compare it
704*9880d681SAndroid Build Coastguard Worker // to the shortest critical path.
705*9880d681SAndroid Build Coastguard Worker SmallVector<const MachineBasicBlock*, 1> ExtraBlocks;
706*9880d681SAndroid Build Coastguard Worker if (IfConv.TBB != IfConv.Tail)
707*9880d681SAndroid Build Coastguard Worker ExtraBlocks.push_back(IfConv.TBB);
708*9880d681SAndroid Build Coastguard Worker unsigned ResLength = FBBTrace.getResourceLength(ExtraBlocks);
709*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Resource length " << ResLength
710*9880d681SAndroid Build Coastguard Worker << ", minimal critical path " << MinCrit << '\n');
711*9880d681SAndroid Build Coastguard Worker if (ResLength > MinCrit + CritLimit) {
712*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Not enough available ILP.\n");
713*9880d681SAndroid Build Coastguard Worker return false;
714*9880d681SAndroid Build Coastguard Worker }
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker // Assume that the depth of the first head terminator will also be the depth
717*9880d681SAndroid Build Coastguard Worker // of the select instruction inserted, as determined by the flag dependency.
718*9880d681SAndroid Build Coastguard Worker // TBB / FBB data dependencies may delay the select even more.
719*9880d681SAndroid Build Coastguard Worker MachineTraceMetrics::Trace HeadTrace = MinInstr->getTrace(IfConv.Head);
720*9880d681SAndroid Build Coastguard Worker unsigned BranchDepth =
721*9880d681SAndroid Build Coastguard Worker HeadTrace.getInstrCycles(*IfConv.Head->getFirstTerminator()).Depth;
722*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Branch depth: " << BranchDepth << '\n');
723*9880d681SAndroid Build Coastguard Worker
724*9880d681SAndroid Build Coastguard Worker // Look at all the tail phis, and compute the critical path extension caused
725*9880d681SAndroid Build Coastguard Worker // by inserting select instructions.
726*9880d681SAndroid Build Coastguard Worker MachineTraceMetrics::Trace TailTrace = MinInstr->getTrace(IfConv.Tail);
727*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = IfConv.PHIs.size(); i != e; ++i) {
728*9880d681SAndroid Build Coastguard Worker SSAIfConv::PHIInfo &PI = IfConv.PHIs[i];
729*9880d681SAndroid Build Coastguard Worker unsigned Slack = TailTrace.getInstrSlack(*PI.PHI);
730*9880d681SAndroid Build Coastguard Worker unsigned MaxDepth = Slack + TailTrace.getInstrCycles(*PI.PHI).Depth;
731*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Slack " << Slack << ":\t" << *PI.PHI);
732*9880d681SAndroid Build Coastguard Worker
733*9880d681SAndroid Build Coastguard Worker // The condition is pulled into the critical path.
734*9880d681SAndroid Build Coastguard Worker unsigned CondDepth = adjCycles(BranchDepth, PI.CondCycles);
735*9880d681SAndroid Build Coastguard Worker if (CondDepth > MaxDepth) {
736*9880d681SAndroid Build Coastguard Worker unsigned Extra = CondDepth - MaxDepth;
737*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Condition adds " << Extra << " cycles.\n");
738*9880d681SAndroid Build Coastguard Worker if (Extra > CritLimit) {
739*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
740*9880d681SAndroid Build Coastguard Worker return false;
741*9880d681SAndroid Build Coastguard Worker }
742*9880d681SAndroid Build Coastguard Worker }
743*9880d681SAndroid Build Coastguard Worker
744*9880d681SAndroid Build Coastguard Worker // The TBB value is pulled into the critical path.
745*9880d681SAndroid Build Coastguard Worker unsigned TDepth = adjCycles(TBBTrace.getPHIDepth(*PI.PHI), PI.TCycles);
746*9880d681SAndroid Build Coastguard Worker if (TDepth > MaxDepth) {
747*9880d681SAndroid Build Coastguard Worker unsigned Extra = TDepth - MaxDepth;
748*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "TBB data adds " << Extra << " cycles.\n");
749*9880d681SAndroid Build Coastguard Worker if (Extra > CritLimit) {
750*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
751*9880d681SAndroid Build Coastguard Worker return false;
752*9880d681SAndroid Build Coastguard Worker }
753*9880d681SAndroid Build Coastguard Worker }
754*9880d681SAndroid Build Coastguard Worker
755*9880d681SAndroid Build Coastguard Worker // The FBB value is pulled into the critical path.
756*9880d681SAndroid Build Coastguard Worker unsigned FDepth = adjCycles(FBBTrace.getPHIDepth(*PI.PHI), PI.FCycles);
757*9880d681SAndroid Build Coastguard Worker if (FDepth > MaxDepth) {
758*9880d681SAndroid Build Coastguard Worker unsigned Extra = FDepth - MaxDepth;
759*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "FBB data adds " << Extra << " cycles.\n");
760*9880d681SAndroid Build Coastguard Worker if (Extra > CritLimit) {
761*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
762*9880d681SAndroid Build Coastguard Worker return false;
763*9880d681SAndroid Build Coastguard Worker }
764*9880d681SAndroid Build Coastguard Worker }
765*9880d681SAndroid Build Coastguard Worker }
766*9880d681SAndroid Build Coastguard Worker return true;
767*9880d681SAndroid Build Coastguard Worker }
768*9880d681SAndroid Build Coastguard Worker
769*9880d681SAndroid Build Coastguard Worker /// Attempt repeated if-conversion on MBB, return true if successful.
770*9880d681SAndroid Build Coastguard Worker ///
tryConvertIf(MachineBasicBlock * MBB)771*9880d681SAndroid Build Coastguard Worker bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *MBB) {
772*9880d681SAndroid Build Coastguard Worker bool Changed = false;
773*9880d681SAndroid Build Coastguard Worker while (IfConv.canConvertIf(MBB) && shouldConvertIf()) {
774*9880d681SAndroid Build Coastguard Worker // If-convert MBB and update analyses.
775*9880d681SAndroid Build Coastguard Worker invalidateTraces();
776*9880d681SAndroid Build Coastguard Worker SmallVector<MachineBasicBlock*, 4> RemovedBlocks;
777*9880d681SAndroid Build Coastguard Worker IfConv.convertIf(RemovedBlocks);
778*9880d681SAndroid Build Coastguard Worker Changed = true;
779*9880d681SAndroid Build Coastguard Worker updateDomTree(RemovedBlocks);
780*9880d681SAndroid Build Coastguard Worker updateLoops(RemovedBlocks);
781*9880d681SAndroid Build Coastguard Worker }
782*9880d681SAndroid Build Coastguard Worker return Changed;
783*9880d681SAndroid Build Coastguard Worker }
784*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)785*9880d681SAndroid Build Coastguard Worker bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
786*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "********** EARLY IF-CONVERSION **********\n"
787*9880d681SAndroid Build Coastguard Worker << "********** Function: " << MF.getName() << '\n');
788*9880d681SAndroid Build Coastguard Worker if (skipFunction(*MF.getFunction()))
789*9880d681SAndroid Build Coastguard Worker return false;
790*9880d681SAndroid Build Coastguard Worker
791*9880d681SAndroid Build Coastguard Worker // Only run if conversion if the target wants it.
792*9880d681SAndroid Build Coastguard Worker const TargetSubtargetInfo &STI = MF.getSubtarget();
793*9880d681SAndroid Build Coastguard Worker if (!STI.enableEarlyIfConversion())
794*9880d681SAndroid Build Coastguard Worker return false;
795*9880d681SAndroid Build Coastguard Worker
796*9880d681SAndroid Build Coastguard Worker TII = STI.getInstrInfo();
797*9880d681SAndroid Build Coastguard Worker TRI = STI.getRegisterInfo();
798*9880d681SAndroid Build Coastguard Worker SchedModel = STI.getSchedModel();
799*9880d681SAndroid Build Coastguard Worker MRI = &MF.getRegInfo();
800*9880d681SAndroid Build Coastguard Worker DomTree = &getAnalysis<MachineDominatorTree>();
801*9880d681SAndroid Build Coastguard Worker Loops = getAnalysisIfAvailable<MachineLoopInfo>();
802*9880d681SAndroid Build Coastguard Worker Traces = &getAnalysis<MachineTraceMetrics>();
803*9880d681SAndroid Build Coastguard Worker MinInstr = nullptr;
804*9880d681SAndroid Build Coastguard Worker
805*9880d681SAndroid Build Coastguard Worker bool Changed = false;
806*9880d681SAndroid Build Coastguard Worker IfConv.runOnMachineFunction(MF);
807*9880d681SAndroid Build Coastguard Worker
808*9880d681SAndroid Build Coastguard Worker // Visit blocks in dominator tree post-order. The post-order enables nested
809*9880d681SAndroid Build Coastguard Worker // if-conversion in a single pass. The tryConvertIf() function may erase
810*9880d681SAndroid Build Coastguard Worker // blocks, but only blocks dominated by the head block. This makes it safe to
811*9880d681SAndroid Build Coastguard Worker // update the dominator tree while the post-order iterator is still active.
812*9880d681SAndroid Build Coastguard Worker for (auto DomNode : post_order(DomTree))
813*9880d681SAndroid Build Coastguard Worker if (tryConvertIf(DomNode->getBlock()))
814*9880d681SAndroid Build Coastguard Worker Changed = true;
815*9880d681SAndroid Build Coastguard Worker
816*9880d681SAndroid Build Coastguard Worker return Changed;
817*9880d681SAndroid Build Coastguard Worker }
818