1*0b57cec5SDimitry Andric //===------------- PPCExpandISEL.cpp - Expand ISEL instruction ------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // A pass that expands the ISEL instruction into an if-then-else sequence. 10*0b57cec5SDimitry Andric // This pass must be run post-RA since all operands must be physical registers. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "PPC.h" 15*0b57cec5SDimitry Andric #include "PPCInstrInfo.h" 16*0b57cec5SDimitry Andric #include "PPCSubtarget.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h" 20*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 21*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 22*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 23*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 24*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 25*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric using namespace llvm; 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric #define DEBUG_TYPE "ppc-expand-isel" 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric STATISTIC(NumExpanded, "Number of ISEL instructions expanded"); 32*0b57cec5SDimitry Andric STATISTIC(NumRemoved, "Number of ISEL instructions removed"); 33*0b57cec5SDimitry Andric STATISTIC(NumFolded, "Number of ISEL instructions folded"); 34*0b57cec5SDimitry Andric 35*0b57cec5SDimitry Andric // If -ppc-gen-isel=false is set, we will disable generating the ISEL 36*0b57cec5SDimitry Andric // instruction on all PPC targets. Otherwise, if the user set option 37*0b57cec5SDimitry Andric // -misel or the platform supports ISEL by default, still generate the 38*0b57cec5SDimitry Andric // ISEL instruction, else expand it. 39*0b57cec5SDimitry Andric static cl::opt<bool> 40*0b57cec5SDimitry Andric GenerateISEL("ppc-gen-isel", 41*0b57cec5SDimitry Andric cl::desc("Enable generating the ISEL instruction."), 42*0b57cec5SDimitry Andric cl::init(true), cl::Hidden); 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric namespace { 45*0b57cec5SDimitry Andric class PPCExpandISEL : public MachineFunctionPass { 46*0b57cec5SDimitry Andric DebugLoc dl; 47*0b57cec5SDimitry Andric MachineFunction *MF; 48*0b57cec5SDimitry Andric const TargetInstrInfo *TII; 49*0b57cec5SDimitry Andric bool IsTrueBlockRequired; 50*0b57cec5SDimitry Andric bool IsFalseBlockRequired; 51*0b57cec5SDimitry Andric MachineBasicBlock *TrueBlock; 52*0b57cec5SDimitry Andric MachineBasicBlock *FalseBlock; 53*0b57cec5SDimitry Andric MachineBasicBlock *NewSuccessor; 54*0b57cec5SDimitry Andric MachineBasicBlock::iterator TrueBlockI; 55*0b57cec5SDimitry Andric MachineBasicBlock::iterator FalseBlockI; 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric typedef SmallVector<MachineInstr *, 4> BlockISELList; 58*0b57cec5SDimitry Andric typedef SmallDenseMap<int, BlockISELList> ISELInstructionList; 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric // A map of MBB numbers to their lists of contained ISEL instructions. 61*0b57cec5SDimitry Andric // Please note when we traverse this list and expand ISEL, we only remove 62*0b57cec5SDimitry Andric // the ISEL from the MBB not from this list. 63*0b57cec5SDimitry Andric ISELInstructionList ISELInstructions; 64*0b57cec5SDimitry Andric 65*0b57cec5SDimitry Andric /// Initialize the object. 66*0b57cec5SDimitry Andric void initialize(MachineFunction &MFParam); 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric void handleSpecialCases(BlockISELList &BIL, MachineBasicBlock *MBB); 69*0b57cec5SDimitry Andric void reorganizeBlockLayout(BlockISELList &BIL, MachineBasicBlock *MBB); 70*0b57cec5SDimitry Andric void populateBlocks(BlockISELList &BIL); 71*0b57cec5SDimitry Andric void expandMergeableISELs(BlockISELList &BIL); 72*0b57cec5SDimitry Andric void expandAndMergeISELs(); 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric bool canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI); 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric /// Is this instruction an ISEL or ISEL8? 77*0b57cec5SDimitry Andric static bool isISEL(const MachineInstr &MI) { 78*0b57cec5SDimitry Andric return (MI.getOpcode() == PPC::ISEL || MI.getOpcode() == PPC::ISEL8); 79*0b57cec5SDimitry Andric } 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric /// Is this instruction an ISEL8? 82*0b57cec5SDimitry Andric static bool isISEL8(const MachineInstr &MI) { 83*0b57cec5SDimitry Andric return (MI.getOpcode() == PPC::ISEL8); 84*0b57cec5SDimitry Andric } 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric /// Are the two operands using the same register? 87*0b57cec5SDimitry Andric bool useSameRegister(const MachineOperand &Op1, const MachineOperand &Op2) { 88*0b57cec5SDimitry Andric return (Op1.getReg() == Op2.getReg()); 89*0b57cec5SDimitry Andric } 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric /// 92*0b57cec5SDimitry Andric /// Collect all ISEL instructions from the current function. 93*0b57cec5SDimitry Andric /// 94*0b57cec5SDimitry Andric /// Walk the current function and collect all the ISEL instructions that are 95*0b57cec5SDimitry Andric /// found. The instructions are placed in the ISELInstructions vector. 96*0b57cec5SDimitry Andric /// 97*0b57cec5SDimitry Andric /// \return true if any ISEL instructions were found, false otherwise 98*0b57cec5SDimitry Andric /// 99*0b57cec5SDimitry Andric bool collectISELInstructions(); 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric public: 102*0b57cec5SDimitry Andric static char ID; 103*0b57cec5SDimitry Andric PPCExpandISEL() : MachineFunctionPass(ID) { 104*0b57cec5SDimitry Andric initializePPCExpandISELPass(*PassRegistry::getPassRegistry()); 105*0b57cec5SDimitry Andric } 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric /// 108*0b57cec5SDimitry Andric /// Determine whether to generate the ISEL instruction or expand it. 109*0b57cec5SDimitry Andric /// 110*0b57cec5SDimitry Andric /// Expand ISEL instruction into if-then-else sequence when one of 111*0b57cec5SDimitry Andric /// the following two conditions hold: 112*0b57cec5SDimitry Andric /// (1) -ppc-gen-isel=false 113*0b57cec5SDimitry Andric /// (2) hasISEL() return false 114*0b57cec5SDimitry Andric /// Otherwise, still generate ISEL instruction. 115*0b57cec5SDimitry Andric /// The -ppc-gen-isel option is set to true by default. Which means the ISEL 116*0b57cec5SDimitry Andric /// instruction is still generated by default on targets that support them. 117*0b57cec5SDimitry Andric /// 118*0b57cec5SDimitry Andric /// \return true if ISEL should be expanded into if-then-else code sequence; 119*0b57cec5SDimitry Andric /// false if ISEL instruction should be generated, i.e. not expanded. 120*0b57cec5SDimitry Andric /// 121*0b57cec5SDimitry Andric static bool isExpandISELEnabled(const MachineFunction &MF); 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric #ifndef NDEBUG 124*0b57cec5SDimitry Andric void DumpISELInstructions() const; 125*0b57cec5SDimitry Andric #endif 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override { 128*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n"); 129*0b57cec5SDimitry Andric initialize(MF); 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric if (!collectISELInstructions()) { 132*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "No ISEL instructions in this function\n"); 133*0b57cec5SDimitry Andric return false; 134*0b57cec5SDimitry Andric } 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric #ifndef NDEBUG 137*0b57cec5SDimitry Andric DumpISELInstructions(); 138*0b57cec5SDimitry Andric #endif 139*0b57cec5SDimitry Andric 140*0b57cec5SDimitry Andric expandAndMergeISELs(); 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric return true; 143*0b57cec5SDimitry Andric } 144*0b57cec5SDimitry Andric }; 145*0b57cec5SDimitry Andric } // end anonymous namespace 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric void PPCExpandISEL::initialize(MachineFunction &MFParam) { 148*0b57cec5SDimitry Andric MF = &MFParam; 149*0b57cec5SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 150*0b57cec5SDimitry Andric ISELInstructions.clear(); 151*0b57cec5SDimitry Andric } 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric bool PPCExpandISEL::isExpandISELEnabled(const MachineFunction &MF) { 154*0b57cec5SDimitry Andric return !GenerateISEL || !MF.getSubtarget<PPCSubtarget>().hasISEL(); 155*0b57cec5SDimitry Andric } 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric bool PPCExpandISEL::collectISELInstructions() { 158*0b57cec5SDimitry Andric for (MachineBasicBlock &MBB : *MF) { 159*0b57cec5SDimitry Andric BlockISELList thisBlockISELs; 160*0b57cec5SDimitry Andric for (MachineInstr &MI : MBB) 161*0b57cec5SDimitry Andric if (isISEL(MI)) 162*0b57cec5SDimitry Andric thisBlockISELs.push_back(&MI); 163*0b57cec5SDimitry Andric if (!thisBlockISELs.empty()) 164*0b57cec5SDimitry Andric ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs)); 165*0b57cec5SDimitry Andric } 166*0b57cec5SDimitry Andric return !ISELInstructions.empty(); 167*0b57cec5SDimitry Andric } 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric #ifndef NDEBUG 170*0b57cec5SDimitry Andric void PPCExpandISEL::DumpISELInstructions() const { 171*0b57cec5SDimitry Andric for (const auto &I : ISELInstructions) { 172*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MF->getBlockNumbered(I.first)) 173*0b57cec5SDimitry Andric << ":\n"); 174*0b57cec5SDimitry Andric for (const auto &VI : I.second) 175*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " "; VI->print(dbgs())); 176*0b57cec5SDimitry Andric } 177*0b57cec5SDimitry Andric } 178*0b57cec5SDimitry Andric #endif 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric /// Contiguous ISELs that have the same condition can be merged. 181*0b57cec5SDimitry Andric bool PPCExpandISEL::canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI) { 182*0b57cec5SDimitry Andric // Same Condition Register? 183*0b57cec5SDimitry Andric if (!useSameRegister(PrevPushedMI->getOperand(3), MI->getOperand(3))) 184*0b57cec5SDimitry Andric return false; 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric MachineBasicBlock::iterator PrevPushedMBBI = *PrevPushedMI; 187*0b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = *MI; 188*0b57cec5SDimitry Andric return (std::prev(MBBI) == PrevPushedMBBI); // Contiguous ISELs? 189*0b57cec5SDimitry Andric } 190*0b57cec5SDimitry Andric 191*0b57cec5SDimitry Andric void PPCExpandISEL::expandAndMergeISELs() { 192*0b57cec5SDimitry Andric bool ExpandISELEnabled = isExpandISELEnabled(*MF); 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric for (auto &BlockList : ISELInstructions) { 195*0b57cec5SDimitry Andric LLVM_DEBUG( 196*0b57cec5SDimitry Andric dbgs() << "Expanding ISEL instructions in " 197*0b57cec5SDimitry Andric << printMBBReference(*MF->getBlockNumbered(BlockList.first)) 198*0b57cec5SDimitry Andric << "\n"); 199*0b57cec5SDimitry Andric BlockISELList &CurrentISELList = BlockList.second; 200*0b57cec5SDimitry Andric auto I = CurrentISELList.begin(); 201*0b57cec5SDimitry Andric auto E = CurrentISELList.end(); 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric while (I != E) { 204*0b57cec5SDimitry Andric assert(isISEL(**I) && "Expecting an ISEL instruction"); 205*0b57cec5SDimitry Andric MachineOperand &Dest = (*I)->getOperand(0); 206*0b57cec5SDimitry Andric MachineOperand &TrueValue = (*I)->getOperand(1); 207*0b57cec5SDimitry Andric MachineOperand &FalseValue = (*I)->getOperand(2); 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric // Special case 1, all registers used by ISEL are the same one. 210*0b57cec5SDimitry Andric // The non-redundant isel 0, 0, 0, N would not satisfy these conditions 211*0b57cec5SDimitry Andric // as it would be ISEL %R0, %ZERO, %R0, %CRN. 212*0b57cec5SDimitry Andric if (useSameRegister(Dest, TrueValue) && 213*0b57cec5SDimitry Andric useSameRegister(Dest, FalseValue)) { 214*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction: " << **I 215*0b57cec5SDimitry Andric << "\n"); 216*0b57cec5SDimitry Andric // FIXME: if the CR field used has no other uses, we could eliminate the 217*0b57cec5SDimitry Andric // instruction that defines it. This would have to be done manually 218*0b57cec5SDimitry Andric // since this pass runs too late to run DCE after it. 219*0b57cec5SDimitry Andric NumRemoved++; 220*0b57cec5SDimitry Andric (*I)->eraseFromParent(); 221*0b57cec5SDimitry Andric I++; 222*0b57cec5SDimitry Andric } else if (useSameRegister(TrueValue, FalseValue)) { 223*0b57cec5SDimitry Andric // Special case 2, the two input registers used by ISEL are the same. 224*0b57cec5SDimitry Andric // Note: the non-foldable isel RX, 0, 0, N would not satisfy this 225*0b57cec5SDimitry Andric // condition as it would be ISEL %RX, %ZERO, %R0, %CRN, which makes it 226*0b57cec5SDimitry Andric // safe to fold ISEL to MR(OR) instead of ADDI. 227*0b57cec5SDimitry Andric MachineBasicBlock *MBB = (*I)->getParent(); 228*0b57cec5SDimitry Andric LLVM_DEBUG( 229*0b57cec5SDimitry Andric dbgs() << "Fold the ISEL instruction to an unconditional copy:\n"); 230*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n"); 231*0b57cec5SDimitry Andric NumFolded++; 232*0b57cec5SDimitry Andric // Note: we're using both the TrueValue and FalseValue operands so as 233*0b57cec5SDimitry Andric // not to lose the kill flag if it is set on either of them. 234*0b57cec5SDimitry Andric BuildMI(*MBB, (*I), dl, TII->get(isISEL8(**I) ? PPC::OR8 : PPC::OR)) 235*0b57cec5SDimitry Andric .add(Dest) 236*0b57cec5SDimitry Andric .add(TrueValue) 237*0b57cec5SDimitry Andric .add(FalseValue); 238*0b57cec5SDimitry Andric (*I)->eraseFromParent(); 239*0b57cec5SDimitry Andric I++; 240*0b57cec5SDimitry Andric } else if (ExpandISELEnabled) { // Normal cases expansion enabled 241*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Expand ISEL instructions:\n"); 242*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n"); 243*0b57cec5SDimitry Andric BlockISELList SubISELList; 244*0b57cec5SDimitry Andric SubISELList.push_back(*I++); 245*0b57cec5SDimitry Andric // Collect the ISELs that can be merged together. 246*0b57cec5SDimitry Andric // This will eat up ISEL instructions without considering whether they 247*0b57cec5SDimitry Andric // may be redundant or foldable to a register copy. So we still keep 248*0b57cec5SDimitry Andric // the handleSpecialCases() downstream to handle them. 249*0b57cec5SDimitry Andric while (I != E && canMerge(SubISELList.back(), *I)) { 250*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n"); 251*0b57cec5SDimitry Andric SubISELList.push_back(*I++); 252*0b57cec5SDimitry Andric } 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric expandMergeableISELs(SubISELList); 255*0b57cec5SDimitry Andric } else { // Normal cases expansion disabled 256*0b57cec5SDimitry Andric I++; // leave the ISEL as it is 257*0b57cec5SDimitry Andric } 258*0b57cec5SDimitry Andric } // end while 259*0b57cec5SDimitry Andric } // end for 260*0b57cec5SDimitry Andric } 261*0b57cec5SDimitry Andric 262*0b57cec5SDimitry Andric void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL, 263*0b57cec5SDimitry Andric MachineBasicBlock *MBB) { 264*0b57cec5SDimitry Andric IsTrueBlockRequired = false; 265*0b57cec5SDimitry Andric IsFalseBlockRequired = false; 266*0b57cec5SDimitry Andric 267*0b57cec5SDimitry Andric auto MI = BIL.begin(); 268*0b57cec5SDimitry Andric while (MI != BIL.end()) { 269*0b57cec5SDimitry Andric assert(isISEL(**MI) && "Expecting an ISEL instruction"); 270*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **MI << "\n"); 271*0b57cec5SDimitry Andric 272*0b57cec5SDimitry Andric MachineOperand &Dest = (*MI)->getOperand(0); 273*0b57cec5SDimitry Andric MachineOperand &TrueValue = (*MI)->getOperand(1); 274*0b57cec5SDimitry Andric MachineOperand &FalseValue = (*MI)->getOperand(2); 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric // If at least one of the ISEL instructions satisfy the following 277*0b57cec5SDimitry Andric // condition, we need the True Block: 278*0b57cec5SDimitry Andric // The Dest Register and True Value Register are not the same 279*0b57cec5SDimitry Andric // Similarly, if at least one of the ISEL instructions satisfy the 280*0b57cec5SDimitry Andric // following condition, we need the False Block: 281*0b57cec5SDimitry Andric // The Dest Register and False Value Register are not the same. 282*0b57cec5SDimitry Andric bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue); 283*0b57cec5SDimitry Andric bool IsORIInstRequired = !useSameRegister(Dest, FalseValue); 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric // Special case 1, all registers used by ISEL are the same one. 286*0b57cec5SDimitry Andric if (!IsADDIInstRequired && !IsORIInstRequired) { 287*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction."); 288*0b57cec5SDimitry Andric // FIXME: if the CR field used has no other uses, we could eliminate the 289*0b57cec5SDimitry Andric // instruction that defines it. This would have to be done manually 290*0b57cec5SDimitry Andric // since this pass runs too late to run DCE after it. 291*0b57cec5SDimitry Andric NumRemoved++; 292*0b57cec5SDimitry Andric (*MI)->eraseFromParent(); 293*0b57cec5SDimitry Andric // Setting MI to the erase result keeps the iterator valid and increased. 294*0b57cec5SDimitry Andric MI = BIL.erase(MI); 295*0b57cec5SDimitry Andric continue; 296*0b57cec5SDimitry Andric } 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric // Special case 2, the two input registers used by ISEL are the same. 299*0b57cec5SDimitry Andric // Note 1: We favor merging ISEL expansions over folding a single one. If 300*0b57cec5SDimitry Andric // the passed list has multiple merge-able ISEL's, we won't fold any. 301*0b57cec5SDimitry Andric // Note 2: There is no need to test for PPC::R0/PPC::X0 because PPC::ZERO/ 302*0b57cec5SDimitry Andric // PPC::ZERO8 will be used for the first operand if the value is meant to 303*0b57cec5SDimitry Andric // be zero. In this case, the useSameRegister method will return false, 304*0b57cec5SDimitry Andric // thereby preventing this ISEL from being folded. 305*0b57cec5SDimitry Andric if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) { 306*0b57cec5SDimitry Andric LLVM_DEBUG( 307*0b57cec5SDimitry Andric dbgs() << "Fold the ISEL instruction to an unconditional copy."); 308*0b57cec5SDimitry Andric NumFolded++; 309*0b57cec5SDimitry Andric // Note: we're using both the TrueValue and FalseValue operands so as 310*0b57cec5SDimitry Andric // not to lose the kill flag if it is set on either of them. 311*0b57cec5SDimitry Andric BuildMI(*MBB, (*MI), dl, TII->get(isISEL8(**MI) ? PPC::OR8 : PPC::OR)) 312*0b57cec5SDimitry Andric .add(Dest) 313*0b57cec5SDimitry Andric .add(TrueValue) 314*0b57cec5SDimitry Andric .add(FalseValue); 315*0b57cec5SDimitry Andric (*MI)->eraseFromParent(); 316*0b57cec5SDimitry Andric // Setting MI to the erase result keeps the iterator valid and increased. 317*0b57cec5SDimitry Andric MI = BIL.erase(MI); 318*0b57cec5SDimitry Andric continue; 319*0b57cec5SDimitry Andric } 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric IsTrueBlockRequired |= IsADDIInstRequired; 322*0b57cec5SDimitry Andric IsFalseBlockRequired |= IsORIInstRequired; 323*0b57cec5SDimitry Andric MI++; 324*0b57cec5SDimitry Andric } 325*0b57cec5SDimitry Andric } 326*0b57cec5SDimitry Andric 327*0b57cec5SDimitry Andric void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL, 328*0b57cec5SDimitry Andric MachineBasicBlock *MBB) { 329*0b57cec5SDimitry Andric if (BIL.empty()) 330*0b57cec5SDimitry Andric return; 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andric assert((IsTrueBlockRequired || IsFalseBlockRequired) && 333*0b57cec5SDimitry Andric "Should have been handled by special cases earlier!"); 334*0b57cec5SDimitry Andric 335*0b57cec5SDimitry Andric MachineBasicBlock *Successor = nullptr; 336*0b57cec5SDimitry Andric const BasicBlock *LLVM_BB = MBB->getBasicBlock(); 337*0b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = (*BIL.back()); 338*0b57cec5SDimitry Andric NewSuccessor = (MBBI != MBB->getLastNonDebugInstr() || !MBB->canFallThrough()) 339*0b57cec5SDimitry Andric // Another BB is needed to move the instructions that 340*0b57cec5SDimitry Andric // follow this ISEL. If the ISEL is the last instruction 341*0b57cec5SDimitry Andric // in a block that can't fall through, we also need a block 342*0b57cec5SDimitry Andric // to branch to. 343*0b57cec5SDimitry Andric ? MF->CreateMachineBasicBlock(LLVM_BB) 344*0b57cec5SDimitry Andric : nullptr; 345*0b57cec5SDimitry Andric 346*0b57cec5SDimitry Andric MachineFunction::iterator It = MBB->getIterator(); 347*0b57cec5SDimitry Andric ++It; // Point to the successor block of MBB. 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andric // If NewSuccessor is NULL then the last ISEL in this group is the last 350*0b57cec5SDimitry Andric // non-debug instruction in this block. Find the fall-through successor 351*0b57cec5SDimitry Andric // of this block to use when updating the CFG below. 352*0b57cec5SDimitry Andric if (!NewSuccessor) { 353*0b57cec5SDimitry Andric for (auto &Succ : MBB->successors()) { 354*0b57cec5SDimitry Andric if (MBB->isLayoutSuccessor(Succ)) { 355*0b57cec5SDimitry Andric Successor = Succ; 356*0b57cec5SDimitry Andric break; 357*0b57cec5SDimitry Andric } 358*0b57cec5SDimitry Andric } 359*0b57cec5SDimitry Andric } else 360*0b57cec5SDimitry Andric Successor = NewSuccessor; 361*0b57cec5SDimitry Andric 362*0b57cec5SDimitry Andric // The FalseBlock and TrueBlock are inserted after the MBB block but before 363*0b57cec5SDimitry Andric // its successor. 364*0b57cec5SDimitry Andric // Note this need to be done *after* the above setting the Successor code. 365*0b57cec5SDimitry Andric if (IsFalseBlockRequired) { 366*0b57cec5SDimitry Andric FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB); 367*0b57cec5SDimitry Andric MF->insert(It, FalseBlock); 368*0b57cec5SDimitry Andric } 369*0b57cec5SDimitry Andric 370*0b57cec5SDimitry Andric if (IsTrueBlockRequired) { 371*0b57cec5SDimitry Andric TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB); 372*0b57cec5SDimitry Andric MF->insert(It, TrueBlock); 373*0b57cec5SDimitry Andric } 374*0b57cec5SDimitry Andric 375*0b57cec5SDimitry Andric if (NewSuccessor) { 376*0b57cec5SDimitry Andric MF->insert(It, NewSuccessor); 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric // Transfer the rest of this block into the new successor block. 379*0b57cec5SDimitry Andric NewSuccessor->splice(NewSuccessor->end(), MBB, 380*0b57cec5SDimitry Andric std::next(MachineBasicBlock::iterator(BIL.back())), 381*0b57cec5SDimitry Andric MBB->end()); 382*0b57cec5SDimitry Andric NewSuccessor->transferSuccessorsAndUpdatePHIs(MBB); 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric // Copy the original liveIns of MBB to NewSuccessor. 385*0b57cec5SDimitry Andric for (auto &LI : MBB->liveins()) 386*0b57cec5SDimitry Andric NewSuccessor->addLiveIn(LI); 387*0b57cec5SDimitry Andric 388*0b57cec5SDimitry Andric // After splitting the NewSuccessor block, Regs defined but not killed 389*0b57cec5SDimitry Andric // in MBB should be treated as liveins of NewSuccessor. 390*0b57cec5SDimitry Andric // Note: Cannot use stepBackward instead since we are using the Reg 391*0b57cec5SDimitry Andric // liveness state at the end of MBB (liveOut of MBB) as the liveIn for 392*0b57cec5SDimitry Andric // NewSuccessor. Otherwise, will cause cyclic dependence. 393*0b57cec5SDimitry Andric LivePhysRegs LPR(*MF->getSubtarget<PPCSubtarget>().getRegisterInfo()); 394*0b57cec5SDimitry Andric SmallVector<std::pair<MCPhysReg, const MachineOperand *>, 2> Clobbers; 395*0b57cec5SDimitry Andric for (MachineInstr &MI : *MBB) 396*0b57cec5SDimitry Andric LPR.stepForward(MI, Clobbers); 397*0b57cec5SDimitry Andric for (auto &LI : LPR) 398*0b57cec5SDimitry Andric NewSuccessor->addLiveIn(LI); 399*0b57cec5SDimitry Andric } else { 400*0b57cec5SDimitry Andric // Remove successor from MBB. 401*0b57cec5SDimitry Andric MBB->removeSuccessor(Successor); 402*0b57cec5SDimitry Andric } 403*0b57cec5SDimitry Andric 404*0b57cec5SDimitry Andric // Note that this needs to be done *after* transfering the successors from MBB 405*0b57cec5SDimitry Andric // to the NewSuccessor block, otherwise these blocks will also be transferred 406*0b57cec5SDimitry Andric // as successors! 407*0b57cec5SDimitry Andric MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor); 408*0b57cec5SDimitry Andric MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor); 409*0b57cec5SDimitry Andric 410*0b57cec5SDimitry Andric if (IsTrueBlockRequired) { 411*0b57cec5SDimitry Andric TrueBlockI = TrueBlock->begin(); 412*0b57cec5SDimitry Andric TrueBlock->addSuccessor(Successor); 413*0b57cec5SDimitry Andric } 414*0b57cec5SDimitry Andric 415*0b57cec5SDimitry Andric if (IsFalseBlockRequired) { 416*0b57cec5SDimitry Andric FalseBlockI = FalseBlock->begin(); 417*0b57cec5SDimitry Andric FalseBlock->addSuccessor(Successor); 418*0b57cec5SDimitry Andric } 419*0b57cec5SDimitry Andric 420*0b57cec5SDimitry Andric // Conditional branch to the TrueBlock or Successor 421*0b57cec5SDimitry Andric BuildMI(*MBB, BIL.back(), dl, TII->get(PPC::BC)) 422*0b57cec5SDimitry Andric .add(BIL.back()->getOperand(3)) 423*0b57cec5SDimitry Andric .addMBB(IsTrueBlockRequired ? TrueBlock : Successor); 424*0b57cec5SDimitry Andric 425*0b57cec5SDimitry Andric // Jump over the true block to the new successor if the condition is false. 426*0b57cec5SDimitry Andric BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB), 427*0b57cec5SDimitry Andric (IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl, 428*0b57cec5SDimitry Andric TII->get(PPC::B)) 429*0b57cec5SDimitry Andric .addMBB(Successor); 430*0b57cec5SDimitry Andric 431*0b57cec5SDimitry Andric if (IsFalseBlockRequired) 432*0b57cec5SDimitry Andric FalseBlockI = FalseBlock->begin(); // get the position of PPC::B 433*0b57cec5SDimitry Andric } 434*0b57cec5SDimitry Andric 435*0b57cec5SDimitry Andric void PPCExpandISEL::populateBlocks(BlockISELList &BIL) { 436*0b57cec5SDimitry Andric for (auto &MI : BIL) { 437*0b57cec5SDimitry Andric assert(isISEL(*MI) && "Expecting an ISEL instruction"); 438*0b57cec5SDimitry Andric 439*0b57cec5SDimitry Andric MachineOperand &Dest = MI->getOperand(0); // location to store to 440*0b57cec5SDimitry Andric MachineOperand &TrueValue = MI->getOperand(1); // Value to store if 441*0b57cec5SDimitry Andric // condition is true 442*0b57cec5SDimitry Andric MachineOperand &FalseValue = MI->getOperand(2); // Value to store if 443*0b57cec5SDimitry Andric // condition is false 444*0b57cec5SDimitry Andric MachineOperand &ConditionRegister = MI->getOperand(3); // Condition 445*0b57cec5SDimitry Andric 446*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Dest: " << Dest << "\n"); 447*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "TrueValue: " << TrueValue << "\n"); 448*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "FalseValue: " << FalseValue << "\n"); 449*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ConditionRegister: " << ConditionRegister << "\n"); 450*0b57cec5SDimitry Andric 451*0b57cec5SDimitry Andric // If the Dest Register and True Value Register are not the same one, we 452*0b57cec5SDimitry Andric // need the True Block. 453*0b57cec5SDimitry Andric bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue); 454*0b57cec5SDimitry Andric bool IsORIInstRequired = !useSameRegister(Dest, FalseValue); 455*0b57cec5SDimitry Andric 456*0b57cec5SDimitry Andric if (IsADDIInstRequired) { 457*0b57cec5SDimitry Andric // Copy the result into the destination if the condition is true. 458*0b57cec5SDimitry Andric BuildMI(*TrueBlock, TrueBlockI, dl, 459*0b57cec5SDimitry Andric TII->get(isISEL8(*MI) ? PPC::ADDI8 : PPC::ADDI)) 460*0b57cec5SDimitry Andric .add(Dest) 461*0b57cec5SDimitry Andric .add(TrueValue) 462*0b57cec5SDimitry Andric .add(MachineOperand::CreateImm(0)); 463*0b57cec5SDimitry Andric 464*0b57cec5SDimitry Andric // Add the LiveIn registers required by true block. 465*0b57cec5SDimitry Andric TrueBlock->addLiveIn(TrueValue.getReg()); 466*0b57cec5SDimitry Andric } 467*0b57cec5SDimitry Andric 468*0b57cec5SDimitry Andric if (IsORIInstRequired) { 469*0b57cec5SDimitry Andric // Add the LiveIn registers required by false block. 470*0b57cec5SDimitry Andric FalseBlock->addLiveIn(FalseValue.getReg()); 471*0b57cec5SDimitry Andric } 472*0b57cec5SDimitry Andric 473*0b57cec5SDimitry Andric if (NewSuccessor) { 474*0b57cec5SDimitry Andric // Add the LiveIn registers required by NewSuccessor block. 475*0b57cec5SDimitry Andric NewSuccessor->addLiveIn(Dest.getReg()); 476*0b57cec5SDimitry Andric NewSuccessor->addLiveIn(TrueValue.getReg()); 477*0b57cec5SDimitry Andric NewSuccessor->addLiveIn(FalseValue.getReg()); 478*0b57cec5SDimitry Andric NewSuccessor->addLiveIn(ConditionRegister.getReg()); 479*0b57cec5SDimitry Andric } 480*0b57cec5SDimitry Andric 481*0b57cec5SDimitry Andric // Copy the value into the destination if the condition is false. 482*0b57cec5SDimitry Andric if (IsORIInstRequired) 483*0b57cec5SDimitry Andric BuildMI(*FalseBlock, FalseBlockI, dl, 484*0b57cec5SDimitry Andric TII->get(isISEL8(*MI) ? PPC::ORI8 : PPC::ORI)) 485*0b57cec5SDimitry Andric .add(Dest) 486*0b57cec5SDimitry Andric .add(FalseValue) 487*0b57cec5SDimitry Andric .add(MachineOperand::CreateImm(0)); 488*0b57cec5SDimitry Andric 489*0b57cec5SDimitry Andric MI->eraseFromParent(); // Remove the ISEL instruction. 490*0b57cec5SDimitry Andric 491*0b57cec5SDimitry Andric NumExpanded++; 492*0b57cec5SDimitry Andric } 493*0b57cec5SDimitry Andric } 494*0b57cec5SDimitry Andric 495*0b57cec5SDimitry Andric void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) { 496*0b57cec5SDimitry Andric // At this stage all the ISELs of BIL are in the same MBB. 497*0b57cec5SDimitry Andric MachineBasicBlock *MBB = BIL.back()->getParent(); 498*0b57cec5SDimitry Andric 499*0b57cec5SDimitry Andric handleSpecialCases(BIL, MBB); 500*0b57cec5SDimitry Andric reorganizeBlockLayout(BIL, MBB); 501*0b57cec5SDimitry Andric populateBlocks(BIL); 502*0b57cec5SDimitry Andric } 503*0b57cec5SDimitry Andric 504*0b57cec5SDimitry Andric INITIALIZE_PASS(PPCExpandISEL, DEBUG_TYPE, "PowerPC Expand ISEL Generation", 505*0b57cec5SDimitry Andric false, false) 506*0b57cec5SDimitry Andric char PPCExpandISEL::ID = 0; 507*0b57cec5SDimitry Andric 508*0b57cec5SDimitry Andric FunctionPass *llvm::createPPCExpandISELPass() { return new PPCExpandISEL(); } 509