xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCExpandISEL.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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