17ae0e2c9SDimitry Andric //===-- EarlyIfConversion.cpp - If-conversion on SSA form machine code ----===//
27ae0e2c9SDimitry Andric //
37ae0e2c9SDimitry Andric // The LLVM Compiler Infrastructure
47ae0e2c9SDimitry Andric //
57ae0e2c9SDimitry Andric // This file is distributed under the University of Illinois Open Source
67ae0e2c9SDimitry Andric // License. See LICENSE.TXT for details.
77ae0e2c9SDimitry Andric //
87ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
97ae0e2c9SDimitry Andric //
107ae0e2c9SDimitry Andric // Early if-conversion is for out-of-order CPUs that don't have a lot of
117ae0e2c9SDimitry Andric // predicable instructions. The goal is to eliminate conditional branches that
127ae0e2c9SDimitry Andric // may mispredict.
137ae0e2c9SDimitry Andric //
147ae0e2c9SDimitry Andric // Instructions from both sides of the branch are executed specutatively, and a
157ae0e2c9SDimitry Andric // cmov instruction selects the result.
167ae0e2c9SDimitry Andric //
177ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
187ae0e2c9SDimitry Andric
197ae0e2c9SDimitry Andric #include "llvm/ADT/BitVector.h"
207ae0e2c9SDimitry Andric #include "llvm/ADT/PostOrderIterator.h"
217ae0e2c9SDimitry Andric #include "llvm/ADT/SetVector.h"
227ae0e2c9SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
237ae0e2c9SDimitry Andric #include "llvm/ADT/SparseSet.h"
247ae0e2c9SDimitry Andric #include "llvm/ADT/Statistic.h"
257ae0e2c9SDimitry Andric #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
267ae0e2c9SDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
277ae0e2c9SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
287ae0e2c9SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
297ae0e2c9SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
307ae0e2c9SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
31139f7f9bSDimitry Andric #include "llvm/CodeGen/MachineTraceMetrics.h"
327ae0e2c9SDimitry Andric #include "llvm/CodeGen/Passes.h"
332cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
342cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
352cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
367ae0e2c9SDimitry Andric #include "llvm/Support/CommandLine.h"
377ae0e2c9SDimitry Andric #include "llvm/Support/Debug.h"
387ae0e2c9SDimitry Andric #include "llvm/Support/raw_ostream.h"
397ae0e2c9SDimitry Andric
407ae0e2c9SDimitry Andric using namespace llvm;
417ae0e2c9SDimitry Andric
4291bc56edSDimitry Andric #define DEBUG_TYPE "early-ifcvt"
4391bc56edSDimitry Andric
447ae0e2c9SDimitry Andric // Absolute maximum number of instructions allowed per speculated block.
457ae0e2c9SDimitry Andric // This bypasses all other heuristics, so it should be set fairly high.
467ae0e2c9SDimitry Andric static cl::opt<unsigned>
477ae0e2c9SDimitry Andric BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden,
487ae0e2c9SDimitry Andric cl::desc("Maximum number of instructions per speculated block."));
497ae0e2c9SDimitry Andric
507ae0e2c9SDimitry Andric // Stress testing mode - disable heuristics.
517ae0e2c9SDimitry Andric static cl::opt<bool> Stress("stress-early-ifcvt", cl::Hidden,
527ae0e2c9SDimitry Andric cl::desc("Turn all knobs to 11"));
537ae0e2c9SDimitry Andric
547ae0e2c9SDimitry Andric STATISTIC(NumDiamondsSeen, "Number of diamonds");
557ae0e2c9SDimitry Andric STATISTIC(NumDiamondsConv, "Number of diamonds converted");
567ae0e2c9SDimitry Andric STATISTIC(NumTrianglesSeen, "Number of triangles");
577ae0e2c9SDimitry Andric STATISTIC(NumTrianglesConv, "Number of triangles converted");
587ae0e2c9SDimitry Andric
597ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
607ae0e2c9SDimitry Andric // SSAIfConv
617ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
627ae0e2c9SDimitry Andric //
637ae0e2c9SDimitry Andric // The SSAIfConv class performs if-conversion on SSA form machine code after
647ae0e2c9SDimitry Andric // determining if it is possible. The class contains no heuristics; external
657ae0e2c9SDimitry Andric // code should be used to determine when if-conversion is a good idea.
667ae0e2c9SDimitry Andric //
677ae0e2c9SDimitry Andric // SSAIfConv can convert both triangles and diamonds:
687ae0e2c9SDimitry Andric //
697ae0e2c9SDimitry Andric // Triangle: Head Diamond: Head
707ae0e2c9SDimitry Andric // | \ / \_
717ae0e2c9SDimitry Andric // | \ / |
727ae0e2c9SDimitry Andric // | [TF]BB FBB TBB
737ae0e2c9SDimitry Andric // | / \ /
747ae0e2c9SDimitry Andric // | / \ /
757ae0e2c9SDimitry Andric // Tail Tail
767ae0e2c9SDimitry Andric //
777ae0e2c9SDimitry Andric // Instructions in the conditional blocks TBB and/or FBB are spliced into the
787ae0e2c9SDimitry Andric // Head block, and phis in the Tail block are converted to select instructions.
797ae0e2c9SDimitry Andric //
807ae0e2c9SDimitry Andric namespace {
817ae0e2c9SDimitry Andric class SSAIfConv {
827ae0e2c9SDimitry Andric const TargetInstrInfo *TII;
837ae0e2c9SDimitry Andric const TargetRegisterInfo *TRI;
847ae0e2c9SDimitry Andric MachineRegisterInfo *MRI;
857ae0e2c9SDimitry Andric
867ae0e2c9SDimitry Andric public:
877ae0e2c9SDimitry Andric /// The block containing the conditional branch.
887ae0e2c9SDimitry Andric MachineBasicBlock *Head;
897ae0e2c9SDimitry Andric
907ae0e2c9SDimitry Andric /// The block containing phis after the if-then-else.
917ae0e2c9SDimitry Andric MachineBasicBlock *Tail;
927ae0e2c9SDimitry Andric
937ae0e2c9SDimitry Andric /// The 'true' conditional block as determined by AnalyzeBranch.
947ae0e2c9SDimitry Andric MachineBasicBlock *TBB;
957ae0e2c9SDimitry Andric
967ae0e2c9SDimitry Andric /// The 'false' conditional block as determined by AnalyzeBranch.
977ae0e2c9SDimitry Andric MachineBasicBlock *FBB;
987ae0e2c9SDimitry Andric
997ae0e2c9SDimitry Andric /// isTriangle - When there is no 'else' block, either TBB or FBB will be
1007ae0e2c9SDimitry Andric /// equal to Tail.
isTriangle() const1017ae0e2c9SDimitry Andric bool isTriangle() const { return TBB == Tail || FBB == Tail; }
1027ae0e2c9SDimitry Andric
1037ae0e2c9SDimitry Andric /// Returns the Tail predecessor for the True side.
getTPred() const1047ae0e2c9SDimitry Andric MachineBasicBlock *getTPred() const { return TBB == Tail ? Head : TBB; }
1057ae0e2c9SDimitry Andric
1067ae0e2c9SDimitry Andric /// Returns the Tail predecessor for the False side.
getFPred() const1077ae0e2c9SDimitry Andric MachineBasicBlock *getFPred() const { return FBB == Tail ? Head : FBB; }
1087ae0e2c9SDimitry Andric
1097ae0e2c9SDimitry Andric /// Information about each phi in the Tail block.
1107ae0e2c9SDimitry Andric struct PHIInfo {
1117ae0e2c9SDimitry Andric MachineInstr *PHI;
1127ae0e2c9SDimitry Andric unsigned TReg, FReg;
1137ae0e2c9SDimitry Andric // Latencies from Cond+Branch, TReg, and FReg to DstReg.
1147ae0e2c9SDimitry Andric int CondCycles, TCycles, FCycles;
1157ae0e2c9SDimitry Andric
PHIInfo__anon398718eb0111::SSAIfConv::PHIInfo1167ae0e2c9SDimitry Andric PHIInfo(MachineInstr *phi)
1177ae0e2c9SDimitry Andric : PHI(phi), TReg(0), FReg(0), CondCycles(0), TCycles(0), FCycles(0) {}
1187ae0e2c9SDimitry Andric };
1197ae0e2c9SDimitry Andric
1207ae0e2c9SDimitry Andric SmallVector<PHIInfo, 8> PHIs;
1217ae0e2c9SDimitry Andric
1227ae0e2c9SDimitry Andric private:
1237ae0e2c9SDimitry Andric /// The branch condition determined by AnalyzeBranch.
1247ae0e2c9SDimitry Andric SmallVector<MachineOperand, 4> Cond;
1257ae0e2c9SDimitry Andric
1267ae0e2c9SDimitry Andric /// Instructions in Head that define values used by the conditional blocks.
1277ae0e2c9SDimitry Andric /// The hoisted instructions must be inserted after these instructions.
1287ae0e2c9SDimitry Andric SmallPtrSet<MachineInstr*, 8> InsertAfter;
1297ae0e2c9SDimitry Andric
1307ae0e2c9SDimitry Andric /// Register units clobbered by the conditional blocks.
1317ae0e2c9SDimitry Andric BitVector ClobberedRegUnits;
1327ae0e2c9SDimitry Andric
1337ae0e2c9SDimitry Andric // Scratch pad for findInsertionPoint.
1347ae0e2c9SDimitry Andric SparseSet<unsigned> LiveRegUnits;
1357ae0e2c9SDimitry Andric
1367ae0e2c9SDimitry Andric /// Insertion point in Head for speculatively executed instructions form TBB
1377ae0e2c9SDimitry Andric /// and FBB.
1387ae0e2c9SDimitry Andric MachineBasicBlock::iterator InsertionPoint;
1397ae0e2c9SDimitry Andric
1407ae0e2c9SDimitry Andric /// Return true if all non-terminator instructions in MBB can be safely
1417ae0e2c9SDimitry Andric /// speculated.
1427ae0e2c9SDimitry Andric bool canSpeculateInstrs(MachineBasicBlock *MBB);
1437ae0e2c9SDimitry Andric
1447ae0e2c9SDimitry Andric /// Find a valid insertion point in Head.
1457ae0e2c9SDimitry Andric bool findInsertionPoint();
1467ae0e2c9SDimitry Andric
1477ae0e2c9SDimitry Andric /// Replace PHI instructions in Tail with selects.
1487ae0e2c9SDimitry Andric void replacePHIInstrs();
1497ae0e2c9SDimitry Andric
1507ae0e2c9SDimitry Andric /// Insert selects and rewrite PHI operands to use them.
1517ae0e2c9SDimitry Andric void rewritePHIOperands();
1527ae0e2c9SDimitry Andric
1537ae0e2c9SDimitry Andric public:
1547ae0e2c9SDimitry Andric /// runOnMachineFunction - Initialize per-function data structures.
runOnMachineFunction(MachineFunction & MF)1557ae0e2c9SDimitry Andric void runOnMachineFunction(MachineFunction &MF) {
15639d628a0SDimitry Andric TII = MF.getSubtarget().getInstrInfo();
15739d628a0SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo();
1587ae0e2c9SDimitry Andric MRI = &MF.getRegInfo();
1597ae0e2c9SDimitry Andric LiveRegUnits.clear();
1607ae0e2c9SDimitry Andric LiveRegUnits.setUniverse(TRI->getNumRegUnits());
1617ae0e2c9SDimitry Andric ClobberedRegUnits.clear();
1627ae0e2c9SDimitry Andric ClobberedRegUnits.resize(TRI->getNumRegUnits());
1637ae0e2c9SDimitry Andric }
1647ae0e2c9SDimitry Andric
1657ae0e2c9SDimitry Andric /// canConvertIf - If the sub-CFG headed by MBB can be if-converted,
1667ae0e2c9SDimitry Andric /// initialize the internal state, and return true.
1677ae0e2c9SDimitry Andric bool canConvertIf(MachineBasicBlock *MBB);
1687ae0e2c9SDimitry Andric
1697ae0e2c9SDimitry Andric /// convertIf - If-convert the last block passed to canConvertIf(), assuming
1707ae0e2c9SDimitry Andric /// it is possible. Add any erased blocks to RemovedBlocks.
1717ae0e2c9SDimitry Andric void convertIf(SmallVectorImpl<MachineBasicBlock*> &RemovedBlocks);
1727ae0e2c9SDimitry Andric };
1737ae0e2c9SDimitry Andric } // end anonymous namespace
1747ae0e2c9SDimitry Andric
1757ae0e2c9SDimitry Andric
1767ae0e2c9SDimitry Andric /// canSpeculateInstrs - Returns true if all the instructions in MBB can safely
1777ae0e2c9SDimitry Andric /// be speculated. The terminators are not considered.
1787ae0e2c9SDimitry Andric ///
1797ae0e2c9SDimitry Andric /// If instructions use any values that are defined in the head basic block,
1807ae0e2c9SDimitry Andric /// the defining instructions are added to InsertAfter.
1817ae0e2c9SDimitry Andric ///
1827ae0e2c9SDimitry Andric /// Any clobbered regunits are added to ClobberedRegUnits.
1837ae0e2c9SDimitry Andric ///
canSpeculateInstrs(MachineBasicBlock * MBB)1847ae0e2c9SDimitry Andric bool SSAIfConv::canSpeculateInstrs(MachineBasicBlock *MBB) {
1857ae0e2c9SDimitry Andric // Reject any live-in physregs. It's probably CPSR/EFLAGS, and very hard to
1867ae0e2c9SDimitry Andric // get right.
1877ae0e2c9SDimitry Andric if (!MBB->livein_empty()) {
1884ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " has live-ins.\n");
1897ae0e2c9SDimitry Andric return false;
1907ae0e2c9SDimitry Andric }
1917ae0e2c9SDimitry Andric
1927ae0e2c9SDimitry Andric unsigned InstrCount = 0;
1937ae0e2c9SDimitry Andric
1947ae0e2c9SDimitry Andric // Check all instructions, except the terminators. It is assumed that
1957ae0e2c9SDimitry Andric // terminators never have side effects or define any used register values.
1967ae0e2c9SDimitry Andric for (MachineBasicBlock::iterator I = MBB->begin(),
1977ae0e2c9SDimitry Andric E = MBB->getFirstTerminator(); I != E; ++I) {
1984ba319b5SDimitry Andric if (I->isDebugInstr())
1997ae0e2c9SDimitry Andric continue;
2007ae0e2c9SDimitry Andric
2017ae0e2c9SDimitry Andric if (++InstrCount > BlockInstrLimit && !Stress) {
2024ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " has more than "
2037ae0e2c9SDimitry Andric << BlockInstrLimit << " instructions.\n");
2047ae0e2c9SDimitry Andric return false;
2057ae0e2c9SDimitry Andric }
2067ae0e2c9SDimitry Andric
2077ae0e2c9SDimitry Andric // There shouldn't normally be any phis in a single-predecessor block.
2087ae0e2c9SDimitry Andric if (I->isPHI()) {
2094ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Can't hoist: " << *I);
2107ae0e2c9SDimitry Andric return false;
2117ae0e2c9SDimitry Andric }
2127ae0e2c9SDimitry Andric
2137ae0e2c9SDimitry Andric // Don't speculate loads. Note that it may be possible and desirable to
2147ae0e2c9SDimitry Andric // speculate GOT or constant pool loads that are guaranteed not to trap,
2157ae0e2c9SDimitry Andric // but we don't support that for now.
2167ae0e2c9SDimitry Andric if (I->mayLoad()) {
2174ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't speculate load: " << *I);
2187ae0e2c9SDimitry Andric return false;
2197ae0e2c9SDimitry Andric }
2207ae0e2c9SDimitry Andric
2217ae0e2c9SDimitry Andric // We never speculate stores, so an AA pointer isn't necessary.
2227ae0e2c9SDimitry Andric bool DontMoveAcrossStore = true;
223ff0cc061SDimitry Andric if (!I->isSafeToMove(nullptr, DontMoveAcrossStore)) {
2244ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Can't speculate: " << *I);
2257ae0e2c9SDimitry Andric return false;
2267ae0e2c9SDimitry Andric }
2277ae0e2c9SDimitry Andric
2287ae0e2c9SDimitry Andric // Check for any dependencies on Head instructions.
22997bc6c73SDimitry Andric for (const MachineOperand &MO : I->operands()) {
23097bc6c73SDimitry Andric if (MO.isRegMask()) {
2314ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Won't speculate regmask: " << *I);
2327ae0e2c9SDimitry Andric return false;
2337ae0e2c9SDimitry Andric }
23497bc6c73SDimitry Andric if (!MO.isReg())
2357ae0e2c9SDimitry Andric continue;
23697bc6c73SDimitry Andric unsigned Reg = MO.getReg();
2377ae0e2c9SDimitry Andric
2387ae0e2c9SDimitry Andric // Remember clobbered regunits.
23997bc6c73SDimitry Andric if (MO.isDef() && TargetRegisterInfo::isPhysicalRegister(Reg))
2407ae0e2c9SDimitry Andric for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
2417ae0e2c9SDimitry Andric ClobberedRegUnits.set(*Units);
2427ae0e2c9SDimitry Andric
24397bc6c73SDimitry Andric if (!MO.readsReg() || !TargetRegisterInfo::isVirtualRegister(Reg))
2447ae0e2c9SDimitry Andric continue;
2457ae0e2c9SDimitry Andric MachineInstr *DefMI = MRI->getVRegDef(Reg);
2467ae0e2c9SDimitry Andric if (!DefMI || DefMI->getParent() != Head)
2477ae0e2c9SDimitry Andric continue;
24839d628a0SDimitry Andric if (InsertAfter.insert(DefMI).second)
2494ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MBB) << " depends on "
2504ba319b5SDimitry Andric << *DefMI);
2517ae0e2c9SDimitry Andric if (DefMI->isTerminator()) {
2524ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Can't insert instructions below terminator.\n");
2537ae0e2c9SDimitry Andric return false;
2547ae0e2c9SDimitry Andric }
2557ae0e2c9SDimitry Andric }
2567ae0e2c9SDimitry Andric }
2577ae0e2c9SDimitry Andric return true;
2587ae0e2c9SDimitry Andric }
2597ae0e2c9SDimitry Andric
2607ae0e2c9SDimitry Andric
2617ae0e2c9SDimitry Andric /// Find an insertion point in Head for the speculated instructions. The
2627ae0e2c9SDimitry Andric /// insertion point must be:
2637ae0e2c9SDimitry Andric ///
2647ae0e2c9SDimitry Andric /// 1. Before any terminators.
2657ae0e2c9SDimitry Andric /// 2. After any instructions in InsertAfter.
2667ae0e2c9SDimitry Andric /// 3. Not have any clobbered regunits live.
2677ae0e2c9SDimitry Andric ///
2687ae0e2c9SDimitry Andric /// This function sets InsertionPoint and returns true when successful, it
2697ae0e2c9SDimitry Andric /// returns false if no valid insertion point could be found.
2707ae0e2c9SDimitry Andric ///
findInsertionPoint()2717ae0e2c9SDimitry Andric bool SSAIfConv::findInsertionPoint() {
2727ae0e2c9SDimitry Andric // Keep track of live regunits before the current position.
2737ae0e2c9SDimitry Andric // Only track RegUnits that are also in ClobberedRegUnits.
2747ae0e2c9SDimitry Andric LiveRegUnits.clear();
2757ae0e2c9SDimitry Andric SmallVector<unsigned, 8> Reads;
2767ae0e2c9SDimitry Andric MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
2777ae0e2c9SDimitry Andric MachineBasicBlock::iterator I = Head->end();
2787ae0e2c9SDimitry Andric MachineBasicBlock::iterator B = Head->begin();
2797ae0e2c9SDimitry Andric while (I != B) {
2807ae0e2c9SDimitry Andric --I;
2817ae0e2c9SDimitry Andric // Some of the conditional code depends in I.
2823ca95b02SDimitry Andric if (InsertAfter.count(&*I)) {
2834ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Can't insert code after " << *I);
2847ae0e2c9SDimitry Andric return false;
2857ae0e2c9SDimitry Andric }
2867ae0e2c9SDimitry Andric
2877ae0e2c9SDimitry Andric // Update live regunits.
28897bc6c73SDimitry Andric for (const MachineOperand &MO : I->operands()) {
2897ae0e2c9SDimitry Andric // We're ignoring regmask operands. That is conservatively correct.
29097bc6c73SDimitry Andric if (!MO.isReg())
2917ae0e2c9SDimitry Andric continue;
29297bc6c73SDimitry Andric unsigned Reg = MO.getReg();
2937ae0e2c9SDimitry Andric if (!TargetRegisterInfo::isPhysicalRegister(Reg))
2947ae0e2c9SDimitry Andric continue;
2957ae0e2c9SDimitry Andric // I clobbers Reg, so it isn't live before I.
29697bc6c73SDimitry Andric if (MO.isDef())
2977ae0e2c9SDimitry Andric for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
2987ae0e2c9SDimitry Andric LiveRegUnits.erase(*Units);
2997ae0e2c9SDimitry Andric // Unless I reads Reg.
30097bc6c73SDimitry Andric if (MO.readsReg())
3017ae0e2c9SDimitry Andric Reads.push_back(Reg);
3027ae0e2c9SDimitry Andric }
3037ae0e2c9SDimitry Andric // Anything read by I is live before I.
3047ae0e2c9SDimitry Andric while (!Reads.empty())
3057ae0e2c9SDimitry Andric for (MCRegUnitIterator Units(Reads.pop_back_val(), TRI); Units.isValid();
3067ae0e2c9SDimitry Andric ++Units)
3077ae0e2c9SDimitry Andric if (ClobberedRegUnits.test(*Units))
3087ae0e2c9SDimitry Andric LiveRegUnits.insert(*Units);
3097ae0e2c9SDimitry Andric
3107ae0e2c9SDimitry Andric // We can't insert before a terminator.
3117ae0e2c9SDimitry Andric if (I != FirstTerm && I->isTerminator())
3127ae0e2c9SDimitry Andric continue;
3137ae0e2c9SDimitry Andric
3147ae0e2c9SDimitry Andric // Some of the clobbered registers are live before I, not a valid insertion
3157ae0e2c9SDimitry Andric // point.
3167ae0e2c9SDimitry Andric if (!LiveRegUnits.empty()) {
3174ba319b5SDimitry Andric LLVM_DEBUG({
3187ae0e2c9SDimitry Andric dbgs() << "Would clobber";
3197ae0e2c9SDimitry Andric for (SparseSet<unsigned>::const_iterator
3207ae0e2c9SDimitry Andric i = LiveRegUnits.begin(), e = LiveRegUnits.end(); i != e; ++i)
3212cab237bSDimitry Andric dbgs() << ' ' << printRegUnit(*i, TRI);
3227ae0e2c9SDimitry Andric dbgs() << " live before " << *I;
3237ae0e2c9SDimitry Andric });
3247ae0e2c9SDimitry Andric continue;
3257ae0e2c9SDimitry Andric }
3267ae0e2c9SDimitry Andric
3277ae0e2c9SDimitry Andric // This is a valid insertion point.
3287ae0e2c9SDimitry Andric InsertionPoint = I;
3294ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Can insert before " << *I);
3307ae0e2c9SDimitry Andric return true;
3317ae0e2c9SDimitry Andric }
3324ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "No legal insertion point found.\n");
3337ae0e2c9SDimitry Andric return false;
3347ae0e2c9SDimitry Andric }
3357ae0e2c9SDimitry Andric
3367ae0e2c9SDimitry Andric
3377ae0e2c9SDimitry Andric
3387ae0e2c9SDimitry Andric /// canConvertIf - analyze the sub-cfg rooted in MBB, and return true if it is
3397ae0e2c9SDimitry Andric /// a potential candidate for if-conversion. Fill out the internal state.
3407ae0e2c9SDimitry Andric ///
canConvertIf(MachineBasicBlock * MBB)3417ae0e2c9SDimitry Andric bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) {
3427ae0e2c9SDimitry Andric Head = MBB;
34391bc56edSDimitry Andric TBB = FBB = Tail = nullptr;
3447ae0e2c9SDimitry Andric
3457ae0e2c9SDimitry Andric if (Head->succ_size() != 2)
3467ae0e2c9SDimitry Andric return false;
3477ae0e2c9SDimitry Andric MachineBasicBlock *Succ0 = Head->succ_begin()[0];
3487ae0e2c9SDimitry Andric MachineBasicBlock *Succ1 = Head->succ_begin()[1];
3497ae0e2c9SDimitry Andric
3507ae0e2c9SDimitry Andric // Canonicalize so Succ0 has MBB as its single predecessor.
3517ae0e2c9SDimitry Andric if (Succ0->pred_size() != 1)
3527ae0e2c9SDimitry Andric std::swap(Succ0, Succ1);
3537ae0e2c9SDimitry Andric
3547ae0e2c9SDimitry Andric if (Succ0->pred_size() != 1 || Succ0->succ_size() != 1)
3557ae0e2c9SDimitry Andric return false;
3567ae0e2c9SDimitry Andric
3577ae0e2c9SDimitry Andric Tail = Succ0->succ_begin()[0];
3587ae0e2c9SDimitry Andric
3597ae0e2c9SDimitry Andric // This is not a triangle.
3607ae0e2c9SDimitry Andric if (Tail != Succ1) {
3617ae0e2c9SDimitry Andric // Check for a diamond. We won't deal with any critical edges.
3627ae0e2c9SDimitry Andric if (Succ1->pred_size() != 1 || Succ1->succ_size() != 1 ||
3637ae0e2c9SDimitry Andric Succ1->succ_begin()[0] != Tail)
3647ae0e2c9SDimitry Andric return false;
3654ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "\nDiamond: " << printMBBReference(*Head) << " -> "
3662cab237bSDimitry Andric << printMBBReference(*Succ0) << "/"
3672cab237bSDimitry Andric << printMBBReference(*Succ1) << " -> "
3682cab237bSDimitry Andric << printMBBReference(*Tail) << '\n');
3697ae0e2c9SDimitry Andric
3707ae0e2c9SDimitry Andric // Live-in physregs are tricky to get right when speculating code.
3717ae0e2c9SDimitry Andric if (!Tail->livein_empty()) {
3724ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Tail has live-ins.\n");
3737ae0e2c9SDimitry Andric return false;
3747ae0e2c9SDimitry Andric }
3757ae0e2c9SDimitry Andric } else {
3764ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "\nTriangle: " << printMBBReference(*Head) << " -> "
3772cab237bSDimitry Andric << printMBBReference(*Succ0) << " -> "
3782cab237bSDimitry Andric << printMBBReference(*Tail) << '\n');
3797ae0e2c9SDimitry Andric }
3807ae0e2c9SDimitry Andric
3817ae0e2c9SDimitry Andric // This is a triangle or a diamond.
3827ae0e2c9SDimitry Andric // If Tail doesn't have any phis, there must be side effects.
3837ae0e2c9SDimitry Andric if (Tail->empty() || !Tail->front().isPHI()) {
3844ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "No phis in tail.\n");
3857ae0e2c9SDimitry Andric return false;
3867ae0e2c9SDimitry Andric }
3877ae0e2c9SDimitry Andric
3887ae0e2c9SDimitry Andric // The branch we're looking to eliminate must be analyzable.
3897ae0e2c9SDimitry Andric Cond.clear();
3903ca95b02SDimitry Andric if (TII->analyzeBranch(*Head, TBB, FBB, Cond)) {
3914ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Branch not analyzable.\n");
3927ae0e2c9SDimitry Andric return false;
3937ae0e2c9SDimitry Andric }
3947ae0e2c9SDimitry Andric
3957ae0e2c9SDimitry Andric // This is weird, probably some sort of degenerate CFG.
3967ae0e2c9SDimitry Andric if (!TBB) {
3974ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "AnalyzeBranch didn't find conditional branch.\n");
3987ae0e2c9SDimitry Andric return false;
3997ae0e2c9SDimitry Andric }
4007ae0e2c9SDimitry Andric
401*b5893f02SDimitry Andric // Make sure the analyzed branch is conditional; one of the successors
402*b5893f02SDimitry Andric // could be a landing pad. (Empty landing pads can be generated on Windows.)
403*b5893f02SDimitry Andric if (Cond.empty()) {
404*b5893f02SDimitry Andric LLVM_DEBUG(dbgs() << "AnalyzeBranch found an unconditional branch.\n");
405*b5893f02SDimitry Andric return false;
406*b5893f02SDimitry Andric }
407*b5893f02SDimitry Andric
4087ae0e2c9SDimitry Andric // AnalyzeBranch doesn't set FBB on a fall-through branch.
4097ae0e2c9SDimitry Andric // Make sure it is always set.
4107ae0e2c9SDimitry Andric FBB = TBB == Succ0 ? Succ1 : Succ0;
4117ae0e2c9SDimitry Andric
4127ae0e2c9SDimitry Andric // Any phis in the tail block must be convertible to selects.
4137ae0e2c9SDimitry Andric PHIs.clear();
4147ae0e2c9SDimitry Andric MachineBasicBlock *TPred = getTPred();
4157ae0e2c9SDimitry Andric MachineBasicBlock *FPred = getFPred();
4167ae0e2c9SDimitry Andric for (MachineBasicBlock::iterator I = Tail->begin(), E = Tail->end();
4177ae0e2c9SDimitry Andric I != E && I->isPHI(); ++I) {
4187ae0e2c9SDimitry Andric PHIs.push_back(&*I);
4197ae0e2c9SDimitry Andric PHIInfo &PI = PHIs.back();
4207ae0e2c9SDimitry Andric // Find PHI operands corresponding to TPred and FPred.
4217ae0e2c9SDimitry Andric for (unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
4227ae0e2c9SDimitry Andric if (PI.PHI->getOperand(i+1).getMBB() == TPred)
4237ae0e2c9SDimitry Andric PI.TReg = PI.PHI->getOperand(i).getReg();
4247ae0e2c9SDimitry Andric if (PI.PHI->getOperand(i+1).getMBB() == FPred)
4257ae0e2c9SDimitry Andric PI.FReg = PI.PHI->getOperand(i).getReg();
4267ae0e2c9SDimitry Andric }
4277ae0e2c9SDimitry Andric assert(TargetRegisterInfo::isVirtualRegister(PI.TReg) && "Bad PHI");
4287ae0e2c9SDimitry Andric assert(TargetRegisterInfo::isVirtualRegister(PI.FReg) && "Bad PHI");
4297ae0e2c9SDimitry Andric
4307ae0e2c9SDimitry Andric // Get target information.
4317ae0e2c9SDimitry Andric if (!TII->canInsertSelect(*Head, Cond, PI.TReg, PI.FReg,
4327ae0e2c9SDimitry Andric PI.CondCycles, PI.TCycles, PI.FCycles)) {
4334ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Can't convert: " << *PI.PHI);
4347ae0e2c9SDimitry Andric return false;
4357ae0e2c9SDimitry Andric }
4367ae0e2c9SDimitry Andric }
4377ae0e2c9SDimitry Andric
4387ae0e2c9SDimitry Andric // Check that the conditional instructions can be speculated.
4397ae0e2c9SDimitry Andric InsertAfter.clear();
4407ae0e2c9SDimitry Andric ClobberedRegUnits.reset();
4417ae0e2c9SDimitry Andric if (TBB != Tail && !canSpeculateInstrs(TBB))
4427ae0e2c9SDimitry Andric return false;
4437ae0e2c9SDimitry Andric if (FBB != Tail && !canSpeculateInstrs(FBB))
4447ae0e2c9SDimitry Andric return false;
4457ae0e2c9SDimitry Andric
4467ae0e2c9SDimitry Andric // Try to find a valid insertion point for the speculated instructions in the
4477ae0e2c9SDimitry Andric // head basic block.
4487ae0e2c9SDimitry Andric if (!findInsertionPoint())
4497ae0e2c9SDimitry Andric return false;
4507ae0e2c9SDimitry Andric
4517ae0e2c9SDimitry Andric if (isTriangle())
4527ae0e2c9SDimitry Andric ++NumTrianglesSeen;
4537ae0e2c9SDimitry Andric else
4547ae0e2c9SDimitry Andric ++NumDiamondsSeen;
4557ae0e2c9SDimitry Andric return true;
4567ae0e2c9SDimitry Andric }
4577ae0e2c9SDimitry Andric
4587ae0e2c9SDimitry Andric /// replacePHIInstrs - Completely replace PHI instructions with selects.
4597ae0e2c9SDimitry Andric /// This is possible when the only Tail predecessors are the if-converted
4607ae0e2c9SDimitry Andric /// blocks.
replacePHIInstrs()4617ae0e2c9SDimitry Andric void SSAIfConv::replacePHIInstrs() {
4627ae0e2c9SDimitry Andric assert(Tail->pred_size() == 2 && "Cannot replace PHIs");
4637ae0e2c9SDimitry Andric MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
4647ae0e2c9SDimitry Andric assert(FirstTerm != Head->end() && "No terminators");
4657ae0e2c9SDimitry Andric DebugLoc HeadDL = FirstTerm->getDebugLoc();
4667ae0e2c9SDimitry Andric
4677ae0e2c9SDimitry Andric // Convert all PHIs to select instructions inserted before FirstTerm.
4687ae0e2c9SDimitry Andric for (unsigned i = 0, e = PHIs.size(); i != e; ++i) {
4697ae0e2c9SDimitry Andric PHIInfo &PI = PHIs[i];
4704ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "If-converting " << *PI.PHI);
4717ae0e2c9SDimitry Andric unsigned DstReg = PI.PHI->getOperand(0).getReg();
4727ae0e2c9SDimitry Andric TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg);
4734ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << " --> " << *std::prev(FirstTerm));
4747ae0e2c9SDimitry Andric PI.PHI->eraseFromParent();
47591bc56edSDimitry Andric PI.PHI = nullptr;
4767ae0e2c9SDimitry Andric }
4777ae0e2c9SDimitry Andric }
4787ae0e2c9SDimitry Andric
4797ae0e2c9SDimitry Andric /// rewritePHIOperands - When there are additional Tail predecessors, insert
4807ae0e2c9SDimitry Andric /// select instructions in Head and rewrite PHI operands to use the selects.
4817ae0e2c9SDimitry Andric /// Keep the PHI instructions in Tail to handle the other predecessors.
rewritePHIOperands()4827ae0e2c9SDimitry Andric void SSAIfConv::rewritePHIOperands() {
4837ae0e2c9SDimitry Andric MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator();
4847ae0e2c9SDimitry Andric assert(FirstTerm != Head->end() && "No terminators");
4857ae0e2c9SDimitry Andric DebugLoc HeadDL = FirstTerm->getDebugLoc();
4867ae0e2c9SDimitry Andric
4877ae0e2c9SDimitry Andric // Convert all PHIs to select instructions inserted before FirstTerm.
4887ae0e2c9SDimitry Andric for (unsigned i = 0, e = PHIs.size(); i != e; ++i) {
4897ae0e2c9SDimitry Andric PHIInfo &PI = PHIs[i];
4908f0fd8f6SDimitry Andric unsigned DstReg = 0;
4918f0fd8f6SDimitry Andric
4924ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "If-converting " << *PI.PHI);
4938f0fd8f6SDimitry Andric if (PI.TReg == PI.FReg) {
4948f0fd8f6SDimitry Andric // We do not need the select instruction if both incoming values are
4958f0fd8f6SDimitry Andric // equal.
4968f0fd8f6SDimitry Andric DstReg = PI.TReg;
4978f0fd8f6SDimitry Andric } else {
4987ae0e2c9SDimitry Andric unsigned PHIDst = PI.PHI->getOperand(0).getReg();
4998f0fd8f6SDimitry Andric DstReg = MRI->createVirtualRegister(MRI->getRegClass(PHIDst));
5008f0fd8f6SDimitry Andric TII->insertSelect(*Head, FirstTerm, HeadDL,
5018f0fd8f6SDimitry Andric DstReg, Cond, PI.TReg, PI.FReg);
5024ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << " --> " << *std::prev(FirstTerm));
5038f0fd8f6SDimitry Andric }
5047ae0e2c9SDimitry Andric
5057ae0e2c9SDimitry Andric // Rewrite PHI operands TPred -> (DstReg, Head), remove FPred.
5067ae0e2c9SDimitry Andric for (unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
5077ae0e2c9SDimitry Andric MachineBasicBlock *MBB = PI.PHI->getOperand(i-1).getMBB();
5087ae0e2c9SDimitry Andric if (MBB == getTPred()) {
5097ae0e2c9SDimitry Andric PI.PHI->getOperand(i-1).setMBB(Head);
5107ae0e2c9SDimitry Andric PI.PHI->getOperand(i-2).setReg(DstReg);
5117ae0e2c9SDimitry Andric } else if (MBB == getFPred()) {
5127ae0e2c9SDimitry Andric PI.PHI->RemoveOperand(i-1);
5137ae0e2c9SDimitry Andric PI.PHI->RemoveOperand(i-2);
5147ae0e2c9SDimitry Andric }
5157ae0e2c9SDimitry Andric }
5164ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << " --> " << *PI.PHI);
5177ae0e2c9SDimitry Andric }
5187ae0e2c9SDimitry Andric }
5197ae0e2c9SDimitry Andric
5207ae0e2c9SDimitry Andric /// convertIf - Execute the if conversion after canConvertIf has determined the
5217ae0e2c9SDimitry Andric /// feasibility.
5227ae0e2c9SDimitry Andric ///
5237ae0e2c9SDimitry Andric /// Any basic blocks erased will be added to RemovedBlocks.
5247ae0e2c9SDimitry Andric ///
convertIf(SmallVectorImpl<MachineBasicBlock * > & RemovedBlocks)5257ae0e2c9SDimitry Andric void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock*> &RemovedBlocks) {
5267ae0e2c9SDimitry Andric assert(Head && Tail && TBB && FBB && "Call canConvertIf first.");
5277ae0e2c9SDimitry Andric
5287ae0e2c9SDimitry Andric // Update statistics.
5297ae0e2c9SDimitry Andric if (isTriangle())
5307ae0e2c9SDimitry Andric ++NumTrianglesConv;
5317ae0e2c9SDimitry Andric else
5327ae0e2c9SDimitry Andric ++NumDiamondsConv;
5337ae0e2c9SDimitry Andric
5347ae0e2c9SDimitry Andric // Move all instructions into Head, except for the terminators.
5357ae0e2c9SDimitry Andric if (TBB != Tail)
5367ae0e2c9SDimitry Andric Head->splice(InsertionPoint, TBB, TBB->begin(), TBB->getFirstTerminator());
5377ae0e2c9SDimitry Andric if (FBB != Tail)
5387ae0e2c9SDimitry Andric Head->splice(InsertionPoint, FBB, FBB->begin(), FBB->getFirstTerminator());
5397ae0e2c9SDimitry Andric
5407ae0e2c9SDimitry Andric // Are there extra Tail predecessors?
5417ae0e2c9SDimitry Andric bool ExtraPreds = Tail->pred_size() != 2;
5427ae0e2c9SDimitry Andric if (ExtraPreds)
5437ae0e2c9SDimitry Andric rewritePHIOperands();
5447ae0e2c9SDimitry Andric else
5457ae0e2c9SDimitry Andric replacePHIInstrs();
5467ae0e2c9SDimitry Andric
5477ae0e2c9SDimitry Andric // Fix up the CFG, temporarily leave Head without any successors.
5487ae0e2c9SDimitry Andric Head->removeSuccessor(TBB);
5497d523365SDimitry Andric Head->removeSuccessor(FBB, true);
5507ae0e2c9SDimitry Andric if (TBB != Tail)
5517d523365SDimitry Andric TBB->removeSuccessor(Tail, true);
5527ae0e2c9SDimitry Andric if (FBB != Tail)
5537d523365SDimitry Andric FBB->removeSuccessor(Tail, true);
5547ae0e2c9SDimitry Andric
5557ae0e2c9SDimitry Andric // Fix up Head's terminators.
5567ae0e2c9SDimitry Andric // It should become a single branch or a fallthrough.
5577ae0e2c9SDimitry Andric DebugLoc HeadDL = Head->getFirstTerminator()->getDebugLoc();
558d88c1a5aSDimitry Andric TII->removeBranch(*Head);
5597ae0e2c9SDimitry Andric
5607ae0e2c9SDimitry Andric // Erase the now empty conditional blocks. It is likely that Head can fall
5617ae0e2c9SDimitry Andric // through to Tail, and we can join the two blocks.
5627ae0e2c9SDimitry Andric if (TBB != Tail) {
5637ae0e2c9SDimitry Andric RemovedBlocks.push_back(TBB);
5647ae0e2c9SDimitry Andric TBB->eraseFromParent();
5657ae0e2c9SDimitry Andric }
5667ae0e2c9SDimitry Andric if (FBB != Tail) {
5677ae0e2c9SDimitry Andric RemovedBlocks.push_back(FBB);
5687ae0e2c9SDimitry Andric FBB->eraseFromParent();
5697ae0e2c9SDimitry Andric }
5707ae0e2c9SDimitry Andric
5717ae0e2c9SDimitry Andric assert(Head->succ_empty() && "Additional head successors?");
5727ae0e2c9SDimitry Andric if (!ExtraPreds && Head->isLayoutSuccessor(Tail)) {
5737ae0e2c9SDimitry Andric // Splice Tail onto the end of Head.
5744ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Joining tail " << printMBBReference(*Tail)
5754ba319b5SDimitry Andric << " into head " << printMBBReference(*Head) << '\n');
5767ae0e2c9SDimitry Andric Head->splice(Head->end(), Tail,
5777ae0e2c9SDimitry Andric Tail->begin(), Tail->end());
5787ae0e2c9SDimitry Andric Head->transferSuccessorsAndUpdatePHIs(Tail);
5797ae0e2c9SDimitry Andric RemovedBlocks.push_back(Tail);
5807ae0e2c9SDimitry Andric Tail->eraseFromParent();
5817ae0e2c9SDimitry Andric } else {
5827ae0e2c9SDimitry Andric // We need a branch to Tail, let code placement work it out later.
5834ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Converting to unconditional branch.\n");
5847ae0e2c9SDimitry Andric SmallVector<MachineOperand, 0> EmptyCond;
585d88c1a5aSDimitry Andric TII->insertBranch(*Head, Tail, nullptr, EmptyCond, HeadDL);
5867ae0e2c9SDimitry Andric Head->addSuccessor(Tail);
5877ae0e2c9SDimitry Andric }
5884ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << *Head);
5897ae0e2c9SDimitry Andric }
5907ae0e2c9SDimitry Andric
5917ae0e2c9SDimitry Andric
5927ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
5937ae0e2c9SDimitry Andric // EarlyIfConverter Pass
5947ae0e2c9SDimitry Andric //===----------------------------------------------------------------------===//
5957ae0e2c9SDimitry Andric
5967ae0e2c9SDimitry Andric namespace {
5977ae0e2c9SDimitry Andric class EarlyIfConverter : public MachineFunctionPass {
5987ae0e2c9SDimitry Andric const TargetInstrInfo *TII;
5997ae0e2c9SDimitry Andric const TargetRegisterInfo *TRI;
60039d628a0SDimitry Andric MCSchedModel SchedModel;
6017ae0e2c9SDimitry Andric MachineRegisterInfo *MRI;
6027ae0e2c9SDimitry Andric MachineDominatorTree *DomTree;
6037ae0e2c9SDimitry Andric MachineLoopInfo *Loops;
6047ae0e2c9SDimitry Andric MachineTraceMetrics *Traces;
6057ae0e2c9SDimitry Andric MachineTraceMetrics::Ensemble *MinInstr;
6067ae0e2c9SDimitry Andric SSAIfConv IfConv;
6077ae0e2c9SDimitry Andric
6087ae0e2c9SDimitry Andric public:
6097ae0e2c9SDimitry Andric static char ID;
EarlyIfConverter()6107ae0e2c9SDimitry Andric EarlyIfConverter() : MachineFunctionPass(ID) {}
61191bc56edSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override;
61291bc56edSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override;
getPassName() const613d88c1a5aSDimitry Andric StringRef getPassName() const override { return "Early If-Conversion"; }
6147ae0e2c9SDimitry Andric
6157ae0e2c9SDimitry Andric private:
6167ae0e2c9SDimitry Andric bool tryConvertIf(MachineBasicBlock*);
6177ae0e2c9SDimitry Andric void updateDomTree(ArrayRef<MachineBasicBlock*> Removed);
6187ae0e2c9SDimitry Andric void updateLoops(ArrayRef<MachineBasicBlock*> Removed);
6197ae0e2c9SDimitry Andric void invalidateTraces();
6207ae0e2c9SDimitry Andric bool shouldConvertIf();
6217ae0e2c9SDimitry Andric };
6227ae0e2c9SDimitry Andric } // end anonymous namespace
6237ae0e2c9SDimitry Andric
6247ae0e2c9SDimitry Andric char EarlyIfConverter::ID = 0;
6257ae0e2c9SDimitry Andric char &llvm::EarlyIfConverterID = EarlyIfConverter::ID;
6267ae0e2c9SDimitry Andric
627302affcbSDimitry Andric INITIALIZE_PASS_BEGIN(EarlyIfConverter, DEBUG_TYPE,
628302affcbSDimitry Andric "Early If Converter", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)6297ae0e2c9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
6307ae0e2c9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
6317ae0e2c9SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineTraceMetrics)
632302affcbSDimitry Andric INITIALIZE_PASS_END(EarlyIfConverter, DEBUG_TYPE,
633302affcbSDimitry Andric "Early If Converter", false, false)
6347ae0e2c9SDimitry Andric
6357ae0e2c9SDimitry Andric void EarlyIfConverter::getAnalysisUsage(AnalysisUsage &AU) const {
6367ae0e2c9SDimitry Andric AU.addRequired<MachineBranchProbabilityInfo>();
6377ae0e2c9SDimitry Andric AU.addRequired<MachineDominatorTree>();
6387ae0e2c9SDimitry Andric AU.addPreserved<MachineDominatorTree>();
6397ae0e2c9SDimitry Andric AU.addRequired<MachineLoopInfo>();
6407ae0e2c9SDimitry Andric AU.addPreserved<MachineLoopInfo>();
6417ae0e2c9SDimitry Andric AU.addRequired<MachineTraceMetrics>();
6427ae0e2c9SDimitry Andric AU.addPreserved<MachineTraceMetrics>();
6437ae0e2c9SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU);
6447ae0e2c9SDimitry Andric }
6457ae0e2c9SDimitry Andric
6467ae0e2c9SDimitry Andric /// Update the dominator tree after if-conversion erased some blocks.
updateDomTree(ArrayRef<MachineBasicBlock * > Removed)6477ae0e2c9SDimitry Andric void EarlyIfConverter::updateDomTree(ArrayRef<MachineBasicBlock*> Removed) {
6487ae0e2c9SDimitry Andric // convertIf can remove TBB, FBB, and Tail can be merged into Head.
6497ae0e2c9SDimitry Andric // TBB and FBB should not dominate any blocks.
6507ae0e2c9SDimitry Andric // Tail children should be transferred to Head.
6517ae0e2c9SDimitry Andric MachineDomTreeNode *HeadNode = DomTree->getNode(IfConv.Head);
6527ae0e2c9SDimitry Andric for (unsigned i = 0, e = Removed.size(); i != e; ++i) {
6537ae0e2c9SDimitry Andric MachineDomTreeNode *Node = DomTree->getNode(Removed[i]);
6547ae0e2c9SDimitry Andric assert(Node != HeadNode && "Cannot erase the head node");
6557ae0e2c9SDimitry Andric while (Node->getNumChildren()) {
6567ae0e2c9SDimitry Andric assert(Node->getBlock() == IfConv.Tail && "Unexpected children");
6577ae0e2c9SDimitry Andric DomTree->changeImmediateDominator(Node->getChildren().back(), HeadNode);
6587ae0e2c9SDimitry Andric }
6597ae0e2c9SDimitry Andric DomTree->eraseNode(Removed[i]);
6607ae0e2c9SDimitry Andric }
6617ae0e2c9SDimitry Andric }
6627ae0e2c9SDimitry Andric
6637ae0e2c9SDimitry Andric /// Update LoopInfo after if-conversion.
updateLoops(ArrayRef<MachineBasicBlock * > Removed)6647ae0e2c9SDimitry Andric void EarlyIfConverter::updateLoops(ArrayRef<MachineBasicBlock*> Removed) {
6657ae0e2c9SDimitry Andric if (!Loops)
6667ae0e2c9SDimitry Andric return;
6677ae0e2c9SDimitry Andric // If-conversion doesn't change loop structure, and it doesn't mess with back
6687ae0e2c9SDimitry Andric // edges, so updating LoopInfo is simply removing the dead blocks.
6697ae0e2c9SDimitry Andric for (unsigned i = 0, e = Removed.size(); i != e; ++i)
6707ae0e2c9SDimitry Andric Loops->removeBlock(Removed[i]);
6717ae0e2c9SDimitry Andric }
6727ae0e2c9SDimitry Andric
6737ae0e2c9SDimitry Andric /// Invalidate MachineTraceMetrics before if-conversion.
invalidateTraces()6747ae0e2c9SDimitry Andric void EarlyIfConverter::invalidateTraces() {
6757ae0e2c9SDimitry Andric Traces->verifyAnalysis();
6767ae0e2c9SDimitry Andric Traces->invalidate(IfConv.Head);
6777ae0e2c9SDimitry Andric Traces->invalidate(IfConv.Tail);
6787ae0e2c9SDimitry Andric Traces->invalidate(IfConv.TBB);
6797ae0e2c9SDimitry Andric Traces->invalidate(IfConv.FBB);
6807ae0e2c9SDimitry Andric Traces->verifyAnalysis();
6817ae0e2c9SDimitry Andric }
6827ae0e2c9SDimitry Andric
6837ae0e2c9SDimitry Andric // Adjust cycles with downward saturation.
adjCycles(unsigned Cyc,int Delta)6847ae0e2c9SDimitry Andric static unsigned adjCycles(unsigned Cyc, int Delta) {
6857ae0e2c9SDimitry Andric if (Delta < 0 && Cyc + Delta > Cyc)
6867ae0e2c9SDimitry Andric return 0;
6877ae0e2c9SDimitry Andric return Cyc + Delta;
6887ae0e2c9SDimitry Andric }
6897ae0e2c9SDimitry Andric
6907ae0e2c9SDimitry Andric /// Apply cost model and heuristics to the if-conversion in IfConv.
6917ae0e2c9SDimitry Andric /// Return true if the conversion is a good idea.
6927ae0e2c9SDimitry Andric ///
shouldConvertIf()6937ae0e2c9SDimitry Andric bool EarlyIfConverter::shouldConvertIf() {
6947ae0e2c9SDimitry Andric // Stress testing mode disables all cost considerations.
6957ae0e2c9SDimitry Andric if (Stress)
6967ae0e2c9SDimitry Andric return true;
6977ae0e2c9SDimitry Andric
6987ae0e2c9SDimitry Andric if (!MinInstr)
6997ae0e2c9SDimitry Andric MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount);
7007ae0e2c9SDimitry Andric
7017ae0e2c9SDimitry Andric MachineTraceMetrics::Trace TBBTrace = MinInstr->getTrace(IfConv.getTPred());
7027ae0e2c9SDimitry Andric MachineTraceMetrics::Trace FBBTrace = MinInstr->getTrace(IfConv.getFPred());
7034ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "TBB: " << TBBTrace << "FBB: " << FBBTrace);
7047ae0e2c9SDimitry Andric unsigned MinCrit = std::min(TBBTrace.getCriticalPath(),
7057ae0e2c9SDimitry Andric FBBTrace.getCriticalPath());
7067ae0e2c9SDimitry Andric
7077ae0e2c9SDimitry Andric // Set a somewhat arbitrary limit on the critical path extension we accept.
70839d628a0SDimitry Andric unsigned CritLimit = SchedModel.MispredictPenalty/2;
7097ae0e2c9SDimitry Andric
7107ae0e2c9SDimitry Andric // If-conversion only makes sense when there is unexploited ILP. Compute the
7117ae0e2c9SDimitry Andric // maximum-ILP resource length of the trace after if-conversion. Compare it
7127ae0e2c9SDimitry Andric // to the shortest critical path.
7137ae0e2c9SDimitry Andric SmallVector<const MachineBasicBlock*, 1> ExtraBlocks;
7147ae0e2c9SDimitry Andric if (IfConv.TBB != IfConv.Tail)
7157ae0e2c9SDimitry Andric ExtraBlocks.push_back(IfConv.TBB);
7167ae0e2c9SDimitry Andric unsigned ResLength = FBBTrace.getResourceLength(ExtraBlocks);
7174ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Resource length " << ResLength
7187ae0e2c9SDimitry Andric << ", minimal critical path " << MinCrit << '\n');
7197ae0e2c9SDimitry Andric if (ResLength > MinCrit + CritLimit) {
7204ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Not enough available ILP.\n");
7217ae0e2c9SDimitry Andric return false;
7227ae0e2c9SDimitry Andric }
7237ae0e2c9SDimitry Andric
7247ae0e2c9SDimitry Andric // Assume that the depth of the first head terminator will also be the depth
7257ae0e2c9SDimitry Andric // of the select instruction inserted, as determined by the flag dependency.
7267ae0e2c9SDimitry Andric // TBB / FBB data dependencies may delay the select even more.
7277ae0e2c9SDimitry Andric MachineTraceMetrics::Trace HeadTrace = MinInstr->getTrace(IfConv.Head);
7287ae0e2c9SDimitry Andric unsigned BranchDepth =
7293ca95b02SDimitry Andric HeadTrace.getInstrCycles(*IfConv.Head->getFirstTerminator()).Depth;
7304ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Branch depth: " << BranchDepth << '\n');
7317ae0e2c9SDimitry Andric
7327ae0e2c9SDimitry Andric // Look at all the tail phis, and compute the critical path extension caused
7337ae0e2c9SDimitry Andric // by inserting select instructions.
7347ae0e2c9SDimitry Andric MachineTraceMetrics::Trace TailTrace = MinInstr->getTrace(IfConv.Tail);
7357ae0e2c9SDimitry Andric for (unsigned i = 0, e = IfConv.PHIs.size(); i != e; ++i) {
7367ae0e2c9SDimitry Andric SSAIfConv::PHIInfo &PI = IfConv.PHIs[i];
7373ca95b02SDimitry Andric unsigned Slack = TailTrace.getInstrSlack(*PI.PHI);
7383ca95b02SDimitry Andric unsigned MaxDepth = Slack + TailTrace.getInstrCycles(*PI.PHI).Depth;
7394ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Slack " << Slack << ":\t" << *PI.PHI);
7407ae0e2c9SDimitry Andric
7417ae0e2c9SDimitry Andric // The condition is pulled into the critical path.
7427ae0e2c9SDimitry Andric unsigned CondDepth = adjCycles(BranchDepth, PI.CondCycles);
7437ae0e2c9SDimitry Andric if (CondDepth > MaxDepth) {
7447ae0e2c9SDimitry Andric unsigned Extra = CondDepth - MaxDepth;
7454ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Condition adds " << Extra << " cycles.\n");
7467ae0e2c9SDimitry Andric if (Extra > CritLimit) {
7474ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
7487ae0e2c9SDimitry Andric return false;
7497ae0e2c9SDimitry Andric }
7507ae0e2c9SDimitry Andric }
7517ae0e2c9SDimitry Andric
7527ae0e2c9SDimitry Andric // The TBB value is pulled into the critical path.
7533ca95b02SDimitry Andric unsigned TDepth = adjCycles(TBBTrace.getPHIDepth(*PI.PHI), PI.TCycles);
7547ae0e2c9SDimitry Andric if (TDepth > MaxDepth) {
7557ae0e2c9SDimitry Andric unsigned Extra = TDepth - MaxDepth;
7564ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "TBB data adds " << Extra << " cycles.\n");
7577ae0e2c9SDimitry Andric if (Extra > CritLimit) {
7584ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
7597ae0e2c9SDimitry Andric return false;
7607ae0e2c9SDimitry Andric }
7617ae0e2c9SDimitry Andric }
7627ae0e2c9SDimitry Andric
7637ae0e2c9SDimitry Andric // The FBB value is pulled into the critical path.
7643ca95b02SDimitry Andric unsigned FDepth = adjCycles(FBBTrace.getPHIDepth(*PI.PHI), PI.FCycles);
7657ae0e2c9SDimitry Andric if (FDepth > MaxDepth) {
7667ae0e2c9SDimitry Andric unsigned Extra = FDepth - MaxDepth;
7674ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "FBB data adds " << Extra << " cycles.\n");
7687ae0e2c9SDimitry Andric if (Extra > CritLimit) {
7694ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n');
7707ae0e2c9SDimitry Andric return false;
7717ae0e2c9SDimitry Andric }
7727ae0e2c9SDimitry Andric }
7737ae0e2c9SDimitry Andric }
7747ae0e2c9SDimitry Andric return true;
7757ae0e2c9SDimitry Andric }
7767ae0e2c9SDimitry Andric
7777ae0e2c9SDimitry Andric /// Attempt repeated if-conversion on MBB, return true if successful.
7787ae0e2c9SDimitry Andric ///
tryConvertIf(MachineBasicBlock * MBB)7797ae0e2c9SDimitry Andric bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *MBB) {
7807ae0e2c9SDimitry Andric bool Changed = false;
7817ae0e2c9SDimitry Andric while (IfConv.canConvertIf(MBB) && shouldConvertIf()) {
7827ae0e2c9SDimitry Andric // If-convert MBB and update analyses.
7837ae0e2c9SDimitry Andric invalidateTraces();
7847ae0e2c9SDimitry Andric SmallVector<MachineBasicBlock*, 4> RemovedBlocks;
7857ae0e2c9SDimitry Andric IfConv.convertIf(RemovedBlocks);
7867ae0e2c9SDimitry Andric Changed = true;
7877ae0e2c9SDimitry Andric updateDomTree(RemovedBlocks);
7887ae0e2c9SDimitry Andric updateLoops(RemovedBlocks);
7897ae0e2c9SDimitry Andric }
7907ae0e2c9SDimitry Andric return Changed;
7917ae0e2c9SDimitry Andric }
7927ae0e2c9SDimitry Andric
runOnMachineFunction(MachineFunction & MF)7937ae0e2c9SDimitry Andric bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
7944ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "********** EARLY IF-CONVERSION **********\n"
7953861d79fSDimitry Andric << "********** Function: " << MF.getName() << '\n');
7962cab237bSDimitry Andric if (skipFunction(MF.getFunction()))
7973ca95b02SDimitry Andric return false;
7983ca95b02SDimitry Andric
79991bc56edSDimitry Andric // Only run if conversion if the target wants it.
800ff0cc061SDimitry Andric const TargetSubtargetInfo &STI = MF.getSubtarget();
801ff0cc061SDimitry Andric if (!STI.enableEarlyIfConversion())
80291bc56edSDimitry Andric return false;
80391bc56edSDimitry Andric
804ff0cc061SDimitry Andric TII = STI.getInstrInfo();
805ff0cc061SDimitry Andric TRI = STI.getRegisterInfo();
806ff0cc061SDimitry Andric SchedModel = STI.getSchedModel();
8077ae0e2c9SDimitry Andric MRI = &MF.getRegInfo();
8087ae0e2c9SDimitry Andric DomTree = &getAnalysis<MachineDominatorTree>();
8097ae0e2c9SDimitry Andric Loops = getAnalysisIfAvailable<MachineLoopInfo>();
8107ae0e2c9SDimitry Andric Traces = &getAnalysis<MachineTraceMetrics>();
81191bc56edSDimitry Andric MinInstr = nullptr;
8127ae0e2c9SDimitry Andric
8137ae0e2c9SDimitry Andric bool Changed = false;
8147ae0e2c9SDimitry Andric IfConv.runOnMachineFunction(MF);
8157ae0e2c9SDimitry Andric
8167ae0e2c9SDimitry Andric // Visit blocks in dominator tree post-order. The post-order enables nested
8177ae0e2c9SDimitry Andric // if-conversion in a single pass. The tryConvertIf() function may erase
8187ae0e2c9SDimitry Andric // blocks, but only blocks dominated by the head block. This makes it safe to
8197ae0e2c9SDimitry Andric // update the dominator tree while the post-order iterator is still active.
820ff0cc061SDimitry Andric for (auto DomNode : post_order(DomTree))
821ff0cc061SDimitry Andric if (tryConvertIf(DomNode->getBlock()))
8227ae0e2c9SDimitry Andric Changed = true;
8237ae0e2c9SDimitry Andric
8247ae0e2c9SDimitry Andric return Changed;
8257ae0e2c9SDimitry Andric }
826