18e8c444dSTony Jiang //===------------- PPCExpandISEL.cpp - Expand ISEL instruction ------------===//
28e8c444dSTony Jiang //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68e8c444dSTony Jiang //
78e8c444dSTony Jiang //===----------------------------------------------------------------------===//
88e8c444dSTony Jiang //
98e8c444dSTony Jiang // A pass that expands the ISEL instruction into an if-then-else sequence.
108e8c444dSTony Jiang // This pass must be run post-RA since all operands must be physical registers.
118e8c444dSTony Jiang //
128e8c444dSTony Jiang //===----------------------------------------------------------------------===//
138e8c444dSTony Jiang
148e8c444dSTony Jiang #include "PPC.h"
158e8c444dSTony Jiang #include "PPCInstrInfo.h"
168e8c444dSTony Jiang #include "PPCSubtarget.h"
178e8c444dSTony Jiang #include "llvm/ADT/DenseMap.h"
188e8c444dSTony Jiang #include "llvm/ADT/Statistic.h"
198e8c444dSTony Jiang #include "llvm/CodeGen/LivePhysRegs.h"
208e8c444dSTony Jiang #include "llvm/CodeGen/MachineFunctionPass.h"
218e8c444dSTony Jiang #include "llvm/CodeGen/MachineInstrBuilder.h"
228e8c444dSTony Jiang #include "llvm/CodeGen/MachineRegisterInfo.h"
238e8c444dSTony Jiang #include "llvm/Support/CommandLine.h"
248e8c444dSTony Jiang #include "llvm/Support/Debug.h"
258e8c444dSTony Jiang #include "llvm/Support/raw_ostream.h"
268e8c444dSTony Jiang
278e8c444dSTony Jiang using namespace llvm;
288e8c444dSTony Jiang
298e8c444dSTony Jiang #define DEBUG_TYPE "ppc-expand-isel"
308e8c444dSTony Jiang
318e8c444dSTony Jiang STATISTIC(NumExpanded, "Number of ISEL instructions expanded");
328e8c444dSTony Jiang STATISTIC(NumRemoved, "Number of ISEL instructions removed");
338e8c444dSTony Jiang STATISTIC(NumFolded, "Number of ISEL instructions folded");
348e8c444dSTony Jiang
358e8c444dSTony Jiang // If -ppc-gen-isel=false is set, we will disable generating the ISEL
368e8c444dSTony Jiang // instruction on all PPC targets. Otherwise, if the user set option
378e8c444dSTony Jiang // -misel or the platform supports ISEL by default, still generate the
388e8c444dSTony Jiang // ISEL instruction, else expand it.
398e8c444dSTony Jiang static cl::opt<bool>
408e8c444dSTony Jiang GenerateISEL("ppc-gen-isel",
418e8c444dSTony Jiang cl::desc("Enable generating the ISEL instruction."),
428e8c444dSTony Jiang cl::init(true), cl::Hidden);
438e8c444dSTony Jiang
44efcf06f5SBenjamin Kramer namespace {
458e8c444dSTony Jiang class PPCExpandISEL : public MachineFunctionPass {
468e8c444dSTony Jiang DebugLoc dl;
478e8c444dSTony Jiang MachineFunction *MF;
488e8c444dSTony Jiang const TargetInstrInfo *TII;
498e8c444dSTony Jiang bool IsTrueBlockRequired;
508e8c444dSTony Jiang bool IsFalseBlockRequired;
518e8c444dSTony Jiang MachineBasicBlock *TrueBlock;
528e8c444dSTony Jiang MachineBasicBlock *FalseBlock;
538e8c444dSTony Jiang MachineBasicBlock *NewSuccessor;
548e8c444dSTony Jiang MachineBasicBlock::iterator TrueBlockI;
558e8c444dSTony Jiang MachineBasicBlock::iterator FalseBlockI;
568e8c444dSTony Jiang
578e8c444dSTony Jiang typedef SmallVector<MachineInstr *, 4> BlockISELList;
588e8c444dSTony Jiang typedef SmallDenseMap<int, BlockISELList> ISELInstructionList;
598e8c444dSTony Jiang
608e8c444dSTony Jiang // A map of MBB numbers to their lists of contained ISEL instructions.
613b49dc54STony Jiang // Please note when we traverse this list and expand ISEL, we only remove
623b49dc54STony Jiang // the ISEL from the MBB not from this list.
638e8c444dSTony Jiang ISELInstructionList ISELInstructions;
648e8c444dSTony Jiang
658e8c444dSTony Jiang /// Initialize the object.
668e8c444dSTony Jiang void initialize(MachineFunction &MFParam);
678e8c444dSTony Jiang
688e8c444dSTony Jiang void handleSpecialCases(BlockISELList &BIL, MachineBasicBlock *MBB);
698e8c444dSTony Jiang void reorganizeBlockLayout(BlockISELList &BIL, MachineBasicBlock *MBB);
708e8c444dSTony Jiang void populateBlocks(BlockISELList &BIL);
718e8c444dSTony Jiang void expandMergeableISELs(BlockISELList &BIL);
728e8c444dSTony Jiang void expandAndMergeISELs();
738e8c444dSTony Jiang
748e8c444dSTony Jiang bool canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI);
758e8c444dSTony Jiang
768e8c444dSTony Jiang /// Is this instruction an ISEL or ISEL8?
isISEL(const MachineInstr & MI)778e8c444dSTony Jiang static bool isISEL(const MachineInstr &MI) {
788e8c444dSTony Jiang return (MI.getOpcode() == PPC::ISEL || MI.getOpcode() == PPC::ISEL8);
798e8c444dSTony Jiang }
808e8c444dSTony Jiang
818e8c444dSTony Jiang /// Is this instruction an ISEL8?
isISEL8(const MachineInstr & MI)828e8c444dSTony Jiang static bool isISEL8(const MachineInstr &MI) {
838e8c444dSTony Jiang return (MI.getOpcode() == PPC::ISEL8);
848e8c444dSTony Jiang }
858e8c444dSTony Jiang
868e8c444dSTony Jiang /// Are the two operands using the same register?
useSameRegister(const MachineOperand & Op1,const MachineOperand & Op2)878e8c444dSTony Jiang bool useSameRegister(const MachineOperand &Op1, const MachineOperand &Op2) {
888e8c444dSTony Jiang return (Op1.getReg() == Op2.getReg());
898e8c444dSTony Jiang }
908e8c444dSTony Jiang
918e8c444dSTony Jiang ///
928e8c444dSTony Jiang /// Collect all ISEL instructions from the current function.
938e8c444dSTony Jiang ///
948e8c444dSTony Jiang /// Walk the current function and collect all the ISEL instructions that are
958e8c444dSTony Jiang /// found. The instructions are placed in the ISELInstructions vector.
968e8c444dSTony Jiang ///
978e8c444dSTony Jiang /// \return true if any ISEL instructions were found, false otherwise
988e8c444dSTony Jiang ///
998e8c444dSTony Jiang bool collectISELInstructions();
1008e8c444dSTony Jiang
1018e8c444dSTony Jiang public:
1028e8c444dSTony Jiang static char ID;
PPCExpandISEL()1038e8c444dSTony Jiang PPCExpandISEL() : MachineFunctionPass(ID) {
1048e8c444dSTony Jiang initializePPCExpandISELPass(*PassRegistry::getPassRegistry());
1058e8c444dSTony Jiang }
1068e8c444dSTony Jiang
1078e8c444dSTony Jiang ///
1088e8c444dSTony Jiang /// Determine whether to generate the ISEL instruction or expand it.
1098e8c444dSTony Jiang ///
1108e8c444dSTony Jiang /// Expand ISEL instruction into if-then-else sequence when one of
1118e8c444dSTony Jiang /// the following two conditions hold:
1128e8c444dSTony Jiang /// (1) -ppc-gen-isel=false
1138e8c444dSTony Jiang /// (2) hasISEL() return false
1148e8c444dSTony Jiang /// Otherwise, still generate ISEL instruction.
1158e8c444dSTony Jiang /// The -ppc-gen-isel option is set to true by default. Which means the ISEL
1168e8c444dSTony Jiang /// instruction is still generated by default on targets that support them.
1178e8c444dSTony Jiang ///
1188e8c444dSTony Jiang /// \return true if ISEL should be expanded into if-then-else code sequence;
1190f7f59f0SHiroshi Inoue /// false if ISEL instruction should be generated, i.e. not expanded.
1208e8c444dSTony Jiang ///
1218e8c444dSTony Jiang static bool isExpandISELEnabled(const MachineFunction &MF);
1228e8c444dSTony Jiang
1238e8c444dSTony Jiang #ifndef NDEBUG
1248e8c444dSTony Jiang void DumpISELInstructions() const;
1258e8c444dSTony Jiang #endif
1268e8c444dSTony Jiang
runOnMachineFunction(MachineFunction & MF)1278e8c444dSTony Jiang bool runOnMachineFunction(MachineFunction &MF) override {
128d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Function: "; MF.dump(); dbgs() << "\n");
1298e8c444dSTony Jiang initialize(MF);
1308e8c444dSTony Jiang
1318e8c444dSTony Jiang if (!collectISELInstructions()) {
132d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "No ISEL instructions in this function\n");
1338e8c444dSTony Jiang return false;
1348e8c444dSTony Jiang }
1358e8c444dSTony Jiang
1368e8c444dSTony Jiang #ifndef NDEBUG
1378e8c444dSTony Jiang DumpISELInstructions();
1388e8c444dSTony Jiang #endif
1398e8c444dSTony Jiang
1408e8c444dSTony Jiang expandAndMergeISELs();
1418e8c444dSTony Jiang
1428e8c444dSTony Jiang return true;
1438e8c444dSTony Jiang }
1448e8c444dSTony Jiang };
145efcf06f5SBenjamin Kramer } // end anonymous namespace
1468e8c444dSTony Jiang
initialize(MachineFunction & MFParam)1478e8c444dSTony Jiang void PPCExpandISEL::initialize(MachineFunction &MFParam) {
1488e8c444dSTony Jiang MF = &MFParam;
1498e8c444dSTony Jiang TII = MF->getSubtarget().getInstrInfo();
1508e8c444dSTony Jiang ISELInstructions.clear();
1518e8c444dSTony Jiang }
1528e8c444dSTony Jiang
isExpandISELEnabled(const MachineFunction & MF)1538e8c444dSTony Jiang bool PPCExpandISEL::isExpandISELEnabled(const MachineFunction &MF) {
1548e8c444dSTony Jiang return !GenerateISEL || !MF.getSubtarget<PPCSubtarget>().hasISEL();
1558e8c444dSTony Jiang }
1568e8c444dSTony Jiang
collectISELInstructions()1578e8c444dSTony Jiang bool PPCExpandISEL::collectISELInstructions() {
1588e8c444dSTony Jiang for (MachineBasicBlock &MBB : *MF) {
1598e8c444dSTony Jiang BlockISELList thisBlockISELs;
1608e8c444dSTony Jiang for (MachineInstr &MI : MBB)
1618e8c444dSTony Jiang if (isISEL(MI))
1628e8c444dSTony Jiang thisBlockISELs.push_back(&MI);
1638e8c444dSTony Jiang if (!thisBlockISELs.empty())
1648e8c444dSTony Jiang ISELInstructions.insert(std::make_pair(MBB.getNumber(), thisBlockISELs));
1658e8c444dSTony Jiang }
1668e8c444dSTony Jiang return !ISELInstructions.empty();
1678e8c444dSTony Jiang }
1688e8c444dSTony Jiang
1698e8c444dSTony Jiang #ifndef NDEBUG
DumpISELInstructions() const1708e8c444dSTony Jiang void PPCExpandISEL::DumpISELInstructions() const {
1718e8c444dSTony Jiang for (const auto &I : ISELInstructions) {
172d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << printMBBReference(*MF->getBlockNumbered(I.first))
173d34e60caSNicola Zaghen << ":\n");
1748e8c444dSTony Jiang for (const auto &VI : I.second)
175d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << " "; VI->print(dbgs()));
1768e8c444dSTony Jiang }
1778e8c444dSTony Jiang }
1788e8c444dSTony Jiang #endif
1798e8c444dSTony Jiang
1808e8c444dSTony Jiang /// Contiguous ISELs that have the same condition can be merged.
canMerge(MachineInstr * PrevPushedMI,MachineInstr * MI)1818e8c444dSTony Jiang bool PPCExpandISEL::canMerge(MachineInstr *PrevPushedMI, MachineInstr *MI) {
1828e8c444dSTony Jiang // Same Condition Register?
1838e8c444dSTony Jiang if (!useSameRegister(PrevPushedMI->getOperand(3), MI->getOperand(3)))
1848e8c444dSTony Jiang return false;
1858e8c444dSTony Jiang
1868e8c444dSTony Jiang MachineBasicBlock::iterator PrevPushedMBBI = *PrevPushedMI;
1878e8c444dSTony Jiang MachineBasicBlock::iterator MBBI = *MI;
1888e8c444dSTony Jiang return (std::prev(MBBI) == PrevPushedMBBI); // Contiguous ISELs?
1898e8c444dSTony Jiang }
1908e8c444dSTony Jiang
expandAndMergeISELs()1918e8c444dSTony Jiang void PPCExpandISEL::expandAndMergeISELs() {
1923b49dc54STony Jiang bool ExpandISELEnabled = isExpandISELEnabled(*MF);
19325528d6dSFrancis Visoiu Mistrih
1943b49dc54STony Jiang for (auto &BlockList : ISELInstructions) {
195d34e60caSNicola Zaghen LLVM_DEBUG(
196d34e60caSNicola Zaghen dbgs() << "Expanding ISEL instructions in "
19725528d6dSFrancis Visoiu Mistrih << printMBBReference(*MF->getBlockNumbered(BlockList.first))
1988e8c444dSTony Jiang << "\n");
1998e8c444dSTony Jiang BlockISELList &CurrentISELList = BlockList.second;
2008e8c444dSTony Jiang auto I = CurrentISELList.begin();
2018e8c444dSTony Jiang auto E = CurrentISELList.end();
2028e8c444dSTony Jiang
2038e8c444dSTony Jiang while (I != E) {
2043b49dc54STony Jiang assert(isISEL(**I) && "Expecting an ISEL instruction");
2053b49dc54STony Jiang MachineOperand &Dest = (*I)->getOperand(0);
2063b49dc54STony Jiang MachineOperand &TrueValue = (*I)->getOperand(1);
2073b49dc54STony Jiang MachineOperand &FalseValue = (*I)->getOperand(2);
2083b49dc54STony Jiang
2093b49dc54STony Jiang // Special case 1, all registers used by ISEL are the same one.
2103b49dc54STony Jiang // The non-redundant isel 0, 0, 0, N would not satisfy these conditions
2113b49dc54STony Jiang // as it would be ISEL %R0, %ZERO, %R0, %CRN.
2123b49dc54STony Jiang if (useSameRegister(Dest, TrueValue) &&
2133b49dc54STony Jiang useSameRegister(Dest, FalseValue)) {
2140f7f59f0SHiroshi Inoue LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction: " << **I
215d34e60caSNicola Zaghen << "\n");
2163b49dc54STony Jiang // FIXME: if the CR field used has no other uses, we could eliminate the
2173b49dc54STony Jiang // instruction that defines it. This would have to be done manually
2183b49dc54STony Jiang // since this pass runs too late to run DCE after it.
2193b49dc54STony Jiang NumRemoved++;
2203b49dc54STony Jiang (*I)->eraseFromParent();
2213b49dc54STony Jiang I++;
2223b49dc54STony Jiang } else if (useSameRegister(TrueValue, FalseValue)) {
2233b49dc54STony Jiang // Special case 2, the two input registers used by ISEL are the same.
2243b49dc54STony Jiang // Note: the non-foldable isel RX, 0, 0, N would not satisfy this
2253b49dc54STony Jiang // condition as it would be ISEL %RX, %ZERO, %R0, %CRN, which makes it
2263b49dc54STony Jiang // safe to fold ISEL to MR(OR) instead of ADDI.
2273b49dc54STony Jiang MachineBasicBlock *MBB = (*I)->getParent();
228d34e60caSNicola Zaghen LLVM_DEBUG(
2290f7f59f0SHiroshi Inoue dbgs() << "Fold the ISEL instruction to an unconditional copy:\n");
230d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");
2313b49dc54STony Jiang NumFolded++;
2323b49dc54STony Jiang // Note: we're using both the TrueValue and FalseValue operands so as
2333b49dc54STony Jiang // not to lose the kill flag if it is set on either of them.
2343b49dc54STony Jiang BuildMI(*MBB, (*I), dl, TII->get(isISEL8(**I) ? PPC::OR8 : PPC::OR))
2353b49dc54STony Jiang .add(Dest)
2363b49dc54STony Jiang .add(TrueValue)
2373b49dc54STony Jiang .add(FalseValue);
2383b49dc54STony Jiang (*I)->eraseFromParent();
2393b49dc54STony Jiang I++;
2403b49dc54STony Jiang } else if (ExpandISELEnabled) { // Normal cases expansion enabled
241d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Expand ISEL instructions:\n");
242d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");
2438e8c444dSTony Jiang BlockISELList SubISELList;
2448e8c444dSTony Jiang SubISELList.push_back(*I++);
2458e8c444dSTony Jiang // Collect the ISELs that can be merged together.
2463b49dc54STony Jiang // This will eat up ISEL instructions without considering whether they
2473b49dc54STony Jiang // may be redundant or foldable to a register copy. So we still keep
2483b49dc54STony Jiang // the handleSpecialCases() downstream to handle them.
2493b49dc54STony Jiang while (I != E && canMerge(SubISELList.back(), *I)) {
250d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ISEL: " << **I << "\n");
2518e8c444dSTony Jiang SubISELList.push_back(*I++);
2523b49dc54STony Jiang }
2538e8c444dSTony Jiang
2548e8c444dSTony Jiang expandMergeableISELs(SubISELList);
2553b49dc54STony Jiang } else { // Normal cases expansion disabled
2563b49dc54STony Jiang I++; // leave the ISEL as it is
2578e8c444dSTony Jiang }
2583b49dc54STony Jiang } // end while
2593b49dc54STony Jiang } // end for
2608e8c444dSTony Jiang }
2618e8c444dSTony Jiang
handleSpecialCases(BlockISELList & BIL,MachineBasicBlock * MBB)2628e8c444dSTony Jiang void PPCExpandISEL::handleSpecialCases(BlockISELList &BIL,
2638e8c444dSTony Jiang MachineBasicBlock *MBB) {
2648e8c444dSTony Jiang IsTrueBlockRequired = false;
2658e8c444dSTony Jiang IsFalseBlockRequired = false;
2668e8c444dSTony Jiang
2678e8c444dSTony Jiang auto MI = BIL.begin();
2688e8c444dSTony Jiang while (MI != BIL.end()) {
2698e8c444dSTony Jiang assert(isISEL(**MI) && "Expecting an ISEL instruction");
270d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "ISEL: " << **MI << "\n");
2718e8c444dSTony Jiang
2728e8c444dSTony Jiang MachineOperand &Dest = (*MI)->getOperand(0);
2738e8c444dSTony Jiang MachineOperand &TrueValue = (*MI)->getOperand(1);
2748e8c444dSTony Jiang MachineOperand &FalseValue = (*MI)->getOperand(2);
2758e8c444dSTony Jiang
2768e8c444dSTony Jiang // If at least one of the ISEL instructions satisfy the following
2778e8c444dSTony Jiang // condition, we need the True Block:
2788e8c444dSTony Jiang // The Dest Register and True Value Register are not the same
2798e8c444dSTony Jiang // Similarly, if at least one of the ISEL instructions satisfy the
2808e8c444dSTony Jiang // following condition, we need the False Block:
2818e8c444dSTony Jiang // The Dest Register and False Value Register are not the same.
2828e8c444dSTony Jiang bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
2838e8c444dSTony Jiang bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
2848e8c444dSTony Jiang
2858e8c444dSTony Jiang // Special case 1, all registers used by ISEL are the same one.
2868e8c444dSTony Jiang if (!IsADDIInstRequired && !IsORIInstRequired) {
287cd83d459SHiroshi Inoue LLVM_DEBUG(dbgs() << "Remove redundant ISEL instruction.");
2883b49dc54STony Jiang // FIXME: if the CR field used has no other uses, we could eliminate the
2893b49dc54STony Jiang // instruction that defines it. This would have to be done manually
2903b49dc54STony Jiang // since this pass runs too late to run DCE after it.
2918e8c444dSTony Jiang NumRemoved++;
2928e8c444dSTony Jiang (*MI)->eraseFromParent();
2938e8c444dSTony Jiang // Setting MI to the erase result keeps the iterator valid and increased.
2948e8c444dSTony Jiang MI = BIL.erase(MI);
2958e8c444dSTony Jiang continue;
2968e8c444dSTony Jiang }
2978e8c444dSTony Jiang
2988e8c444dSTony Jiang // Special case 2, the two input registers used by ISEL are the same.
2998e8c444dSTony Jiang // Note 1: We favor merging ISEL expansions over folding a single one. If
3008e8c444dSTony Jiang // the passed list has multiple merge-able ISEL's, we won't fold any.
3018e8c444dSTony Jiang // Note 2: There is no need to test for PPC::R0/PPC::X0 because PPC::ZERO/
3028e8c444dSTony Jiang // PPC::ZERO8 will be used for the first operand if the value is meant to
3038e8c444dSTony Jiang // be zero. In this case, the useSameRegister method will return false,
3048e8c444dSTony Jiang // thereby preventing this ISEL from being folded.
3058e8c444dSTony Jiang if (useSameRegister(TrueValue, FalseValue) && (BIL.size() == 1)) {
306d34e60caSNicola Zaghen LLVM_DEBUG(
307cd83d459SHiroshi Inoue dbgs() << "Fold the ISEL instruction to an unconditional copy.");
3088e8c444dSTony Jiang NumFolded++;
3093b49dc54STony Jiang // Note: we're using both the TrueValue and FalseValue operands so as
3103b49dc54STony Jiang // not to lose the kill flag if it is set on either of them.
3113b49dc54STony Jiang BuildMI(*MBB, (*MI), dl, TII->get(isISEL8(**MI) ? PPC::OR8 : PPC::OR))
3128e8c444dSTony Jiang .add(Dest)
3138e8c444dSTony Jiang .add(TrueValue)
3143b49dc54STony Jiang .add(FalseValue);
3158e8c444dSTony Jiang (*MI)->eraseFromParent();
3168e8c444dSTony Jiang // Setting MI to the erase result keeps the iterator valid and increased.
3178e8c444dSTony Jiang MI = BIL.erase(MI);
3188e8c444dSTony Jiang continue;
3198e8c444dSTony Jiang }
3208e8c444dSTony Jiang
3218e8c444dSTony Jiang IsTrueBlockRequired |= IsADDIInstRequired;
3228e8c444dSTony Jiang IsFalseBlockRequired |= IsORIInstRequired;
3238e8c444dSTony Jiang MI++;
3248e8c444dSTony Jiang }
3258e8c444dSTony Jiang }
3268e8c444dSTony Jiang
reorganizeBlockLayout(BlockISELList & BIL,MachineBasicBlock * MBB)3278e8c444dSTony Jiang void PPCExpandISEL::reorganizeBlockLayout(BlockISELList &BIL,
3288e8c444dSTony Jiang MachineBasicBlock *MBB) {
3298e8c444dSTony Jiang if (BIL.empty())
3308e8c444dSTony Jiang return;
3318e8c444dSTony Jiang
3328e8c444dSTony Jiang assert((IsTrueBlockRequired || IsFalseBlockRequired) &&
3338e8c444dSTony Jiang "Should have been handled by special cases earlier!");
3348e8c444dSTony Jiang
3358e8c444dSTony Jiang MachineBasicBlock *Successor = nullptr;
3368e8c444dSTony Jiang const BasicBlock *LLVM_BB = MBB->getBasicBlock();
3378e8c444dSTony Jiang MachineBasicBlock::iterator MBBI = (*BIL.back());
3388e8c444dSTony Jiang NewSuccessor = (MBBI != MBB->getLastNonDebugInstr() || !MBB->canFallThrough())
3398e8c444dSTony Jiang // Another BB is needed to move the instructions that
3408e8c444dSTony Jiang // follow this ISEL. If the ISEL is the last instruction
3418e8c444dSTony Jiang // in a block that can't fall through, we also need a block
3428e8c444dSTony Jiang // to branch to.
3438e8c444dSTony Jiang ? MF->CreateMachineBasicBlock(LLVM_BB)
3448e8c444dSTony Jiang : nullptr;
3458e8c444dSTony Jiang
3468e8c444dSTony Jiang MachineFunction::iterator It = MBB->getIterator();
3478e8c444dSTony Jiang ++It; // Point to the successor block of MBB.
3488e8c444dSTony Jiang
3498e8c444dSTony Jiang // If NewSuccessor is NULL then the last ISEL in this group is the last
3508e8c444dSTony Jiang // non-debug instruction in this block. Find the fall-through successor
3518e8c444dSTony Jiang // of this block to use when updating the CFG below.
3528e8c444dSTony Jiang if (!NewSuccessor) {
3538e8c444dSTony Jiang for (auto &Succ : MBB->successors()) {
3548e8c444dSTony Jiang if (MBB->isLayoutSuccessor(Succ)) {
3558e8c444dSTony Jiang Successor = Succ;
3568e8c444dSTony Jiang break;
3578e8c444dSTony Jiang }
3588e8c444dSTony Jiang }
3598e8c444dSTony Jiang } else
3608e8c444dSTony Jiang Successor = NewSuccessor;
3618e8c444dSTony Jiang
3628e8c444dSTony Jiang // The FalseBlock and TrueBlock are inserted after the MBB block but before
3638e8c444dSTony Jiang // its successor.
3648e8c444dSTony Jiang // Note this need to be done *after* the above setting the Successor code.
3658e8c444dSTony Jiang if (IsFalseBlockRequired) {
3668e8c444dSTony Jiang FalseBlock = MF->CreateMachineBasicBlock(LLVM_BB);
3678e8c444dSTony Jiang MF->insert(It, FalseBlock);
3688e8c444dSTony Jiang }
3698e8c444dSTony Jiang
3708e8c444dSTony Jiang if (IsTrueBlockRequired) {
3718e8c444dSTony Jiang TrueBlock = MF->CreateMachineBasicBlock(LLVM_BB);
3728e8c444dSTony Jiang MF->insert(It, TrueBlock);
3738e8c444dSTony Jiang }
3748e8c444dSTony Jiang
3758e8c444dSTony Jiang if (NewSuccessor) {
3768e8c444dSTony Jiang MF->insert(It, NewSuccessor);
3778e8c444dSTony Jiang
3788e8c444dSTony Jiang // Transfer the rest of this block into the new successor block.
3798e8c444dSTony Jiang NewSuccessor->splice(NewSuccessor->end(), MBB,
3808e8c444dSTony Jiang std::next(MachineBasicBlock::iterator(BIL.back())),
3818e8c444dSTony Jiang MBB->end());
3828e8c444dSTony Jiang NewSuccessor->transferSuccessorsAndUpdatePHIs(MBB);
3838e8c444dSTony Jiang
3844bb0a1cbSKang Zhang // Update the liveins for NewSuccessor.
3854bb0a1cbSKang Zhang LivePhysRegs LPR;
3864bb0a1cbSKang Zhang computeAndAddLiveIns(LPR, *NewSuccessor);
3878e8c444dSTony Jiang
3888e8c444dSTony Jiang } else {
3898e8c444dSTony Jiang // Remove successor from MBB.
3908e8c444dSTony Jiang MBB->removeSuccessor(Successor);
3918e8c444dSTony Jiang }
3928e8c444dSTony Jiang
3938e8c444dSTony Jiang // Note that this needs to be done *after* transfering the successors from MBB
3948e8c444dSTony Jiang // to the NewSuccessor block, otherwise these blocks will also be transferred
3958e8c444dSTony Jiang // as successors!
3968e8c444dSTony Jiang MBB->addSuccessor(IsTrueBlockRequired ? TrueBlock : Successor);
3978e8c444dSTony Jiang MBB->addSuccessor(IsFalseBlockRequired ? FalseBlock : Successor);
3988e8c444dSTony Jiang
3998e8c444dSTony Jiang if (IsTrueBlockRequired) {
4008e8c444dSTony Jiang TrueBlockI = TrueBlock->begin();
4018e8c444dSTony Jiang TrueBlock->addSuccessor(Successor);
4028e8c444dSTony Jiang }
4038e8c444dSTony Jiang
4048e8c444dSTony Jiang if (IsFalseBlockRequired) {
4058e8c444dSTony Jiang FalseBlockI = FalseBlock->begin();
4068e8c444dSTony Jiang FalseBlock->addSuccessor(Successor);
4078e8c444dSTony Jiang }
4088e8c444dSTony Jiang
4098e8c444dSTony Jiang // Conditional branch to the TrueBlock or Successor
4108e8c444dSTony Jiang BuildMI(*MBB, BIL.back(), dl, TII->get(PPC::BC))
4118e8c444dSTony Jiang .add(BIL.back()->getOperand(3))
4128e8c444dSTony Jiang .addMBB(IsTrueBlockRequired ? TrueBlock : Successor);
4138e8c444dSTony Jiang
4148e8c444dSTony Jiang // Jump over the true block to the new successor if the condition is false.
4158e8c444dSTony Jiang BuildMI(*(IsFalseBlockRequired ? FalseBlock : MBB),
4168e8c444dSTony Jiang (IsFalseBlockRequired ? FalseBlockI : BIL.back()), dl,
4178e8c444dSTony Jiang TII->get(PPC::B))
4188e8c444dSTony Jiang .addMBB(Successor);
4198e8c444dSTony Jiang
4208e8c444dSTony Jiang if (IsFalseBlockRequired)
4218e8c444dSTony Jiang FalseBlockI = FalseBlock->begin(); // get the position of PPC::B
4228e8c444dSTony Jiang }
4238e8c444dSTony Jiang
populateBlocks(BlockISELList & BIL)4248e8c444dSTony Jiang void PPCExpandISEL::populateBlocks(BlockISELList &BIL) {
4258e8c444dSTony Jiang for (auto &MI : BIL) {
4268e8c444dSTony Jiang assert(isISEL(*MI) && "Expecting an ISEL instruction");
4278e8c444dSTony Jiang
4288e8c444dSTony Jiang MachineOperand &Dest = MI->getOperand(0); // location to store to
4298e8c444dSTony Jiang MachineOperand &TrueValue = MI->getOperand(1); // Value to store if
4308e8c444dSTony Jiang // condition is true
4318e8c444dSTony Jiang MachineOperand &FalseValue = MI->getOperand(2); // Value to store if
4328e8c444dSTony Jiang // condition is false
4338e8c444dSTony Jiang
434d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Dest: " << Dest << "\n");
435d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "TrueValue: " << TrueValue << "\n");
436d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "FalseValue: " << FalseValue << "\n");
437*b73290beSHaojian Wu LLVM_DEBUG(dbgs() << "ConditionRegister: " << MI->getOperand(3) << "\n");
4388e8c444dSTony Jiang
4398e8c444dSTony Jiang // If the Dest Register and True Value Register are not the same one, we
4408e8c444dSTony Jiang // need the True Block.
4418e8c444dSTony Jiang bool IsADDIInstRequired = !useSameRegister(Dest, TrueValue);
4428e8c444dSTony Jiang bool IsORIInstRequired = !useSameRegister(Dest, FalseValue);
4438e8c444dSTony Jiang
4448e8c444dSTony Jiang // Copy the result into the destination if the condition is true.
4454bb0a1cbSKang Zhang if (IsADDIInstRequired)
4468e8c444dSTony Jiang BuildMI(*TrueBlock, TrueBlockI, dl,
4478e8c444dSTony Jiang TII->get(isISEL8(*MI) ? PPC::ADDI8 : PPC::ADDI))
4488e8c444dSTony Jiang .add(Dest)
4498e8c444dSTony Jiang .add(TrueValue)
4508e8c444dSTony Jiang .add(MachineOperand::CreateImm(0));
4518e8c444dSTony Jiang
4524bb0a1cbSKang Zhang // Copy the result into the destination if the condition is false.
4538e8c444dSTony Jiang if (IsORIInstRequired)
4548e8c444dSTony Jiang BuildMI(*FalseBlock, FalseBlockI, dl,
4558e8c444dSTony Jiang TII->get(isISEL8(*MI) ? PPC::ORI8 : PPC::ORI))
4568e8c444dSTony Jiang .add(Dest)
4578e8c444dSTony Jiang .add(FalseValue)
4588e8c444dSTony Jiang .add(MachineOperand::CreateImm(0));
4598e8c444dSTony Jiang
4608e8c444dSTony Jiang MI->eraseFromParent(); // Remove the ISEL instruction.
4618e8c444dSTony Jiang
4628e8c444dSTony Jiang NumExpanded++;
4638e8c444dSTony Jiang }
4644bb0a1cbSKang Zhang
4654bb0a1cbSKang Zhang if (IsTrueBlockRequired) {
4664bb0a1cbSKang Zhang // Update the liveins for TrueBlock.
4674bb0a1cbSKang Zhang LivePhysRegs LPR;
4684bb0a1cbSKang Zhang computeAndAddLiveIns(LPR, *TrueBlock);
4694bb0a1cbSKang Zhang }
4704bb0a1cbSKang Zhang
4714bb0a1cbSKang Zhang if (IsFalseBlockRequired) {
4724bb0a1cbSKang Zhang // Update the liveins for FalseBlock.
4734bb0a1cbSKang Zhang LivePhysRegs LPR;
4744bb0a1cbSKang Zhang computeAndAddLiveIns(LPR, *FalseBlock);
4754bb0a1cbSKang Zhang }
4768e8c444dSTony Jiang }
4778e8c444dSTony Jiang
expandMergeableISELs(BlockISELList & BIL)4788e8c444dSTony Jiang void PPCExpandISEL::expandMergeableISELs(BlockISELList &BIL) {
4798e8c444dSTony Jiang // At this stage all the ISELs of BIL are in the same MBB.
4808e8c444dSTony Jiang MachineBasicBlock *MBB = BIL.back()->getParent();
4818e8c444dSTony Jiang
4828e8c444dSTony Jiang handleSpecialCases(BIL, MBB);
4838e8c444dSTony Jiang reorganizeBlockLayout(BIL, MBB);
4848e8c444dSTony Jiang populateBlocks(BIL);
4858e8c444dSTony Jiang }
4868e8c444dSTony Jiang
4878e8c444dSTony Jiang INITIALIZE_PASS(PPCExpandISEL, DEBUG_TYPE, "PowerPC Expand ISEL Generation",
4888e8c444dSTony Jiang false, false)
4898e8c444dSTony Jiang char PPCExpandISEL::ID = 0;
4908e8c444dSTony Jiang
createPPCExpandISELPass()4918e8c444dSTony Jiang FunctionPass *llvm::createPPCExpandISELPass() { return new PPCExpandISEL(); }
492