10b57cec5SDimitry Andric //===------------- PPCExpandISEL.cpp - Expand ISEL instruction ------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // A pass that expands the ISEL instruction into an if-then-else sequence. 100b57cec5SDimitry Andric // This pass must be run post-RA since all operands must be physical registers. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "PPC.h" 150b57cec5SDimitry Andric #include "PPCInstrInfo.h" 160b57cec5SDimitry Andric #include "PPCSubtarget.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 180b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 190b57cec5SDimitry Andric #include "llvm/CodeGen/LivePhysRegs.h" 200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 230b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 240b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric #define DEBUG_TYPE "ppc-expand-isel" 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric STATISTIC(NumExpanded, "Number of ISEL instructions expanded"); 320b57cec5SDimitry Andric STATISTIC(NumRemoved, "Number of ISEL instructions removed"); 330b57cec5SDimitry Andric STATISTIC(NumFolded, "Number of ISEL instructions folded"); 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric // If -ppc-gen-isel=false is set, we will disable generating the ISEL 360b57cec5SDimitry Andric // instruction on all PPC targets. Otherwise, if the user set option 370b57cec5SDimitry Andric // -misel or the platform supports ISEL by default, still generate the 380b57cec5SDimitry Andric // ISEL instruction, else expand it. 390b57cec5SDimitry Andric static cl::opt<bool> 400b57cec5SDimitry Andric GenerateISEL("ppc-gen-isel", 410b57cec5SDimitry Andric cl::desc("Enable generating the ISEL instruction."), 420b57cec5SDimitry Andric cl::init(true), cl::Hidden); 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric namespace { 450b57cec5SDimitry Andric class PPCExpandISEL : public MachineFunctionPass { 460b57cec5SDimitry Andric DebugLoc dl; 470b57cec5SDimitry Andric MachineFunction *MF; 480b57cec5SDimitry Andric const TargetInstrInfo *TII; 490b57cec5SDimitry Andric bool IsTrueBlockRequired; 500b57cec5SDimitry Andric bool IsFalseBlockRequired; 510b57cec5SDimitry Andric MachineBasicBlock *TrueBlock; 520b57cec5SDimitry Andric MachineBasicBlock *FalseBlock; 530b57cec5SDimitry Andric MachineBasicBlock *NewSuccessor; 540b57cec5SDimitry Andric MachineBasicBlock::iterator TrueBlockI; 550b57cec5SDimitry Andric MachineBasicBlock::iterator FalseBlockI; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric typedef SmallVector<MachineInstr *, 4> BlockISELList; 580b57cec5SDimitry Andric typedef SmallDenseMap<int, BlockISELList> ISELInstructionList; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // A map of MBB numbers to their lists of contained ISEL instructions. 610b57cec5SDimitry Andric // Please note when we traverse this list and expand ISEL, we only remove 620b57cec5SDimitry Andric // the ISEL from the MBB not from this list. 630b57cec5SDimitry Andric ISELInstructionList ISELInstructions; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric /// Initialize the object. 660b57cec5SDimitry Andric void initialize(MachineFunction &MFParam); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric void handleSpecialCases(BlockISELList &BIL, MachineBasicBlock *MBB); 690b57cec5SDimitry Andric void reorganizeBlockLayout(BlockISELList &BIL, MachineBasicBlock *MBB); 700b57cec5SDimitry Andric void populateBlocks(BlockISELList &BIL); 710b57cec5SDimitry Andric void expandMergeableISELs(BlockISELList &BIL); 720b57cec5SDimitry Andric void expandAndMergeISELs(); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric bool canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI); 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric /// Is this instruction an ISEL or ISEL8? 770b57cec5SDimitry Andric static bool isISEL(const MachineInstr &MI) { 780b57cec5SDimitry Andric return (MI.getOpcode() == PPC::ISEL || MI.getOpcode() == PPC::ISEL8); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// Is this instruction an ISEL8? 820b57cec5SDimitry Andric static bool isISEL8(const MachineInstr &MI) { 830b57cec5SDimitry Andric return (MI.getOpcode() == PPC::ISEL8); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric /// Are the two operands using the same register? 870b57cec5SDimitry Andric bool useSameRegister(const MachineOperand &Op1, const MachineOperand &Op2) { 880b57cec5SDimitry Andric return (Op1.getReg() == Op2.getReg()); 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric /// 920b57cec5SDimitry Andric /// Collect all ISEL instructions from the current function. 930b57cec5SDimitry Andric /// 940b57cec5SDimitry Andric /// Walk the current function and collect all the ISEL instructions that are 950b57cec5SDimitry Andric /// found. The instructions are placed in the ISELInstructions vector. 960b57cec5SDimitry Andric /// 970b57cec5SDimitry Andric /// \return true if any ISEL instructions were found, false otherwise 980b57cec5SDimitry Andric /// 990b57cec5SDimitry Andric bool collectISELInstructions(); 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric public: 1020b57cec5SDimitry Andric static char ID; 1030b57cec5SDimitry Andric PPCExpandISEL() : MachineFunctionPass(ID) { 1040b57cec5SDimitry Andric initializePPCExpandISELPass(*PassRegistry::getPassRegistry()); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric /// 1080b57cec5SDimitry Andric /// Determine whether to generate the ISEL instruction or expand it. 1090b57cec5SDimitry Andric /// 1100b57cec5SDimitry Andric /// Expand ISEL instruction into if-then-else sequence when one of 1110b57cec5SDimitry Andric /// the following two conditions hold: 1120b57cec5SDimitry Andric /// (1) -ppc-gen-isel=false 1130b57cec5SDimitry Andric /// (2) hasISEL() return false 1140b57cec5SDimitry Andric /// Otherwise, still generate ISEL instruction. 1150b57cec5SDimitry Andric /// The -ppc-gen-isel option is set to true by default. Which means the ISEL 1160b57cec5SDimitry Andric /// instruction is still generated by default on targets that support them. 1170b57cec5SDimitry Andric /// 1180b57cec5SDimitry Andric /// \return true if ISEL should be expanded into if-then-else code sequence; 1190b57cec5SDimitry Andric /// false if ISEL instruction should be generated, i.e. not expanded. 1200b57cec5SDimitry Andric /// 1210b57cec5SDimitry Andric static bool isExpandISELEnabled(const MachineFunction &MF); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric #ifndef NDEBUG 1240b57cec5SDimitry Andric void DumpISELInstructions() const; 1250b57cec5SDimitry Andric #endif 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override { 1280b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n"); 1290b57cec5SDimitry Andric initialize(MF); 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric if (!collectISELInstructions()) { 1320b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "No ISEL instructions in this function\n"); 1330b57cec5SDimitry Andric return false; 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric #ifndef NDEBUG 1370b57cec5SDimitry Andric DumpISELInstructions(); 1380b57cec5SDimitry Andric #endif 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric expandAndMergeISELs(); 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric return true; 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric }; 1450b57cec5SDimitry Andric } // end anonymous namespace 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric void PPCExpandISEL::initialize(MachineFunction &MFParam) { 1480b57cec5SDimitry Andric MF = &MFParam; 1490b57cec5SDimitry Andric TII = MF->getSubtarget().getInstrInfo(); 1500b57cec5SDimitry Andric ISELInstructions.clear(); 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric bool PPCExpandISEL::isExpandISELEnabled(const MachineFunction &MF) { 1540b57cec5SDimitry Andric return !GenerateISEL || !MF.getSubtarget<PPCSubtarget>().hasISEL(); 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric bool PPCExpandISEL::collectISELInstructions() { 1580b57cec5SDimitry Andric for (MachineBasicBlock &MBB : *MF) { 1590b57cec5SDimitry Andric BlockISELList thisBlockISELs; 1600b57cec5SDimitry Andric for (MachineInstr &MI : MBB) 1610b57cec5SDimitry Andric if (isISEL(MI)) 1620b57cec5SDimitry Andric thisBlockISELs.push_back(&MI); 1630b57cec5SDimitry Andric if (!thisBlockISELs.empty()) 1640b57cec5SDimitry Andric ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs)); 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric return !ISELInstructions.empty(); 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric #ifndef NDEBUG 1700b57cec5SDimitry Andric void PPCExpandISEL::DumpISELInstructions() const { 1710b57cec5SDimitry Andric for (const auto &I : ISELInstructions) { 1720b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << printMBBReference(*MF->getBlockNumbered(I.first)) 1730b57cec5SDimitry Andric << ":\n"); 1740b57cec5SDimitry Andric for (const auto &VI : I.second) 1750b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << " "; VI->print(dbgs())); 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric #endif 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// Contiguous ISELs that have the same condition can be merged. 1810b57cec5SDimitry Andric bool PPCExpandISEL::canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI) { 1820b57cec5SDimitry Andric // Same Condition Register? 1830b57cec5SDimitry Andric if (!useSameRegister(PrevPushedMI->getOperand(3), MI->getOperand(3))) 1840b57cec5SDimitry Andric return false; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric MachineBasicBlock::iterator PrevPushedMBBI = *PrevPushedMI; 1870b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = *MI; 1880b57cec5SDimitry Andric return (std::prev(MBBI) == PrevPushedMBBI); // Contiguous ISELs? 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric void PPCExpandISEL::expandAndMergeISELs() { 1920b57cec5SDimitry Andric bool ExpandISELEnabled = isExpandISELEnabled(*MF); 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric for (auto &BlockList : ISELInstructions) { 1950b57cec5SDimitry Andric LLVM_DEBUG( 1960b57cec5SDimitry Andric dbgs() << "Expanding ISEL instructions in " 1970b57cec5SDimitry Andric << printMBBReference(*MF->getBlockNumbered(BlockList.first)) 1980b57cec5SDimitry Andric << "\n"); 1990b57cec5SDimitry Andric BlockISELList &CurrentISELList = BlockList.second; 2000b57cec5SDimitry Andric auto I = CurrentISELList.begin(); 2010b57cec5SDimitry Andric auto E = CurrentISELList.end(); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric while (I != E) { 2040b57cec5SDimitry Andric assert(isISEL(**I) && "Expecting an ISEL instruction"); 2050b57cec5SDimitry Andric MachineOperand &Dest = (*I)->getOperand(0); 2060b57cec5SDimitry Andric MachineOperand &TrueValue = (*I)->getOperand(1); 2070b57cec5SDimitry Andric MachineOperand &FalseValue = (*I)->getOperand(2); 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric // Special case 1, all registers used by ISEL are the same one. 2100b57cec5SDimitry Andric // The non-redundant isel 0, 0, 0, N would not satisfy these conditions 2110b57cec5SDimitry Andric // as it would be ISEL %R0, %ZERO, %R0, %CRN. 2120b57cec5SDimitry Andric if (useSameRegister(Dest, TrueValue) && 2130b57cec5SDimitry Andric useSameRegister(Dest, FalseValue)) { 2140b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction: " << **I 2150b57cec5SDimitry Andric << "\n"); 2160b57cec5SDimitry Andric // FIXME: if the CR field used has no other uses, we could eliminate the 2170b57cec5SDimitry Andric // instruction that defines it. This would have to be done manually 2180b57cec5SDimitry Andric // since this pass runs too late to run DCE after it. 2190b57cec5SDimitry Andric NumRemoved++; 2200b57cec5SDimitry Andric (*I)->eraseFromParent(); 2210b57cec5SDimitry Andric I++; 2220b57cec5SDimitry Andric } else if (useSameRegister(TrueValue, FalseValue)) { 2230b57cec5SDimitry Andric // Special case 2, the two input registers used by ISEL are the same. 2240b57cec5SDimitry Andric // Note: the non-foldable isel RX, 0, 0, N would not satisfy this 2250b57cec5SDimitry Andric // condition as it would be ISEL %RX, %ZERO, %R0, %CRN, which makes it 2260b57cec5SDimitry Andric // safe to fold ISEL to MR(OR) instead of ADDI. 2270b57cec5SDimitry Andric MachineBasicBlock *MBB = (*I)->getParent(); 2280b57cec5SDimitry Andric LLVM_DEBUG( 2290b57cec5SDimitry Andric dbgs() << "Fold the ISEL instruction to an unconditional copy:\n"); 2300b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n"); 2310b57cec5SDimitry Andric NumFolded++; 2320b57cec5SDimitry Andric // Note: we're using both the TrueValue and FalseValue operands so as 2330b57cec5SDimitry Andric // not to lose the kill flag if it is set on either of them. 2340b57cec5SDimitry Andric BuildMI(*MBB, (*I), dl, TII->get(isISEL8(**I) ? PPC::OR8 : PPC::OR)) 2350b57cec5SDimitry Andric .add(Dest) 2360b57cec5SDimitry Andric .add(TrueValue) 2370b57cec5SDimitry Andric .add(FalseValue); 2380b57cec5SDimitry Andric (*I)->eraseFromParent(); 2390b57cec5SDimitry Andric I++; 2400b57cec5SDimitry Andric } else if (ExpandISELEnabled) { // Normal cases expansion enabled 2410b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Expand ISEL instructions:\n"); 2420b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n"); 2430b57cec5SDimitry Andric BlockISELList SubISELList; 2440b57cec5SDimitry Andric SubISELList.push_back(*I++); 2450b57cec5SDimitry Andric // Collect the ISELs that can be merged together. 2460b57cec5SDimitry Andric // This will eat up ISEL instructions without considering whether they 2470b57cec5SDimitry Andric // may be redundant or foldable to a register copy. So we still keep 2480b57cec5SDimitry Andric // the handleSpecialCases() downstream to handle them. 2490b57cec5SDimitry Andric while (I != E && canMerge(SubISELList.back(), *I)) { 2500b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n"); 2510b57cec5SDimitry Andric SubISELList.push_back(*I++); 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric expandMergeableISELs(SubISELList); 2550b57cec5SDimitry Andric } else { // Normal cases expansion disabled 2560b57cec5SDimitry Andric I++; // leave the ISEL as it is 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric } // end while 2590b57cec5SDimitry Andric } // end for 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL, 2630b57cec5SDimitry Andric MachineBasicBlock *MBB) { 2640b57cec5SDimitry Andric IsTrueBlockRequired = false; 2650b57cec5SDimitry Andric IsFalseBlockRequired = false; 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric auto MI = BIL.begin(); 2680b57cec5SDimitry Andric while (MI != BIL.end()) { 2690b57cec5SDimitry Andric assert(isISEL(**MI) && "Expecting an ISEL instruction"); 2700b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "ISEL: " << **MI << "\n"); 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric MachineOperand &Dest = (*MI)->getOperand(0); 2730b57cec5SDimitry Andric MachineOperand &TrueValue = (*MI)->getOperand(1); 2740b57cec5SDimitry Andric MachineOperand &FalseValue = (*MI)->getOperand(2); 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric // If at least one of the ISEL instructions satisfy the following 2770b57cec5SDimitry Andric // condition, we need the True Block: 2780b57cec5SDimitry Andric // The Dest Register and True Value Register are not the same 2790b57cec5SDimitry Andric // Similarly, if at least one of the ISEL instructions satisfy the 2800b57cec5SDimitry Andric // following condition, we need the False Block: 2810b57cec5SDimitry Andric // The Dest Register and False Value Register are not the same. 2820b57cec5SDimitry Andric bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue); 2830b57cec5SDimitry Andric bool IsORIInstRequired = !useSameRegister(Dest, FalseValue); 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric // Special case 1, all registers used by ISEL are the same one. 2860b57cec5SDimitry Andric if (!IsADDIInstRequired && !IsORIInstRequired) { 2870b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction."); 2880b57cec5SDimitry Andric // FIXME: if the CR field used has no other uses, we could eliminate the 2890b57cec5SDimitry Andric // instruction that defines it. This would have to be done manually 2900b57cec5SDimitry Andric // since this pass runs too late to run DCE after it. 2910b57cec5SDimitry Andric NumRemoved++; 2920b57cec5SDimitry Andric (*MI)->eraseFromParent(); 2930b57cec5SDimitry Andric // Setting MI to the erase result keeps the iterator valid and increased. 2940b57cec5SDimitry Andric MI = BIL.erase(MI); 2950b57cec5SDimitry Andric continue; 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric // Special case 2, the two input registers used by ISEL are the same. 2990b57cec5SDimitry Andric // Note 1: We favor merging ISEL expansions over folding a single one. If 3000b57cec5SDimitry Andric // the passed list has multiple merge-able ISEL's, we won't fold any. 3010b57cec5SDimitry Andric // Note 2: There is no need to test for PPC::R0/PPC::X0 because PPC::ZERO/ 3020b57cec5SDimitry Andric // PPC::ZERO8 will be used for the first operand if the value is meant to 3030b57cec5SDimitry Andric // be zero. In this case, the useSameRegister method will return false, 3040b57cec5SDimitry Andric // thereby preventing this ISEL from being folded. 3050b57cec5SDimitry Andric if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) { 3060b57cec5SDimitry Andric LLVM_DEBUG( 3070b57cec5SDimitry Andric dbgs() << "Fold the ISEL instruction to an unconditional copy."); 3080b57cec5SDimitry Andric NumFolded++; 3090b57cec5SDimitry Andric // Note: we're using both the TrueValue and FalseValue operands so as 3100b57cec5SDimitry Andric // not to lose the kill flag if it is set on either of them. 3110b57cec5SDimitry Andric BuildMI(*MBB, (*MI), dl, TII->get(isISEL8(**MI) ? PPC::OR8 : PPC::OR)) 3120b57cec5SDimitry Andric .add(Dest) 3130b57cec5SDimitry Andric .add(TrueValue) 3140b57cec5SDimitry Andric .add(FalseValue); 3150b57cec5SDimitry Andric (*MI)->eraseFromParent(); 3160b57cec5SDimitry Andric // Setting MI to the erase result keeps the iterator valid and increased. 3170b57cec5SDimitry Andric MI = BIL.erase(MI); 3180b57cec5SDimitry Andric continue; 3190b57cec5SDimitry Andric } 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric IsTrueBlockRequired |= IsADDIInstRequired; 3220b57cec5SDimitry Andric IsFalseBlockRequired |= IsORIInstRequired; 3230b57cec5SDimitry Andric MI++; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL, 3280b57cec5SDimitry Andric MachineBasicBlock *MBB) { 3290b57cec5SDimitry Andric if (BIL.empty()) 3300b57cec5SDimitry Andric return; 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric assert((IsTrueBlockRequired || IsFalseBlockRequired) && 3330b57cec5SDimitry Andric "Should have been handled by special cases earlier!"); 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric MachineBasicBlock *Successor = nullptr; 3360b57cec5SDimitry Andric const BasicBlock *LLVM_BB = MBB->getBasicBlock(); 3370b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = (*BIL.back()); 3380b57cec5SDimitry Andric NewSuccessor = (MBBI != MBB->getLastNonDebugInstr() || !MBB->canFallThrough()) 3390b57cec5SDimitry Andric // Another BB is needed to move the instructions that 3400b57cec5SDimitry Andric // follow this ISEL. If the ISEL is the last instruction 3410b57cec5SDimitry Andric // in a block that can't fall through, we also need a block 3420b57cec5SDimitry Andric // to branch to. 3430b57cec5SDimitry Andric ? MF->CreateMachineBasicBlock(LLVM_BB) 3440b57cec5SDimitry Andric : nullptr; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric MachineFunction::iterator It = MBB->getIterator(); 3470b57cec5SDimitry Andric ++It; // Point to the successor block of MBB. 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric // If NewSuccessor is NULL then the last ISEL in this group is the last 3500b57cec5SDimitry Andric // non-debug instruction in this block. Find the fall-through successor 3510b57cec5SDimitry Andric // of this block to use when updating the CFG below. 3520b57cec5SDimitry Andric if (!NewSuccessor) { 3530b57cec5SDimitry Andric for (auto &Succ : MBB->successors()) { 3540b57cec5SDimitry Andric if (MBB->isLayoutSuccessor(Succ)) { 3550b57cec5SDimitry Andric Successor = Succ; 3560b57cec5SDimitry Andric break; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric } else 3600b57cec5SDimitry Andric Successor = NewSuccessor; 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric // The FalseBlock and TrueBlock are inserted after the MBB block but before 3630b57cec5SDimitry Andric // its successor. 3640b57cec5SDimitry Andric // Note this need to be done *after* the above setting the Successor code. 3650b57cec5SDimitry Andric if (IsFalseBlockRequired) { 3660b57cec5SDimitry Andric FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB); 3670b57cec5SDimitry Andric MF->insert(It, FalseBlock); 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric if (IsTrueBlockRequired) { 3710b57cec5SDimitry Andric TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB); 3720b57cec5SDimitry Andric MF->insert(It, TrueBlock); 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric if (NewSuccessor) { 3760b57cec5SDimitry Andric MF->insert(It, NewSuccessor); 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric // Transfer the rest of this block into the new successor block. 3790b57cec5SDimitry Andric NewSuccessor->splice(NewSuccessor->end(), MBB, 3800b57cec5SDimitry Andric std::next(MachineBasicBlock::iterator(BIL.back())), 3810b57cec5SDimitry Andric MBB->end()); 3820b57cec5SDimitry Andric NewSuccessor->transferSuccessorsAndUpdatePHIs(MBB); 3830b57cec5SDimitry Andric 384*5ffd83dbSDimitry Andric // Update the liveins for NewSuccessor. 385*5ffd83dbSDimitry Andric LivePhysRegs LPR; 386*5ffd83dbSDimitry Andric computeAndAddLiveIns(LPR, *NewSuccessor); 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric } else { 3890b57cec5SDimitry Andric // Remove successor from MBB. 3900b57cec5SDimitry Andric MBB->removeSuccessor(Successor); 3910b57cec5SDimitry Andric } 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric // Note that this needs to be done *after* transfering the successors from MBB 3940b57cec5SDimitry Andric // to the NewSuccessor block, otherwise these blocks will also be transferred 3950b57cec5SDimitry Andric // as successors! 3960b57cec5SDimitry Andric MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor); 3970b57cec5SDimitry Andric MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor); 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric if (IsTrueBlockRequired) { 4000b57cec5SDimitry Andric TrueBlockI = TrueBlock->begin(); 4010b57cec5SDimitry Andric TrueBlock->addSuccessor(Successor); 4020b57cec5SDimitry Andric } 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric if (IsFalseBlockRequired) { 4050b57cec5SDimitry Andric FalseBlockI = FalseBlock->begin(); 4060b57cec5SDimitry Andric FalseBlock->addSuccessor(Successor); 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric // Conditional branch to the TrueBlock or Successor 4100b57cec5SDimitry Andric BuildMI(*MBB, BIL.back(), dl, TII->get(PPC::BC)) 4110b57cec5SDimitry Andric .add(BIL.back()->getOperand(3)) 4120b57cec5SDimitry Andric .addMBB(IsTrueBlockRequired ? TrueBlock : Successor); 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric // Jump over the true block to the new successor if the condition is false. 4150b57cec5SDimitry Andric BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB), 4160b57cec5SDimitry Andric (IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl, 4170b57cec5SDimitry Andric TII->get(PPC::B)) 4180b57cec5SDimitry Andric .addMBB(Successor); 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric if (IsFalseBlockRequired) 4210b57cec5SDimitry Andric FalseBlockI = FalseBlock->begin(); // get the position of PPC::B 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric void PPCExpandISEL::populateBlocks(BlockISELList &BIL) { 4250b57cec5SDimitry Andric for (auto &MI : BIL) { 4260b57cec5SDimitry Andric assert(isISEL(*MI) && "Expecting an ISEL instruction"); 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric MachineOperand &Dest = MI->getOperand(0); // location to store to 4290b57cec5SDimitry Andric MachineOperand &TrueValue = MI->getOperand(1); // Value to store if 4300b57cec5SDimitry Andric // condition is true 4310b57cec5SDimitry Andric MachineOperand &FalseValue = MI->getOperand(2); // Value to store if 4320b57cec5SDimitry Andric // condition is false 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Dest: " << Dest << "\n"); 4350b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "TrueValue: " << TrueValue << "\n"); 4360b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "FalseValue: " << FalseValue << "\n"); 437*5ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "ConditionRegister: " << MI->getOperand(3) << "\n"); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric // If the Dest Register and True Value Register are not the same one, we 4400b57cec5SDimitry Andric // need the True Block. 4410b57cec5SDimitry Andric bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue); 4420b57cec5SDimitry Andric bool IsORIInstRequired = !useSameRegister(Dest, FalseValue); 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric // Copy the result into the destination if the condition is true. 445*5ffd83dbSDimitry Andric if (IsADDIInstRequired) 4460b57cec5SDimitry Andric BuildMI(*TrueBlock, TrueBlockI, dl, 4470b57cec5SDimitry Andric TII->get(isISEL8(*MI) ? PPC::ADDI8 : PPC::ADDI)) 4480b57cec5SDimitry Andric .add(Dest) 4490b57cec5SDimitry Andric .add(TrueValue) 4500b57cec5SDimitry Andric .add(MachineOperand::CreateImm(0)); 4510b57cec5SDimitry Andric 452*5ffd83dbSDimitry Andric // Copy the result into the destination if the condition is false. 4530b57cec5SDimitry Andric if (IsORIInstRequired) 4540b57cec5SDimitry Andric BuildMI(*FalseBlock, FalseBlockI, dl, 4550b57cec5SDimitry Andric TII->get(isISEL8(*MI) ? PPC::ORI8 : PPC::ORI)) 4560b57cec5SDimitry Andric .add(Dest) 4570b57cec5SDimitry Andric .add(FalseValue) 4580b57cec5SDimitry Andric .add(MachineOperand::CreateImm(0)); 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric MI->eraseFromParent(); // Remove the ISEL instruction. 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric NumExpanded++; 4630b57cec5SDimitry Andric } 464*5ffd83dbSDimitry Andric 465*5ffd83dbSDimitry Andric if (IsTrueBlockRequired) { 466*5ffd83dbSDimitry Andric // Update the liveins for TrueBlock. 467*5ffd83dbSDimitry Andric LivePhysRegs LPR; 468*5ffd83dbSDimitry Andric computeAndAddLiveIns(LPR, *TrueBlock); 469*5ffd83dbSDimitry Andric } 470*5ffd83dbSDimitry Andric 471*5ffd83dbSDimitry Andric if (IsFalseBlockRequired) { 472*5ffd83dbSDimitry Andric // Update the liveins for FalseBlock. 473*5ffd83dbSDimitry Andric LivePhysRegs LPR; 474*5ffd83dbSDimitry Andric computeAndAddLiveIns(LPR, *FalseBlock); 475*5ffd83dbSDimitry Andric } 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) { 4790b57cec5SDimitry Andric // At this stage all the ISELs of BIL are in the same MBB. 4800b57cec5SDimitry Andric MachineBasicBlock *MBB = BIL.back()->getParent(); 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric handleSpecialCases(BIL, MBB); 4830b57cec5SDimitry Andric reorganizeBlockLayout(BIL, MBB); 4840b57cec5SDimitry Andric populateBlocks(BIL); 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric INITIALIZE_PASS(PPCExpandISEL, DEBUG_TYPE, "PowerPC Expand ISEL Generation", 4880b57cec5SDimitry Andric false, false) 4890b57cec5SDimitry Andric char PPCExpandISEL::ID = 0; 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric FunctionPass *llvm::createPPCExpandISELPass() { return new PPCExpandISEL(); } 492