1f8a63a15SJakob Stoklund Olesen //===-- EarlyIfConversion.cpp - If-conversion on SSA form machine code ----===// 2f8a63a15SJakob Stoklund Olesen // 3f8a63a15SJakob Stoklund Olesen // The LLVM Compiler Infrastructure 4f8a63a15SJakob Stoklund Olesen // 5f8a63a15SJakob Stoklund Olesen // This file is distributed under the University of Illinois Open Source 6f8a63a15SJakob Stoklund Olesen // License. See LICENSE.TXT for details. 7f8a63a15SJakob Stoklund Olesen // 8f8a63a15SJakob Stoklund Olesen //===----------------------------------------------------------------------===// 9f8a63a15SJakob Stoklund Olesen // 10f8a63a15SJakob Stoklund Olesen // Early if-conversion is for out-of-order CPUs that don't have a lot of 11f8a63a15SJakob Stoklund Olesen // predicable instructions. The goal is to eliminate conditional branches that 12f8a63a15SJakob Stoklund Olesen // may mispredict. 13f8a63a15SJakob Stoklund Olesen // 14f8a63a15SJakob Stoklund Olesen // Instructions from both sides of the branch are executed specutatively, and a 15f8a63a15SJakob Stoklund Olesen // cmov instruction selects the result. 16f8a63a15SJakob Stoklund Olesen // 17f8a63a15SJakob Stoklund Olesen //===----------------------------------------------------------------------===// 18f8a63a15SJakob Stoklund Olesen 19f8a63a15SJakob Stoklund Olesen #include "llvm/ADT/BitVector.h" 2002638392SJakob Stoklund Olesen #include "llvm/ADT/PostOrderIterator.h" 21f8a63a15SJakob Stoklund Olesen #include "llvm/ADT/SetVector.h" 22f8a63a15SJakob Stoklund Olesen #include "llvm/ADT/SmallPtrSet.h" 23f8a63a15SJakob Stoklund Olesen #include "llvm/ADT/SparseSet.h" 24d0af1d96SJakob Stoklund Olesen #include "llvm/ADT/Statistic.h" 25f8a63a15SJakob Stoklund Olesen #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" 2602638392SJakob Stoklund Olesen #include "llvm/CodeGen/MachineDominators.h" 27f8a63a15SJakob Stoklund Olesen #include "llvm/CodeGen/MachineFunction.h" 28f8a63a15SJakob Stoklund Olesen #include "llvm/CodeGen/MachineFunctionPass.h" 29bc90a4eaSJakob Stoklund Olesen #include "llvm/CodeGen/MachineLoopInfo.h" 30f8a63a15SJakob Stoklund Olesen #include "llvm/CodeGen/MachineRegisterInfo.h" 31965665bbSJakob Stoklund Olesen #include "llvm/CodeGen/MachineTraceMetrics.h" 32965665bbSJakob Stoklund Olesen #include "llvm/CodeGen/Passes.h" 33f8a63a15SJakob Stoklund Olesen #include "llvm/Support/CommandLine.h" 34f8a63a15SJakob Stoklund Olesen #include "llvm/Support/Debug.h" 35f8a63a15SJakob Stoklund Olesen #include "llvm/Support/raw_ostream.h" 36ed0881b2SChandler Carruth #include "llvm/Target/TargetInstrInfo.h" 37ed0881b2SChandler Carruth #include "llvm/Target/TargetRegisterInfo.h" 38ed0881b2SChandler Carruth #include "llvm/Target/TargetSubtargetInfo.h" 39f8a63a15SJakob Stoklund Olesen 40f8a63a15SJakob Stoklund Olesen using namespace llvm; 41f8a63a15SJakob Stoklund Olesen 421b9dde08SChandler Carruth #define DEBUG_TYPE "early-ifcvt" 431b9dde08SChandler Carruth 44f8a63a15SJakob Stoklund Olesen // Absolute maximum number of instructions allowed per speculated block. 45f8a63a15SJakob Stoklund Olesen // This bypasses all other heuristics, so it should be set fairly high. 46f8a63a15SJakob Stoklund Olesen static cl::opt<unsigned> 47f8a63a15SJakob Stoklund Olesen BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden, 48f8a63a15SJakob Stoklund Olesen cl::desc("Maximum number of instructions per speculated block.")); 49f8a63a15SJakob Stoklund Olesen 50f8a63a15SJakob Stoklund Olesen // Stress testing mode - disable heuristics. 51f8a63a15SJakob Stoklund Olesen static cl::opt<bool> Stress("stress-early-ifcvt", cl::Hidden, 52f8a63a15SJakob Stoklund Olesen cl::desc("Turn all knobs to 11")); 53f8a63a15SJakob Stoklund Olesen 54d0af1d96SJakob Stoklund Olesen STATISTIC(NumDiamondsSeen, "Number of diamonds"); 55d0af1d96SJakob Stoklund Olesen STATISTIC(NumDiamondsConv, "Number of diamonds converted"); 56d0af1d96SJakob Stoklund Olesen STATISTIC(NumTrianglesSeen, "Number of triangles"); 57d0af1d96SJakob Stoklund Olesen STATISTIC(NumTrianglesConv, "Number of triangles converted"); 58d0af1d96SJakob Stoklund Olesen 59f8a63a15SJakob Stoklund Olesen //===----------------------------------------------------------------------===// 60f8a63a15SJakob Stoklund Olesen // SSAIfConv 61f8a63a15SJakob Stoklund Olesen //===----------------------------------------------------------------------===// 62f8a63a15SJakob Stoklund Olesen // 63f8a63a15SJakob Stoklund Olesen // The SSAIfConv class performs if-conversion on SSA form machine code after 6411d08b2eSMatt Beaumont-Gay // determining if it is possible. The class contains no heuristics; external 65f8a63a15SJakob Stoklund Olesen // code should be used to determine when if-conversion is a good idea. 66f8a63a15SJakob Stoklund Olesen // 6711d08b2eSMatt Beaumont-Gay // SSAIfConv can convert both triangles and diamonds: 68f8a63a15SJakob Stoklund Olesen // 69f8a63a15SJakob Stoklund Olesen // Triangle: Head Diamond: Head 7011d08b2eSMatt Beaumont-Gay // | \ / \_ 7111d08b2eSMatt Beaumont-Gay // | \ / | 72f8a63a15SJakob Stoklund Olesen // | [TF]BB FBB TBB 73f8a63a15SJakob Stoklund Olesen // | / \ / 74f8a63a15SJakob Stoklund Olesen // | / \ / 75f8a63a15SJakob Stoklund Olesen // Tail Tail 76f8a63a15SJakob Stoklund Olesen // 77f8a63a15SJakob Stoklund Olesen // Instructions in the conditional blocks TBB and/or FBB are spliced into the 7811d08b2eSMatt Beaumont-Gay // Head block, and phis in the Tail block are converted to select instructions. 79f8a63a15SJakob Stoklund Olesen // 80f8a63a15SJakob Stoklund Olesen namespace { 81f8a63a15SJakob Stoklund Olesen class SSAIfConv { 82f8a63a15SJakob Stoklund Olesen const TargetInstrInfo *TII; 83f8a63a15SJakob Stoklund Olesen const TargetRegisterInfo *TRI; 84f8a63a15SJakob Stoklund Olesen MachineRegisterInfo *MRI; 85f8a63a15SJakob Stoklund Olesen 8602638392SJakob Stoklund Olesen public: 87f8a63a15SJakob Stoklund Olesen /// The block containing the conditional branch. 88f8a63a15SJakob Stoklund Olesen MachineBasicBlock *Head; 89f8a63a15SJakob Stoklund Olesen 90f8a63a15SJakob Stoklund Olesen /// The block containing phis after the if-then-else. 91f8a63a15SJakob Stoklund Olesen MachineBasicBlock *Tail; 92f8a63a15SJakob Stoklund Olesen 93f8a63a15SJakob Stoklund Olesen /// The 'true' conditional block as determined by AnalyzeBranch. 94f8a63a15SJakob Stoklund Olesen MachineBasicBlock *TBB; 95f8a63a15SJakob Stoklund Olesen 96f8a63a15SJakob Stoklund Olesen /// The 'false' conditional block as determined by AnalyzeBranch. 97f8a63a15SJakob Stoklund Olesen MachineBasicBlock *FBB; 98f8a63a15SJakob Stoklund Olesen 99f8a63a15SJakob Stoklund Olesen /// isTriangle - When there is no 'else' block, either TBB or FBB will be 100f8a63a15SJakob Stoklund Olesen /// equal to Tail. 101f8a63a15SJakob Stoklund Olesen bool isTriangle() const { return TBB == Tail || FBB == Tail; } 102f8a63a15SJakob Stoklund Olesen 1030a99062cSJakob Stoklund Olesen /// Returns the Tail predecessor for the True side. 1040a99062cSJakob Stoklund Olesen MachineBasicBlock *getTPred() const { return TBB == Tail ? Head : TBB; } 1050a99062cSJakob Stoklund Olesen 1060a99062cSJakob Stoklund Olesen /// Returns the Tail predecessor for the False side. 1070a99062cSJakob Stoklund Olesen MachineBasicBlock *getFPred() const { return FBB == Tail ? Head : FBB; } 1080a99062cSJakob Stoklund Olesen 109f8a63a15SJakob Stoklund Olesen /// Information about each phi in the Tail block. 110f8a63a15SJakob Stoklund Olesen struct PHIInfo { 111f8a63a15SJakob Stoklund Olesen MachineInstr *PHI; 112f8a63a15SJakob Stoklund Olesen unsigned TReg, FReg; 113f8a63a15SJakob Stoklund Olesen // Latencies from Cond+Branch, TReg, and FReg to DstReg. 114f8a63a15SJakob Stoklund Olesen int CondCycles, TCycles, FCycles; 115f8a63a15SJakob Stoklund Olesen 116f8a63a15SJakob Stoklund Olesen PHIInfo(MachineInstr *phi) 117f8a63a15SJakob Stoklund Olesen : PHI(phi), TReg(0), FReg(0), CondCycles(0), TCycles(0), FCycles(0) {} 118f8a63a15SJakob Stoklund Olesen }; 119f8a63a15SJakob Stoklund Olesen 120f8a63a15SJakob Stoklund Olesen SmallVector<PHIInfo, 8> PHIs; 121f8a63a15SJakob Stoklund Olesen 12202638392SJakob Stoklund Olesen private: 12302638392SJakob Stoklund Olesen /// The branch condition determined by AnalyzeBranch. 12402638392SJakob Stoklund Olesen SmallVector<MachineOperand, 4> Cond; 12502638392SJakob Stoklund Olesen 126f8a63a15SJakob Stoklund Olesen /// Instructions in Head that define values used by the conditional blocks. 127f8a63a15SJakob Stoklund Olesen /// The hoisted instructions must be inserted after these instructions. 128f8a63a15SJakob Stoklund Olesen SmallPtrSet<MachineInstr*, 8> InsertAfter; 129f8a63a15SJakob Stoklund Olesen 130f8a63a15SJakob Stoklund Olesen /// Register units clobbered by the conditional blocks. 131f8a63a15SJakob Stoklund Olesen BitVector ClobberedRegUnits; 132f8a63a15SJakob Stoklund Olesen 133f8a63a15SJakob Stoklund Olesen // Scratch pad for findInsertionPoint. 134f8a63a15SJakob Stoklund Olesen SparseSet<unsigned> LiveRegUnits; 135f8a63a15SJakob Stoklund Olesen 136f8a63a15SJakob Stoklund Olesen /// Insertion point in Head for speculatively executed instructions form TBB 137f8a63a15SJakob Stoklund Olesen /// and FBB. 138f8a63a15SJakob Stoklund Olesen MachineBasicBlock::iterator InsertionPoint; 139f8a63a15SJakob Stoklund Olesen 140f8a63a15SJakob Stoklund Olesen /// Return true if all non-terminator instructions in MBB can be safely 141f8a63a15SJakob Stoklund Olesen /// speculated. 142f8a63a15SJakob Stoklund Olesen bool canSpeculateInstrs(MachineBasicBlock *MBB); 143f8a63a15SJakob Stoklund Olesen 144f8a63a15SJakob Stoklund Olesen /// Find a valid insertion point in Head. 145f8a63a15SJakob Stoklund Olesen bool findInsertionPoint(); 146f8a63a15SJakob Stoklund Olesen 14783a927d8SJakob Stoklund Olesen /// Replace PHI instructions in Tail with selects. 14883a927d8SJakob Stoklund Olesen void replacePHIInstrs(); 14983a927d8SJakob Stoklund Olesen 15083a927d8SJakob Stoklund Olesen /// Insert selects and rewrite PHI operands to use them. 15183a927d8SJakob Stoklund Olesen void rewritePHIOperands(); 15283a927d8SJakob Stoklund Olesen 153f8a63a15SJakob Stoklund Olesen public: 154f8a63a15SJakob Stoklund Olesen /// runOnMachineFunction - Initialize per-function data structures. 155f8a63a15SJakob Stoklund Olesen void runOnMachineFunction(MachineFunction &MF) { 156fc6de428SEric Christopher TII = MF.getSubtarget().getInstrInfo(); 157fc6de428SEric Christopher TRI = MF.getSubtarget().getRegisterInfo(); 158f8a63a15SJakob Stoklund Olesen MRI = &MF.getRegInfo(); 159f8a63a15SJakob Stoklund Olesen LiveRegUnits.clear(); 160f8a63a15SJakob Stoklund Olesen LiveRegUnits.setUniverse(TRI->getNumRegUnits()); 161f8a63a15SJakob Stoklund Olesen ClobberedRegUnits.clear(); 162f8a63a15SJakob Stoklund Olesen ClobberedRegUnits.resize(TRI->getNumRegUnits()); 163f8a63a15SJakob Stoklund Olesen } 164f8a63a15SJakob Stoklund Olesen 165f8a63a15SJakob Stoklund Olesen /// canConvertIf - If the sub-CFG headed by MBB can be if-converted, 166f8a63a15SJakob Stoklund Olesen /// initialize the internal state, and return true. 167f8a63a15SJakob Stoklund Olesen bool canConvertIf(MachineBasicBlock *MBB); 168f8a63a15SJakob Stoklund Olesen 169f8a63a15SJakob Stoklund Olesen /// convertIf - If-convert the last block passed to canConvertIf(), assuming 17002638392SJakob Stoklund Olesen /// it is possible. Add any erased blocks to RemovedBlocks. 17102638392SJakob Stoklund Olesen void convertIf(SmallVectorImpl<MachineBasicBlock*> &RemovedBlocks); 172f8a63a15SJakob Stoklund Olesen }; 173f8a63a15SJakob Stoklund Olesen } // end anonymous namespace 174f8a63a15SJakob Stoklund Olesen 175f8a63a15SJakob Stoklund Olesen 176f8a63a15SJakob Stoklund Olesen /// canSpeculateInstrs - Returns true if all the instructions in MBB can safely 177f8a63a15SJakob Stoklund Olesen /// be speculated. The terminators are not considered. 178f8a63a15SJakob Stoklund Olesen /// 179f8a63a15SJakob Stoklund Olesen /// If instructions use any values that are defined in the head basic block, 180f8a63a15SJakob Stoklund Olesen /// the defining instructions are added to InsertAfter. 181f8a63a15SJakob Stoklund Olesen /// 182f8a63a15SJakob Stoklund Olesen /// Any clobbered regunits are added to ClobberedRegUnits. 183f8a63a15SJakob Stoklund Olesen /// 184f8a63a15SJakob Stoklund Olesen bool SSAIfConv::canSpeculateInstrs(MachineBasicBlock *MBB) { 185f8a63a15SJakob Stoklund Olesen // Reject any live-in physregs. It's probably CPSR/EFLAGS, and very hard to 186f8a63a15SJakob Stoklund Olesen // get right. 187f8a63a15SJakob Stoklund Olesen if (!MBB->livein_empty()) { 188f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "BB#" << MBB->getNumber() << " has live-ins.\n"); 189f8a63a15SJakob Stoklund Olesen return false; 190f8a63a15SJakob Stoklund Olesen } 191f8a63a15SJakob Stoklund Olesen 192f8a63a15SJakob Stoklund Olesen unsigned InstrCount = 0; 1933f1bb93cSJakob Stoklund Olesen 1943f1bb93cSJakob Stoklund Olesen // Check all instructions, except the terminators. It is assumed that 1953f1bb93cSJakob Stoklund Olesen // terminators never have side effects or define any used register values. 196f8a63a15SJakob Stoklund Olesen for (MachineBasicBlock::iterator I = MBB->begin(), 197f8a63a15SJakob Stoklund Olesen E = MBB->getFirstTerminator(); I != E; ++I) { 198f8a63a15SJakob Stoklund Olesen if (I->isDebugValue()) 199f8a63a15SJakob Stoklund Olesen continue; 200f8a63a15SJakob Stoklund Olesen 201f8a63a15SJakob Stoklund Olesen if (++InstrCount > BlockInstrLimit && !Stress) { 202f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "BB#" << MBB->getNumber() << " has more than " 203f8a63a15SJakob Stoklund Olesen << BlockInstrLimit << " instructions.\n"); 204f8a63a15SJakob Stoklund Olesen return false; 205f8a63a15SJakob Stoklund Olesen } 206f8a63a15SJakob Stoklund Olesen 207f8a63a15SJakob Stoklund Olesen // There shouldn't normally be any phis in a single-predecessor block. 208f8a63a15SJakob Stoklund Olesen if (I->isPHI()) { 209f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Can't hoist: " << *I); 210f8a63a15SJakob Stoklund Olesen return false; 211f8a63a15SJakob Stoklund Olesen } 212f8a63a15SJakob Stoklund Olesen 213f8a63a15SJakob Stoklund Olesen // Don't speculate loads. Note that it may be possible and desirable to 214f8a63a15SJakob Stoklund Olesen // speculate GOT or constant pool loads that are guaranteed not to trap, 215f8a63a15SJakob Stoklund Olesen // but we don't support that for now. 216f8a63a15SJakob Stoklund Olesen if (I->mayLoad()) { 217f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Won't speculate load: " << *I); 218f8a63a15SJakob Stoklund Olesen return false; 219f8a63a15SJakob Stoklund Olesen } 220f8a63a15SJakob Stoklund Olesen 221f8a63a15SJakob Stoklund Olesen // We never speculate stores, so an AA pointer isn't necessary. 222f8a63a15SJakob Stoklund Olesen bool DontMoveAcrossStore = true; 22307066ccaSMatthias Braun if (!I->isSafeToMove(nullptr, DontMoveAcrossStore)) { 224f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Can't speculate: " << *I); 225f8a63a15SJakob Stoklund Olesen return false; 226f8a63a15SJakob Stoklund Olesen } 227f8a63a15SJakob Stoklund Olesen 228f8a63a15SJakob Stoklund Olesen // Check for any dependencies on Head instructions. 22927a6cfd8SMatthias Braun for (const MachineOperand &MO : I->operands()) { 230e41e146cSMatthias Braun if (MO.isRegMask()) { 231f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Won't speculate regmask: " << *I); 232f8a63a15SJakob Stoklund Olesen return false; 233f8a63a15SJakob Stoklund Olesen } 234e41e146cSMatthias Braun if (!MO.isReg()) 235f8a63a15SJakob Stoklund Olesen continue; 236e41e146cSMatthias Braun unsigned Reg = MO.getReg(); 237f8a63a15SJakob Stoklund Olesen 238f8a63a15SJakob Stoklund Olesen // Remember clobbered regunits. 239e41e146cSMatthias Braun if (MO.isDef() && TargetRegisterInfo::isPhysicalRegister(Reg)) 240f8a63a15SJakob Stoklund Olesen for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) 241f8a63a15SJakob Stoklund Olesen ClobberedRegUnits.set(*Units); 242f8a63a15SJakob Stoklund Olesen 243e41e146cSMatthias Braun if (!MO.readsReg() || !TargetRegisterInfo::isVirtualRegister(Reg)) 244f8a63a15SJakob Stoklund Olesen continue; 245f8a63a15SJakob Stoklund Olesen MachineInstr *DefMI = MRI->getVRegDef(Reg); 246f8a63a15SJakob Stoklund Olesen if (!DefMI || DefMI->getParent() != Head) 247f8a63a15SJakob Stoklund Olesen continue; 24870573dcdSDavid Blaikie if (InsertAfter.insert(DefMI).second) 249f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "BB#" << MBB->getNumber() << " depends on " << *DefMI); 250f8a63a15SJakob Stoklund Olesen if (DefMI->isTerminator()) { 251f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Can't insert instructions below terminator.\n"); 252f8a63a15SJakob Stoklund Olesen return false; 253f8a63a15SJakob Stoklund Olesen } 254f8a63a15SJakob Stoklund Olesen } 255f8a63a15SJakob Stoklund Olesen } 256f8a63a15SJakob Stoklund Olesen return true; 257f8a63a15SJakob Stoklund Olesen } 258f8a63a15SJakob Stoklund Olesen 259f8a63a15SJakob Stoklund Olesen 260f8a63a15SJakob Stoklund Olesen /// Find an insertion point in Head for the speculated instructions. The 261f8a63a15SJakob Stoklund Olesen /// insertion point must be: 262f8a63a15SJakob Stoklund Olesen /// 263f8a63a15SJakob Stoklund Olesen /// 1. Before any terminators. 264f8a63a15SJakob Stoklund Olesen /// 2. After any instructions in InsertAfter. 265f8a63a15SJakob Stoklund Olesen /// 3. Not have any clobbered regunits live. 266f8a63a15SJakob Stoklund Olesen /// 267f8a63a15SJakob Stoklund Olesen /// This function sets InsertionPoint and returns true when successful, it 268f8a63a15SJakob Stoklund Olesen /// returns false if no valid insertion point could be found. 269f8a63a15SJakob Stoklund Olesen /// 270f8a63a15SJakob Stoklund Olesen bool SSAIfConv::findInsertionPoint() { 271f8a63a15SJakob Stoklund Olesen // Keep track of live regunits before the current position. 272f8a63a15SJakob Stoklund Olesen // Only track RegUnits that are also in ClobberedRegUnits. 273f8a63a15SJakob Stoklund Olesen LiveRegUnits.clear(); 274f8a63a15SJakob Stoklund Olesen SmallVector<unsigned, 8> Reads; 275f8a63a15SJakob Stoklund Olesen MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator(); 276f8a63a15SJakob Stoklund Olesen MachineBasicBlock::iterator I = Head->end(); 277f8a63a15SJakob Stoklund Olesen MachineBasicBlock::iterator B = Head->begin(); 278f8a63a15SJakob Stoklund Olesen while (I != B) { 279f8a63a15SJakob Stoklund Olesen --I; 280f8a63a15SJakob Stoklund Olesen // Some of the conditional code depends in I. 281f8a63a15SJakob Stoklund Olesen if (InsertAfter.count(I)) { 282f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Can't insert code after " << *I); 283f8a63a15SJakob Stoklund Olesen return false; 284f8a63a15SJakob Stoklund Olesen } 285f8a63a15SJakob Stoklund Olesen 286f8a63a15SJakob Stoklund Olesen // Update live regunits. 287e41e146cSMatthias Braun for (const MachineOperand &MO : I->operands()) { 288f8a63a15SJakob Stoklund Olesen // We're ignoring regmask operands. That is conservatively correct. 289e41e146cSMatthias Braun if (!MO.isReg()) 290f8a63a15SJakob Stoklund Olesen continue; 291e41e146cSMatthias Braun unsigned Reg = MO.getReg(); 292f8a63a15SJakob Stoklund Olesen if (!TargetRegisterInfo::isPhysicalRegister(Reg)) 293f8a63a15SJakob Stoklund Olesen continue; 294f8a63a15SJakob Stoklund Olesen // I clobbers Reg, so it isn't live before I. 295e41e146cSMatthias Braun if (MO.isDef()) 296f8a63a15SJakob Stoklund Olesen for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) 297f8a63a15SJakob Stoklund Olesen LiveRegUnits.erase(*Units); 298f8a63a15SJakob Stoklund Olesen // Unless I reads Reg. 299e41e146cSMatthias Braun if (MO.readsReg()) 300f8a63a15SJakob Stoklund Olesen Reads.push_back(Reg); 301f8a63a15SJakob Stoklund Olesen } 302f8a63a15SJakob Stoklund Olesen // Anything read by I is live before I. 303f8a63a15SJakob Stoklund Olesen while (!Reads.empty()) 304f8a63a15SJakob Stoklund Olesen for (MCRegUnitIterator Units(Reads.pop_back_val(), TRI); Units.isValid(); 305f8a63a15SJakob Stoklund Olesen ++Units) 306f8a63a15SJakob Stoklund Olesen if (ClobberedRegUnits.test(*Units)) 307f8a63a15SJakob Stoklund Olesen LiveRegUnits.insert(*Units); 308f8a63a15SJakob Stoklund Olesen 309f8a63a15SJakob Stoklund Olesen // We can't insert before a terminator. 310f8a63a15SJakob Stoklund Olesen if (I != FirstTerm && I->isTerminator()) 311f8a63a15SJakob Stoklund Olesen continue; 312f8a63a15SJakob Stoklund Olesen 313f8a63a15SJakob Stoklund Olesen // Some of the clobbered registers are live before I, not a valid insertion 314f8a63a15SJakob Stoklund Olesen // point. 315f8a63a15SJakob Stoklund Olesen if (!LiveRegUnits.empty()) { 316f8a63a15SJakob Stoklund Olesen DEBUG({ 317f8a63a15SJakob Stoklund Olesen dbgs() << "Would clobber"; 318f8a63a15SJakob Stoklund Olesen for (SparseSet<unsigned>::const_iterator 319f8a63a15SJakob Stoklund Olesen i = LiveRegUnits.begin(), e = LiveRegUnits.end(); i != e; ++i) 320f8a63a15SJakob Stoklund Olesen dbgs() << ' ' << PrintRegUnit(*i, TRI); 321f8a63a15SJakob Stoklund Olesen dbgs() << " live before " << *I; 322f8a63a15SJakob Stoklund Olesen }); 323f8a63a15SJakob Stoklund Olesen continue; 324f8a63a15SJakob Stoklund Olesen } 325f8a63a15SJakob Stoklund Olesen 326f8a63a15SJakob Stoklund Olesen // This is a valid insertion point. 327f8a63a15SJakob Stoklund Olesen InsertionPoint = I; 328f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Can insert before " << *I); 329f8a63a15SJakob Stoklund Olesen return true; 330f8a63a15SJakob Stoklund Olesen } 331f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "No legal insertion point found.\n"); 332f8a63a15SJakob Stoklund Olesen return false; 333f8a63a15SJakob Stoklund Olesen } 334f8a63a15SJakob Stoklund Olesen 335f8a63a15SJakob Stoklund Olesen 336f8a63a15SJakob Stoklund Olesen 337f8a63a15SJakob Stoklund Olesen /// canConvertIf - analyze the sub-cfg rooted in MBB, and return true if it is 338f8a63a15SJakob Stoklund Olesen /// a potential candidate for if-conversion. Fill out the internal state. 339f8a63a15SJakob Stoklund Olesen /// 340f8a63a15SJakob Stoklund Olesen bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB) { 341f8a63a15SJakob Stoklund Olesen Head = MBB; 342c0196b1bSCraig Topper TBB = FBB = Tail = nullptr; 343f8a63a15SJakob Stoklund Olesen 344f8a63a15SJakob Stoklund Olesen if (Head->succ_size() != 2) 345f8a63a15SJakob Stoklund Olesen return false; 346f8a63a15SJakob Stoklund Olesen MachineBasicBlock *Succ0 = Head->succ_begin()[0]; 347f8a63a15SJakob Stoklund Olesen MachineBasicBlock *Succ1 = Head->succ_begin()[1]; 348f8a63a15SJakob Stoklund Olesen 349f8a63a15SJakob Stoklund Olesen // Canonicalize so Succ0 has MBB as its single predecessor. 350f8a63a15SJakob Stoklund Olesen if (Succ0->pred_size() != 1) 351f8a63a15SJakob Stoklund Olesen std::swap(Succ0, Succ1); 352f8a63a15SJakob Stoklund Olesen 353f8a63a15SJakob Stoklund Olesen if (Succ0->pred_size() != 1 || Succ0->succ_size() != 1) 354f8a63a15SJakob Stoklund Olesen return false; 355f8a63a15SJakob Stoklund Olesen 356f8a63a15SJakob Stoklund Olesen Tail = Succ0->succ_begin()[0]; 357f8a63a15SJakob Stoklund Olesen 358f8a63a15SJakob Stoklund Olesen // This is not a triangle. 359f8a63a15SJakob Stoklund Olesen if (Tail != Succ1) { 360f8a63a15SJakob Stoklund Olesen // Check for a diamond. We won't deal with any critical edges. 361f8a63a15SJakob Stoklund Olesen if (Succ1->pred_size() != 1 || Succ1->succ_size() != 1 || 362f8a63a15SJakob Stoklund Olesen Succ1->succ_begin()[0] != Tail) 363f8a63a15SJakob Stoklund Olesen return false; 364f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "\nDiamond: BB#" << Head->getNumber() 365f8a63a15SJakob Stoklund Olesen << " -> BB#" << Succ0->getNumber() 366f8a63a15SJakob Stoklund Olesen << "/BB#" << Succ1->getNumber() 367f8a63a15SJakob Stoklund Olesen << " -> BB#" << Tail->getNumber() << '\n'); 368f8a63a15SJakob Stoklund Olesen 369f8a63a15SJakob Stoklund Olesen // Live-in physregs are tricky to get right when speculating code. 370f8a63a15SJakob Stoklund Olesen if (!Tail->livein_empty()) { 371f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Tail has live-ins.\n"); 372f8a63a15SJakob Stoklund Olesen return false; 373f8a63a15SJakob Stoklund Olesen } 374f8a63a15SJakob Stoklund Olesen } else { 375f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "\nTriangle: BB#" << Head->getNumber() 376f8a63a15SJakob Stoklund Olesen << " -> BB#" << Succ0->getNumber() 377f8a63a15SJakob Stoklund Olesen << " -> BB#" << Tail->getNumber() << '\n'); 378f8a63a15SJakob Stoklund Olesen } 379f8a63a15SJakob Stoklund Olesen 380f8a63a15SJakob Stoklund Olesen // This is a triangle or a diamond. 381f8a63a15SJakob Stoklund Olesen // If Tail doesn't have any phis, there must be side effects. 382f8a63a15SJakob Stoklund Olesen if (Tail->empty() || !Tail->front().isPHI()) { 383f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "No phis in tail.\n"); 384f8a63a15SJakob Stoklund Olesen return false; 385f8a63a15SJakob Stoklund Olesen } 386f8a63a15SJakob Stoklund Olesen 387f8a63a15SJakob Stoklund Olesen // The branch we're looking to eliminate must be analyzable. 388f8a63a15SJakob Stoklund Olesen Cond.clear(); 389f8a63a15SJakob Stoklund Olesen if (TII->AnalyzeBranch(*Head, TBB, FBB, Cond)) { 390f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Branch not analyzable.\n"); 391f8a63a15SJakob Stoklund Olesen return false; 392f8a63a15SJakob Stoklund Olesen } 393f8a63a15SJakob Stoklund Olesen 394f8a63a15SJakob Stoklund Olesen // This is weird, probably some sort of degenerate CFG. 395f8a63a15SJakob Stoklund Olesen if (!TBB) { 396f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "AnalyzeBranch didn't find conditional branch.\n"); 397f8a63a15SJakob Stoklund Olesen return false; 398f8a63a15SJakob Stoklund Olesen } 399f8a63a15SJakob Stoklund Olesen 400f8a63a15SJakob Stoklund Olesen // AnalyzeBranch doesn't set FBB on a fall-through branch. 401f8a63a15SJakob Stoklund Olesen // Make sure it is always set. 402f8a63a15SJakob Stoklund Olesen FBB = TBB == Succ0 ? Succ1 : Succ0; 403f8a63a15SJakob Stoklund Olesen 404f8a63a15SJakob Stoklund Olesen // Any phis in the tail block must be convertible to selects. 405f8a63a15SJakob Stoklund Olesen PHIs.clear(); 4060a99062cSJakob Stoklund Olesen MachineBasicBlock *TPred = getTPred(); 4070a99062cSJakob Stoklund Olesen MachineBasicBlock *FPred = getFPred(); 408f8a63a15SJakob Stoklund Olesen for (MachineBasicBlock::iterator I = Tail->begin(), E = Tail->end(); 409f8a63a15SJakob Stoklund Olesen I != E && I->isPHI(); ++I) { 410f8a63a15SJakob Stoklund Olesen PHIs.push_back(&*I); 411f8a63a15SJakob Stoklund Olesen PHIInfo &PI = PHIs.back(); 412f8a63a15SJakob Stoklund Olesen // Find PHI operands corresponding to TPred and FPred. 413f8a63a15SJakob Stoklund Olesen for (unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) { 414f8a63a15SJakob Stoklund Olesen if (PI.PHI->getOperand(i+1).getMBB() == TPred) 415f8a63a15SJakob Stoklund Olesen PI.TReg = PI.PHI->getOperand(i).getReg(); 416f8a63a15SJakob Stoklund Olesen if (PI.PHI->getOperand(i+1).getMBB() == FPred) 417f8a63a15SJakob Stoklund Olesen PI.FReg = PI.PHI->getOperand(i).getReg(); 418f8a63a15SJakob Stoklund Olesen } 419f8a63a15SJakob Stoklund Olesen assert(TargetRegisterInfo::isVirtualRegister(PI.TReg) && "Bad PHI"); 420f8a63a15SJakob Stoklund Olesen assert(TargetRegisterInfo::isVirtualRegister(PI.FReg) && "Bad PHI"); 421f8a63a15SJakob Stoklund Olesen 422f8a63a15SJakob Stoklund Olesen // Get target information. 423f8a63a15SJakob Stoklund Olesen if (!TII->canInsertSelect(*Head, Cond, PI.TReg, PI.FReg, 424f8a63a15SJakob Stoklund Olesen PI.CondCycles, PI.TCycles, PI.FCycles)) { 425f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Can't convert: " << *PI.PHI); 426f8a63a15SJakob Stoklund Olesen return false; 427f8a63a15SJakob Stoklund Olesen } 428f8a63a15SJakob Stoklund Olesen } 429f8a63a15SJakob Stoklund Olesen 430f8a63a15SJakob Stoklund Olesen // Check that the conditional instructions can be speculated. 431f8a63a15SJakob Stoklund Olesen InsertAfter.clear(); 432f8a63a15SJakob Stoklund Olesen ClobberedRegUnits.reset(); 433f8a63a15SJakob Stoklund Olesen if (TBB != Tail && !canSpeculateInstrs(TBB)) 434f8a63a15SJakob Stoklund Olesen return false; 435f8a63a15SJakob Stoklund Olesen if (FBB != Tail && !canSpeculateInstrs(FBB)) 436f8a63a15SJakob Stoklund Olesen return false; 437f8a63a15SJakob Stoklund Olesen 438f8a63a15SJakob Stoklund Olesen // Try to find a valid insertion point for the speculated instructions in the 439f8a63a15SJakob Stoklund Olesen // head basic block. 440f8a63a15SJakob Stoklund Olesen if (!findInsertionPoint()) 441f8a63a15SJakob Stoklund Olesen return false; 442f8a63a15SJakob Stoklund Olesen 443d0af1d96SJakob Stoklund Olesen if (isTriangle()) 444d0af1d96SJakob Stoklund Olesen ++NumTrianglesSeen; 445d0af1d96SJakob Stoklund Olesen else 446d0af1d96SJakob Stoklund Olesen ++NumDiamondsSeen; 447f8a63a15SJakob Stoklund Olesen return true; 448f8a63a15SJakob Stoklund Olesen } 449f8a63a15SJakob Stoklund Olesen 45083a927d8SJakob Stoklund Olesen /// replacePHIInstrs - Completely replace PHI instructions with selects. 45183a927d8SJakob Stoklund Olesen /// This is possible when the only Tail predecessors are the if-converted 45283a927d8SJakob Stoklund Olesen /// blocks. 45383a927d8SJakob Stoklund Olesen void SSAIfConv::replacePHIInstrs() { 45483a927d8SJakob Stoklund Olesen assert(Tail->pred_size() == 2 && "Cannot replace PHIs"); 455f8a63a15SJakob Stoklund Olesen MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator(); 456f8a63a15SJakob Stoklund Olesen assert(FirstTerm != Head->end() && "No terminators"); 457f8a63a15SJakob Stoklund Olesen DebugLoc HeadDL = FirstTerm->getDebugLoc(); 458f8a63a15SJakob Stoklund Olesen 459f8a63a15SJakob Stoklund Olesen // Convert all PHIs to select instructions inserted before FirstTerm. 460f8a63a15SJakob Stoklund Olesen for (unsigned i = 0, e = PHIs.size(); i != e; ++i) { 461f8a63a15SJakob Stoklund Olesen PHIInfo &PI = PHIs[i]; 462f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "If-converting " << *PI.PHI); 463f8a63a15SJakob Stoklund Olesen unsigned DstReg = PI.PHI->getOperand(0).getReg(); 464f8a63a15SJakob Stoklund Olesen TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg, Cond, PI.TReg, PI.FReg); 465b6d0bd48SBenjamin Kramer DEBUG(dbgs() << " --> " << *std::prev(FirstTerm)); 466f8a63a15SJakob Stoklund Olesen PI.PHI->eraseFromParent(); 467c0196b1bSCraig Topper PI.PHI = nullptr; 468f8a63a15SJakob Stoklund Olesen } 46983a927d8SJakob Stoklund Olesen } 47083a927d8SJakob Stoklund Olesen 47183a927d8SJakob Stoklund Olesen /// rewritePHIOperands - When there are additional Tail predecessors, insert 47283a927d8SJakob Stoklund Olesen /// select instructions in Head and rewrite PHI operands to use the selects. 47383a927d8SJakob Stoklund Olesen /// Keep the PHI instructions in Tail to handle the other predecessors. 47483a927d8SJakob Stoklund Olesen void SSAIfConv::rewritePHIOperands() { 47583a927d8SJakob Stoklund Olesen MachineBasicBlock::iterator FirstTerm = Head->getFirstTerminator(); 47683a927d8SJakob Stoklund Olesen assert(FirstTerm != Head->end() && "No terminators"); 47783a927d8SJakob Stoklund Olesen DebugLoc HeadDL = FirstTerm->getDebugLoc(); 47883a927d8SJakob Stoklund Olesen 47983a927d8SJakob Stoklund Olesen // Convert all PHIs to select instructions inserted before FirstTerm. 48083a927d8SJakob Stoklund Olesen for (unsigned i = 0, e = PHIs.size(); i != e; ++i) { 48183a927d8SJakob Stoklund Olesen PHIInfo &PI = PHIs[i]; 482e0b3499dSYi Jiang unsigned DstReg = 0; 483e0b3499dSYi Jiang 48483a927d8SJakob Stoklund Olesen DEBUG(dbgs() << "If-converting " << *PI.PHI); 485e0b3499dSYi Jiang if (PI.TReg == PI.FReg) { 486e0b3499dSYi Jiang // We do not need the select instruction if both incoming values are 487e0b3499dSYi Jiang // equal. 488e0b3499dSYi Jiang DstReg = PI.TReg; 489e0b3499dSYi Jiang } else { 49083a927d8SJakob Stoklund Olesen unsigned PHIDst = PI.PHI->getOperand(0).getReg(); 491e0b3499dSYi Jiang DstReg = MRI->createVirtualRegister(MRI->getRegClass(PHIDst)); 492e0b3499dSYi Jiang TII->insertSelect(*Head, FirstTerm, HeadDL, 493e0b3499dSYi Jiang DstReg, Cond, PI.TReg, PI.FReg); 494b6d0bd48SBenjamin Kramer DEBUG(dbgs() << " --> " << *std::prev(FirstTerm)); 495e0b3499dSYi Jiang } 49683a927d8SJakob Stoklund Olesen 49783a927d8SJakob Stoklund Olesen // Rewrite PHI operands TPred -> (DstReg, Head), remove FPred. 49883a927d8SJakob Stoklund Olesen for (unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) { 49983a927d8SJakob Stoklund Olesen MachineBasicBlock *MBB = PI.PHI->getOperand(i-1).getMBB(); 50083a927d8SJakob Stoklund Olesen if (MBB == getTPred()) { 50183a927d8SJakob Stoklund Olesen PI.PHI->getOperand(i-1).setMBB(Head); 50283a927d8SJakob Stoklund Olesen PI.PHI->getOperand(i-2).setReg(DstReg); 50383a927d8SJakob Stoklund Olesen } else if (MBB == getFPred()) { 50483a927d8SJakob Stoklund Olesen PI.PHI->RemoveOperand(i-1); 50583a927d8SJakob Stoklund Olesen PI.PHI->RemoveOperand(i-2); 50683a927d8SJakob Stoklund Olesen } 50783a927d8SJakob Stoklund Olesen } 50883a927d8SJakob Stoklund Olesen DEBUG(dbgs() << " --> " << *PI.PHI); 50983a927d8SJakob Stoklund Olesen } 51083a927d8SJakob Stoklund Olesen } 51183a927d8SJakob Stoklund Olesen 51283a927d8SJakob Stoklund Olesen /// convertIf - Execute the if conversion after canConvertIf has determined the 51383a927d8SJakob Stoklund Olesen /// feasibility. 51483a927d8SJakob Stoklund Olesen /// 51583a927d8SJakob Stoklund Olesen /// Any basic blocks erased will be added to RemovedBlocks. 51683a927d8SJakob Stoklund Olesen /// 51783a927d8SJakob Stoklund Olesen void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock*> &RemovedBlocks) { 51883a927d8SJakob Stoklund Olesen assert(Head && Tail && TBB && FBB && "Call canConvertIf first."); 51983a927d8SJakob Stoklund Olesen 520d0af1d96SJakob Stoklund Olesen // Update statistics. 521d0af1d96SJakob Stoklund Olesen if (isTriangle()) 522d0af1d96SJakob Stoklund Olesen ++NumTrianglesConv; 523d0af1d96SJakob Stoklund Olesen else 524d0af1d96SJakob Stoklund Olesen ++NumDiamondsConv; 525d0af1d96SJakob Stoklund Olesen 52683a927d8SJakob Stoklund Olesen // Move all instructions into Head, except for the terminators. 52783a927d8SJakob Stoklund Olesen if (TBB != Tail) 52883a927d8SJakob Stoklund Olesen Head->splice(InsertionPoint, TBB, TBB->begin(), TBB->getFirstTerminator()); 52983a927d8SJakob Stoklund Olesen if (FBB != Tail) 53083a927d8SJakob Stoklund Olesen Head->splice(InsertionPoint, FBB, FBB->begin(), FBB->getFirstTerminator()); 53183a927d8SJakob Stoklund Olesen 53283a927d8SJakob Stoklund Olesen // Are there extra Tail predecessors? 53383a927d8SJakob Stoklund Olesen bool ExtraPreds = Tail->pred_size() != 2; 53483a927d8SJakob Stoklund Olesen if (ExtraPreds) 53583a927d8SJakob Stoklund Olesen rewritePHIOperands(); 53683a927d8SJakob Stoklund Olesen else 53783a927d8SJakob Stoklund Olesen replacePHIInstrs(); 538f8a63a15SJakob Stoklund Olesen 539f8a63a15SJakob Stoklund Olesen // Fix up the CFG, temporarily leave Head without any successors. 540f8a63a15SJakob Stoklund Olesen Head->removeSuccessor(TBB); 541*c106989fSCong Hou Head->removeSuccessor(FBB, true); 542f8a63a15SJakob Stoklund Olesen if (TBB != Tail) 543*c106989fSCong Hou TBB->removeSuccessor(Tail, true); 544f8a63a15SJakob Stoklund Olesen if (FBB != Tail) 545*c106989fSCong Hou FBB->removeSuccessor(Tail, true); 546f8a63a15SJakob Stoklund Olesen 547f8a63a15SJakob Stoklund Olesen // Fix up Head's terminators. 548f8a63a15SJakob Stoklund Olesen // It should become a single branch or a fallthrough. 54983a927d8SJakob Stoklund Olesen DebugLoc HeadDL = Head->getFirstTerminator()->getDebugLoc(); 550f8a63a15SJakob Stoklund Olesen TII->RemoveBranch(*Head); 551f8a63a15SJakob Stoklund Olesen 552f8a63a15SJakob Stoklund Olesen // Erase the now empty conditional blocks. It is likely that Head can fall 553f8a63a15SJakob Stoklund Olesen // through to Tail, and we can join the two blocks. 55402638392SJakob Stoklund Olesen if (TBB != Tail) { 55502638392SJakob Stoklund Olesen RemovedBlocks.push_back(TBB); 55602638392SJakob Stoklund Olesen TBB->eraseFromParent(); 55702638392SJakob Stoklund Olesen } 55802638392SJakob Stoklund Olesen if (FBB != Tail) { 55902638392SJakob Stoklund Olesen RemovedBlocks.push_back(FBB); 56002638392SJakob Stoklund Olesen FBB->eraseFromParent(); 56102638392SJakob Stoklund Olesen } 562f8a63a15SJakob Stoklund Olesen 563f8a63a15SJakob Stoklund Olesen assert(Head->succ_empty() && "Additional head successors?"); 56483a927d8SJakob Stoklund Olesen if (!ExtraPreds && Head->isLayoutSuccessor(Tail)) { 565f8a63a15SJakob Stoklund Olesen // Splice Tail onto the end of Head. 566f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Joining tail BB#" << Tail->getNumber() 567f8a63a15SJakob Stoklund Olesen << " into head BB#" << Head->getNumber() << '\n'); 568f8a63a15SJakob Stoklund Olesen Head->splice(Head->end(), Tail, 569f8a63a15SJakob Stoklund Olesen Tail->begin(), Tail->end()); 570f8a63a15SJakob Stoklund Olesen Head->transferSuccessorsAndUpdatePHIs(Tail); 57102638392SJakob Stoklund Olesen RemovedBlocks.push_back(Tail); 57202638392SJakob Stoklund Olesen Tail->eraseFromParent(); 573f8a63a15SJakob Stoklund Olesen } else { 574f8a63a15SJakob Stoklund Olesen // We need a branch to Tail, let code placement work it out later. 575f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "Converting to unconditional branch.\n"); 576f8a63a15SJakob Stoklund Olesen SmallVector<MachineOperand, 0> EmptyCond; 577c0196b1bSCraig Topper TII->InsertBranch(*Head, Tail, nullptr, EmptyCond, HeadDL); 578f8a63a15SJakob Stoklund Olesen Head->addSuccessor(Tail); 579f8a63a15SJakob Stoklund Olesen } 580f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << *Head); 581f8a63a15SJakob Stoklund Olesen } 582f8a63a15SJakob Stoklund Olesen 583f8a63a15SJakob Stoklund Olesen 584f8a63a15SJakob Stoklund Olesen //===----------------------------------------------------------------------===// 585f8a63a15SJakob Stoklund Olesen // EarlyIfConverter Pass 586f8a63a15SJakob Stoklund Olesen //===----------------------------------------------------------------------===// 587f8a63a15SJakob Stoklund Olesen 588f8a63a15SJakob Stoklund Olesen namespace { 589f8a63a15SJakob Stoklund Olesen class EarlyIfConverter : public MachineFunctionPass { 590f8a63a15SJakob Stoklund Olesen const TargetInstrInfo *TII; 591f8a63a15SJakob Stoklund Olesen const TargetRegisterInfo *TRI; 59211759457SPete Cooper MCSchedModel SchedModel; 593f8a63a15SJakob Stoklund Olesen MachineRegisterInfo *MRI; 59402638392SJakob Stoklund Olesen MachineDominatorTree *DomTree; 595bc90a4eaSJakob Stoklund Olesen MachineLoopInfo *Loops; 596f9029fefSJakob Stoklund Olesen MachineTraceMetrics *Traces; 597f9029fefSJakob Stoklund Olesen MachineTraceMetrics::Ensemble *MinInstr; 598f8a63a15SJakob Stoklund Olesen SSAIfConv IfConv; 599f8a63a15SJakob Stoklund Olesen 600f8a63a15SJakob Stoklund Olesen public: 601f8a63a15SJakob Stoklund Olesen static char ID; 602f8a63a15SJakob Stoklund Olesen EarlyIfConverter() : MachineFunctionPass(ID) {} 6034584cd54SCraig Topper void getAnalysisUsage(AnalysisUsage &AU) const override; 6044584cd54SCraig Topper bool runOnMachineFunction(MachineFunction &MF) override; 6054584cd54SCraig Topper const char *getPassName() const override { return "Early If-Conversion"; } 606f8a63a15SJakob Stoklund Olesen 607f8a63a15SJakob Stoklund Olesen private: 608f8a63a15SJakob Stoklund Olesen bool tryConvertIf(MachineBasicBlock*); 60902638392SJakob Stoklund Olesen void updateDomTree(ArrayRef<MachineBasicBlock*> Removed); 610bc90a4eaSJakob Stoklund Olesen void updateLoops(ArrayRef<MachineBasicBlock*> Removed); 611f9029fefSJakob Stoklund Olesen void invalidateTraces(); 612f9029fefSJakob Stoklund Olesen bool shouldConvertIf(); 613f8a63a15SJakob Stoklund Olesen }; 614f8a63a15SJakob Stoklund Olesen } // end anonymous namespace 615f8a63a15SJakob Stoklund Olesen 616f8a63a15SJakob Stoklund Olesen char EarlyIfConverter::ID = 0; 617f8a63a15SJakob Stoklund Olesen char &llvm::EarlyIfConverterID = EarlyIfConverter::ID; 618f8a63a15SJakob Stoklund Olesen 619f8a63a15SJakob Stoklund Olesen INITIALIZE_PASS_BEGIN(EarlyIfConverter, 620f8a63a15SJakob Stoklund Olesen "early-ifcvt", "Early If Converter", false, false) 621f8a63a15SJakob Stoklund Olesen INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) 62202638392SJakob Stoklund Olesen INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) 623f9029fefSJakob Stoklund Olesen INITIALIZE_PASS_DEPENDENCY(MachineTraceMetrics) 624f8a63a15SJakob Stoklund Olesen INITIALIZE_PASS_END(EarlyIfConverter, 625f8a63a15SJakob Stoklund Olesen "early-ifcvt", "Early If Converter", false, false) 626f8a63a15SJakob Stoklund Olesen 627f8a63a15SJakob Stoklund Olesen void EarlyIfConverter::getAnalysisUsage(AnalysisUsage &AU) const { 628f8a63a15SJakob Stoklund Olesen AU.addRequired<MachineBranchProbabilityInfo>(); 62902638392SJakob Stoklund Olesen AU.addRequired<MachineDominatorTree>(); 63002638392SJakob Stoklund Olesen AU.addPreserved<MachineDominatorTree>(); 631bc90a4eaSJakob Stoklund Olesen AU.addRequired<MachineLoopInfo>(); 632bc90a4eaSJakob Stoklund Olesen AU.addPreserved<MachineLoopInfo>(); 633f9029fefSJakob Stoklund Olesen AU.addRequired<MachineTraceMetrics>(); 634f9029fefSJakob Stoklund Olesen AU.addPreserved<MachineTraceMetrics>(); 635f8a63a15SJakob Stoklund Olesen MachineFunctionPass::getAnalysisUsage(AU); 636f8a63a15SJakob Stoklund Olesen } 637f8a63a15SJakob Stoklund Olesen 63802638392SJakob Stoklund Olesen /// Update the dominator tree after if-conversion erased some blocks. 63902638392SJakob Stoklund Olesen void EarlyIfConverter::updateDomTree(ArrayRef<MachineBasicBlock*> Removed) { 64002638392SJakob Stoklund Olesen // convertIf can remove TBB, FBB, and Tail can be merged into Head. 64102638392SJakob Stoklund Olesen // TBB and FBB should not dominate any blocks. 64202638392SJakob Stoklund Olesen // Tail children should be transferred to Head. 64302638392SJakob Stoklund Olesen MachineDomTreeNode *HeadNode = DomTree->getNode(IfConv.Head); 64402638392SJakob Stoklund Olesen for (unsigned i = 0, e = Removed.size(); i != e; ++i) { 64502638392SJakob Stoklund Olesen MachineDomTreeNode *Node = DomTree->getNode(Removed[i]); 64602638392SJakob Stoklund Olesen assert(Node != HeadNode && "Cannot erase the head node"); 64702638392SJakob Stoklund Olesen while (Node->getNumChildren()) { 64802638392SJakob Stoklund Olesen assert(Node->getBlock() == IfConv.Tail && "Unexpected children"); 64902638392SJakob Stoklund Olesen DomTree->changeImmediateDominator(Node->getChildren().back(), HeadNode); 65002638392SJakob Stoklund Olesen } 65102638392SJakob Stoklund Olesen DomTree->eraseNode(Removed[i]); 65202638392SJakob Stoklund Olesen } 653f8a63a15SJakob Stoklund Olesen } 654f8a63a15SJakob Stoklund Olesen 655bc90a4eaSJakob Stoklund Olesen /// Update LoopInfo after if-conversion. 656bc90a4eaSJakob Stoklund Olesen void EarlyIfConverter::updateLoops(ArrayRef<MachineBasicBlock*> Removed) { 657bc90a4eaSJakob Stoklund Olesen if (!Loops) 658bc90a4eaSJakob Stoklund Olesen return; 659bc90a4eaSJakob Stoklund Olesen // If-conversion doesn't change loop structure, and it doesn't mess with back 660bc90a4eaSJakob Stoklund Olesen // edges, so updating LoopInfo is simply removing the dead blocks. 661bc90a4eaSJakob Stoklund Olesen for (unsigned i = 0, e = Removed.size(); i != e; ++i) 662bc90a4eaSJakob Stoklund Olesen Loops->removeBlock(Removed[i]); 663bc90a4eaSJakob Stoklund Olesen } 664bc90a4eaSJakob Stoklund Olesen 665f9029fefSJakob Stoklund Olesen /// Invalidate MachineTraceMetrics before if-conversion. 666f9029fefSJakob Stoklund Olesen void EarlyIfConverter::invalidateTraces() { 667a12a7d5fSJakob Stoklund Olesen Traces->verifyAnalysis(); 668f9029fefSJakob Stoklund Olesen Traces->invalidate(IfConv.Head); 669f9029fefSJakob Stoklund Olesen Traces->invalidate(IfConv.Tail); 670f9029fefSJakob Stoklund Olesen Traces->invalidate(IfConv.TBB); 671f9029fefSJakob Stoklund Olesen Traces->invalidate(IfConv.FBB); 672a12a7d5fSJakob Stoklund Olesen Traces->verifyAnalysis(); 673f9029fefSJakob Stoklund Olesen } 674f9029fefSJakob Stoklund Olesen 675bc55bfdeSJakob Stoklund Olesen // Adjust cycles with downward saturation. 676bc55bfdeSJakob Stoklund Olesen static unsigned adjCycles(unsigned Cyc, int Delta) { 677bc55bfdeSJakob Stoklund Olesen if (Delta < 0 && Cyc + Delta > Cyc) 678bc55bfdeSJakob Stoklund Olesen return 0; 679bc55bfdeSJakob Stoklund Olesen return Cyc + Delta; 680bc55bfdeSJakob Stoklund Olesen } 681bc55bfdeSJakob Stoklund Olesen 682f9029fefSJakob Stoklund Olesen /// Apply cost model and heuristics to the if-conversion in IfConv. 683f9029fefSJakob Stoklund Olesen /// Return true if the conversion is a good idea. 684f9029fefSJakob Stoklund Olesen /// 685f9029fefSJakob Stoklund Olesen bool EarlyIfConverter::shouldConvertIf() { 686fa8a26f9SJakob Stoklund Olesen // Stress testing mode disables all cost considerations. 687fa8a26f9SJakob Stoklund Olesen if (Stress) 688fa8a26f9SJakob Stoklund Olesen return true; 689fa8a26f9SJakob Stoklund Olesen 690f9029fefSJakob Stoklund Olesen if (!MinInstr) 691f9029fefSJakob Stoklund Olesen MinInstr = Traces->getEnsemble(MachineTraceMetrics::TS_MinInstrCount); 69275d9d515SJakob Stoklund Olesen 693bc55bfdeSJakob Stoklund Olesen MachineTraceMetrics::Trace TBBTrace = MinInstr->getTrace(IfConv.getTPred()); 694bc55bfdeSJakob Stoklund Olesen MachineTraceMetrics::Trace FBBTrace = MinInstr->getTrace(IfConv.getFPred()); 69575d9d515SJakob Stoklund Olesen DEBUG(dbgs() << "TBB: " << TBBTrace << "FBB: " << FBBTrace); 696bc55bfdeSJakob Stoklund Olesen unsigned MinCrit = std::min(TBBTrace.getCriticalPath(), 697bc55bfdeSJakob Stoklund Olesen FBBTrace.getCriticalPath()); 698bc55bfdeSJakob Stoklund Olesen 699bc55bfdeSJakob Stoklund Olesen // Set a somewhat arbitrary limit on the critical path extension we accept. 70011759457SPete Cooper unsigned CritLimit = SchedModel.MispredictPenalty/2; 701bc55bfdeSJakob Stoklund Olesen 702bc55bfdeSJakob Stoklund Olesen // If-conversion only makes sense when there is unexploited ILP. Compute the 703bc55bfdeSJakob Stoklund Olesen // maximum-ILP resource length of the trace after if-conversion. Compare it 704bc55bfdeSJakob Stoklund Olesen // to the shortest critical path. 705bc55bfdeSJakob Stoklund Olesen SmallVector<const MachineBasicBlock*, 1> ExtraBlocks; 706bc55bfdeSJakob Stoklund Olesen if (IfConv.TBB != IfConv.Tail) 707bc55bfdeSJakob Stoklund Olesen ExtraBlocks.push_back(IfConv.TBB); 708bc55bfdeSJakob Stoklund Olesen unsigned ResLength = FBBTrace.getResourceLength(ExtraBlocks); 709bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Resource length " << ResLength 710bc55bfdeSJakob Stoklund Olesen << ", minimal critical path " << MinCrit << '\n'); 711bc55bfdeSJakob Stoklund Olesen if (ResLength > MinCrit + CritLimit) { 712bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Not enough available ILP.\n"); 71375d9d515SJakob Stoklund Olesen return false; 71475d9d515SJakob Stoklund Olesen } 715bc55bfdeSJakob Stoklund Olesen 716bc55bfdeSJakob Stoklund Olesen // Assume that the depth of the first head terminator will also be the depth 717bc55bfdeSJakob Stoklund Olesen // of the select instruction inserted, as determined by the flag dependency. 718bc55bfdeSJakob Stoklund Olesen // TBB / FBB data dependencies may delay the select even more. 719bc55bfdeSJakob Stoklund Olesen MachineTraceMetrics::Trace HeadTrace = MinInstr->getTrace(IfConv.Head); 720bc55bfdeSJakob Stoklund Olesen unsigned BranchDepth = 721bc55bfdeSJakob Stoklund Olesen HeadTrace.getInstrCycles(IfConv.Head->getFirstTerminator()).Depth; 722bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Branch depth: " << BranchDepth << '\n'); 723bc55bfdeSJakob Stoklund Olesen 724bc55bfdeSJakob Stoklund Olesen // Look at all the tail phis, and compute the critical path extension caused 725bc55bfdeSJakob Stoklund Olesen // by inserting select instructions. 726bc55bfdeSJakob Stoklund Olesen MachineTraceMetrics::Trace TailTrace = MinInstr->getTrace(IfConv.Tail); 727bc55bfdeSJakob Stoklund Olesen for (unsigned i = 0, e = IfConv.PHIs.size(); i != e; ++i) { 728bc55bfdeSJakob Stoklund Olesen SSAIfConv::PHIInfo &PI = IfConv.PHIs[i]; 729bc55bfdeSJakob Stoklund Olesen unsigned Slack = TailTrace.getInstrSlack(PI.PHI); 730bc55bfdeSJakob Stoklund Olesen unsigned MaxDepth = Slack + TailTrace.getInstrCycles(PI.PHI).Depth; 731bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Slack " << Slack << ":\t" << *PI.PHI); 732bc55bfdeSJakob Stoklund Olesen 733bc55bfdeSJakob Stoklund Olesen // The condition is pulled into the critical path. 734bc55bfdeSJakob Stoklund Olesen unsigned CondDepth = adjCycles(BranchDepth, PI.CondCycles); 735bc55bfdeSJakob Stoklund Olesen if (CondDepth > MaxDepth) { 736bc55bfdeSJakob Stoklund Olesen unsigned Extra = CondDepth - MaxDepth; 737bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Condition adds " << Extra << " cycles.\n"); 738bc55bfdeSJakob Stoklund Olesen if (Extra > CritLimit) { 739bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n'); 740bc55bfdeSJakob Stoklund Olesen return false; 741bc55bfdeSJakob Stoklund Olesen } 742bc55bfdeSJakob Stoklund Olesen } 743bc55bfdeSJakob Stoklund Olesen 744bc55bfdeSJakob Stoklund Olesen // The TBB value is pulled into the critical path. 745bc55bfdeSJakob Stoklund Olesen unsigned TDepth = adjCycles(TBBTrace.getPHIDepth(PI.PHI), PI.TCycles); 746bc55bfdeSJakob Stoklund Olesen if (TDepth > MaxDepth) { 747bc55bfdeSJakob Stoklund Olesen unsigned Extra = TDepth - MaxDepth; 748bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "TBB data adds " << Extra << " cycles.\n"); 749bc55bfdeSJakob Stoklund Olesen if (Extra > CritLimit) { 750bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n'); 751bc55bfdeSJakob Stoklund Olesen return false; 752bc55bfdeSJakob Stoklund Olesen } 753bc55bfdeSJakob Stoklund Olesen } 754bc55bfdeSJakob Stoklund Olesen 755bc55bfdeSJakob Stoklund Olesen // The FBB value is pulled into the critical path. 756bc55bfdeSJakob Stoklund Olesen unsigned FDepth = adjCycles(FBBTrace.getPHIDepth(PI.PHI), PI.FCycles); 757bc55bfdeSJakob Stoklund Olesen if (FDepth > MaxDepth) { 758bc55bfdeSJakob Stoklund Olesen unsigned Extra = FDepth - MaxDepth; 759bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "FBB data adds " << Extra << " cycles.\n"); 760bc55bfdeSJakob Stoklund Olesen if (Extra > CritLimit) { 761bc55bfdeSJakob Stoklund Olesen DEBUG(dbgs() << "Exceeds limit of " << CritLimit << '\n'); 762bc55bfdeSJakob Stoklund Olesen return false; 763bc55bfdeSJakob Stoklund Olesen } 764bc55bfdeSJakob Stoklund Olesen } 765bc55bfdeSJakob Stoklund Olesen } 766f9029fefSJakob Stoklund Olesen return true; 767f9029fefSJakob Stoklund Olesen } 768f9029fefSJakob Stoklund Olesen 76902638392SJakob Stoklund Olesen /// Attempt repeated if-conversion on MBB, return true if successful. 77002638392SJakob Stoklund Olesen /// 77102638392SJakob Stoklund Olesen bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *MBB) { 77202638392SJakob Stoklund Olesen bool Changed = false; 773f9029fefSJakob Stoklund Olesen while (IfConv.canConvertIf(MBB) && shouldConvertIf()) { 77402638392SJakob Stoklund Olesen // If-convert MBB and update analyses. 775f9029fefSJakob Stoklund Olesen invalidateTraces(); 77602638392SJakob Stoklund Olesen SmallVector<MachineBasicBlock*, 4> RemovedBlocks; 77702638392SJakob Stoklund Olesen IfConv.convertIf(RemovedBlocks); 77802638392SJakob Stoklund Olesen Changed = true; 77902638392SJakob Stoklund Olesen updateDomTree(RemovedBlocks); 780bc90a4eaSJakob Stoklund Olesen updateLoops(RemovedBlocks); 78102638392SJakob Stoklund Olesen } 78202638392SJakob Stoklund Olesen return Changed; 78302638392SJakob Stoklund Olesen } 784f8a63a15SJakob Stoklund Olesen 785f8a63a15SJakob Stoklund Olesen bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) { 786f8a63a15SJakob Stoklund Olesen DEBUG(dbgs() << "********** EARLY IF-CONVERSION **********\n" 787c8c2920aSDavid Blaikie << "********** Function: " << MF.getName() << '\n'); 7886b0fcfeeSEric Christopher // Only run if conversion if the target wants it. 7893d4276f0SEric Christopher const TargetSubtargetInfo &STI = MF.getSubtarget(); 7903d4276f0SEric Christopher if (!STI.enableEarlyIfConversion()) 7919eff5178SEric Christopher return false; 7926b0fcfeeSEric Christopher 7933d4276f0SEric Christopher TII = STI.getInstrInfo(); 7943d4276f0SEric Christopher TRI = STI.getRegisterInfo(); 7953d4276f0SEric Christopher SchedModel = STI.getSchedModel(); 796f8a63a15SJakob Stoklund Olesen MRI = &MF.getRegInfo(); 79702638392SJakob Stoklund Olesen DomTree = &getAnalysis<MachineDominatorTree>(); 798bc90a4eaSJakob Stoklund Olesen Loops = getAnalysisIfAvailable<MachineLoopInfo>(); 799f9029fefSJakob Stoklund Olesen Traces = &getAnalysis<MachineTraceMetrics>(); 800c0196b1bSCraig Topper MinInstr = nullptr; 801f8a63a15SJakob Stoklund Olesen 802f8a63a15SJakob Stoklund Olesen bool Changed = false; 803f8a63a15SJakob Stoklund Olesen IfConv.runOnMachineFunction(MF); 804f8a63a15SJakob Stoklund Olesen 80502638392SJakob Stoklund Olesen // Visit blocks in dominator tree post-order. The post-order enables nested 80602638392SJakob Stoklund Olesen // if-conversion in a single pass. The tryConvertIf() function may erase 80702638392SJakob Stoklund Olesen // blocks, but only blocks dominated by the head block. This makes it safe to 80802638392SJakob Stoklund Olesen // update the dominator tree while the post-order iterator is still active. 80925db4f41SDaniel Berlin for (auto DomNode : post_order(DomTree)) 81025db4f41SDaniel Berlin if (tryConvertIf(DomNode->getBlock())) 811f8a63a15SJakob Stoklund Olesen Changed = true; 812f8a63a15SJakob Stoklund Olesen 813f8a63a15SJakob Stoklund Olesen return Changed; 814f8a63a15SJakob Stoklund Olesen } 815