xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/PPCCTRLoops.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
181ad6265SDimitry Andric //===-- PPCCTRLoops.cpp - Generate CTR loops ------------------------------===//
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 //
981ad6265SDimitry Andric // This pass generates machine instructions for the CTR loops related pseudos:
10bdd1243dSDimitry Andric // 1: MTCTRloop/DecreaseCTRloop
11bdd1243dSDimitry Andric // 2: MTCTR8loop/DecreaseCTR8loop
1281ad6265SDimitry Andric //
1381ad6265SDimitry Andric // If a CTR loop can be generated:
14bdd1243dSDimitry Andric // 1: MTCTRloop/MTCTR8loop will be converted to "mtctr"
15bdd1243dSDimitry Andric // 2: DecreaseCTRloop/DecreaseCTR8loop will be converted to "bdnz/bdz" and
1681ad6265SDimitry Andric //    its user branch instruction can be deleted.
1781ad6265SDimitry Andric //
1881ad6265SDimitry Andric // If a CTR loop can not be generated due to clobber of CTR:
19bdd1243dSDimitry Andric // 1: MTCTRloop/MTCTR8loop can be deleted.
20bdd1243dSDimitry Andric // 2: DecreaseCTRloop/DecreaseCTR8loop will be converted to "addi -1" and
2181ad6265SDimitry Andric //    a "cmplwi/cmpldi".
2281ad6265SDimitry Andric //
2381ad6265SDimitry Andric // This pass runs just before register allocation, because we don't want
24bdd1243dSDimitry Andric // register allocator to allocate register for DecreaseCTRloop if a CTR can be
2581ad6265SDimitry Andric // generated or if a CTR loop can not be generated, we don't have any condition
2681ad6265SDimitry Andric // register for the new added "cmplwi/cmpldi".
270b57cec5SDimitry Andric //
280b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
290b57cec5SDimitry Andric 
30e8d8bef9SDimitry Andric #include "PPC.h"
3181ad6265SDimitry Andric #include "PPCInstrInfo.h"
3281ad6265SDimitry Andric #include "PPCSubtarget.h"
3381ad6265SDimitry Andric #include "llvm/ADT/Statistic.h"
34e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
37e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
3881ad6265SDimitry Andric #include "llvm/CodeGen/MachineLoopInfo.h"
39e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
4081ad6265SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
41e8d8bef9SDimitry Andric #include "llvm/CodeGen/Register.h"
42e8d8bef9SDimitry Andric #include "llvm/InitializePasses.h"
43e8d8bef9SDimitry Andric #include "llvm/Pass.h"
44e8d8bef9SDimitry Andric #include "llvm/PassRegistry.h"
45e8d8bef9SDimitry Andric #include "llvm/Support/CodeGen.h"
46e8d8bef9SDimitry Andric #include "llvm/Support/Debug.h"
47e8d8bef9SDimitry Andric #include "llvm/Support/ErrorHandling.h"
4881ad6265SDimitry Andric #include <cassert>
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric using namespace llvm;
510b57cec5SDimitry Andric 
5281ad6265SDimitry Andric #define DEBUG_TYPE "ppc-ctrloops"
5381ad6265SDimitry Andric 
5481ad6265SDimitry Andric STATISTIC(NumCTRLoops, "Number of CTR loops generated");
5581ad6265SDimitry Andric STATISTIC(NumNormalLoops, "Number of normal compare + branch loops generated");
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric namespace {
5881ad6265SDimitry Andric class PPCCTRLoops : public MachineFunctionPass {
590b57cec5SDimitry Andric public:
600b57cec5SDimitry Andric   static char ID;
610b57cec5SDimitry Andric 
PPCCTRLoops()6281ad6265SDimitry Andric   PPCCTRLoops() : MachineFunctionPass(ID) {
6381ad6265SDimitry Andric     initializePPCCTRLoopsPass(*PassRegistry::getPassRegistry());
640b57cec5SDimitry Andric   }
650b57cec5SDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const660b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
67*0fca6ea1SDimitry Andric     AU.addRequired<MachineLoopInfoWrapperPass>();
680b57cec5SDimitry Andric     MachineFunctionPass::getAnalysisUsage(AU);
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric private:
7481ad6265SDimitry Andric   const PPCInstrInfo *TII = nullptr;
7581ad6265SDimitry Andric   MachineRegisterInfo *MRI = nullptr;
7681ad6265SDimitry Andric 
7781ad6265SDimitry Andric   bool processLoop(MachineLoop *ML);
7881ad6265SDimitry Andric   bool isCTRClobber(MachineInstr *MI, bool CheckReads) const;
7981ad6265SDimitry Andric   void expandNormalLoops(MachineLoop *ML, MachineInstr *Start,
8081ad6265SDimitry Andric                          MachineInstr *Dec);
8181ad6265SDimitry Andric   void expandCTRLoops(MachineLoop *ML, MachineInstr *Start, MachineInstr *Dec);
8281ad6265SDimitry Andric };
8381ad6265SDimitry Andric } // namespace
8481ad6265SDimitry Andric 
8581ad6265SDimitry Andric char PPCCTRLoops::ID = 0;
8681ad6265SDimitry Andric 
8781ad6265SDimitry Andric INITIALIZE_PASS_BEGIN(PPCCTRLoops, DEBUG_TYPE, "PowerPC CTR loops generation",
8881ad6265SDimitry Andric                       false, false)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)89*0fca6ea1SDimitry Andric INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
9081ad6265SDimitry Andric INITIALIZE_PASS_END(PPCCTRLoops, DEBUG_TYPE, "PowerPC CTR loops generation",
9181ad6265SDimitry Andric                     false, false)
9281ad6265SDimitry Andric 
9381ad6265SDimitry Andric FunctionPass *llvm::createPPCCTRLoopsPass() { return new PPCCTRLoops(); }
9481ad6265SDimitry Andric 
runOnMachineFunction(MachineFunction & MF)9581ad6265SDimitry Andric bool PPCCTRLoops::runOnMachineFunction(MachineFunction &MF) {
9681ad6265SDimitry Andric   bool Changed = false;
9781ad6265SDimitry Andric 
98*0fca6ea1SDimitry Andric   auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
9981ad6265SDimitry Andric   TII = static_cast<const PPCInstrInfo *>(MF.getSubtarget().getInstrInfo());
10081ad6265SDimitry Andric   MRI = &MF.getRegInfo();
10181ad6265SDimitry Andric 
102bdd1243dSDimitry Andric   for (auto *ML : MLI) {
10381ad6265SDimitry Andric     if (ML->isOutermost())
10481ad6265SDimitry Andric       Changed |= processLoop(ML);
10581ad6265SDimitry Andric   }
10681ad6265SDimitry Andric 
107bdd1243dSDimitry Andric #ifndef NDEBUG
108bdd1243dSDimitry Andric   for (const MachineBasicBlock &BB : MF) {
109bdd1243dSDimitry Andric     for (const MachineInstr &I : BB)
110bdd1243dSDimitry Andric       assert((I.getOpcode() != PPC::DecreaseCTRloop &&
111bdd1243dSDimitry Andric               I.getOpcode() != PPC::DecreaseCTR8loop) &&
112bdd1243dSDimitry Andric              "CTR loop pseudo is not expanded!");
113bdd1243dSDimitry Andric   }
114bdd1243dSDimitry Andric #endif
115bdd1243dSDimitry Andric 
11681ad6265SDimitry Andric   return Changed;
11781ad6265SDimitry Andric }
11881ad6265SDimitry Andric 
isCTRClobber(MachineInstr * MI,bool CheckReads) const11981ad6265SDimitry Andric bool PPCCTRLoops::isCTRClobber(MachineInstr *MI, bool CheckReads) const {
12081ad6265SDimitry Andric   if (!CheckReads) {
12181ad6265SDimitry Andric     // If we are only checking for defs, that is we are going to find
12281ad6265SDimitry Andric     // definitions before MTCTRloop, for this case:
12381ad6265SDimitry Andric     // CTR defination inside the callee of a call instruction will not impact
12481ad6265SDimitry Andric     // the defination of MTCTRloop, so we can use definesRegister() for the
12581ad6265SDimitry Andric     // check, no need to check the regmask.
126*0fca6ea1SDimitry Andric     return MI->definesRegister(PPC::CTR, /*TRI=*/nullptr) ||
127*0fca6ea1SDimitry Andric            MI->definesRegister(PPC::CTR8, /*TRI=*/nullptr);
12881ad6265SDimitry Andric   }
12981ad6265SDimitry Andric 
130*0fca6ea1SDimitry Andric   if (MI->modifiesRegister(PPC::CTR, /*TRI=*/nullptr) ||
131*0fca6ea1SDimitry Andric       MI->modifiesRegister(PPC::CTR8, /*TRI=*/nullptr))
13281ad6265SDimitry Andric     return true;
13381ad6265SDimitry Andric 
13481ad6265SDimitry Andric   if (MI->getDesc().isCall())
13581ad6265SDimitry Andric     return true;
13681ad6265SDimitry Andric 
13781ad6265SDimitry Andric   // We define the CTR in the loop preheader, so if there is any CTR reader in
13881ad6265SDimitry Andric   // the loop, we also can not use CTR loop form.
139*0fca6ea1SDimitry Andric   if (MI->readsRegister(PPC::CTR, /*TRI=*/nullptr) ||
140*0fca6ea1SDimitry Andric       MI->readsRegister(PPC::CTR8, /*TRI=*/nullptr))
14181ad6265SDimitry Andric     return true;
14281ad6265SDimitry Andric 
14381ad6265SDimitry Andric   return false;
14481ad6265SDimitry Andric }
14581ad6265SDimitry Andric 
processLoop(MachineLoop * ML)14681ad6265SDimitry Andric bool PPCCTRLoops::processLoop(MachineLoop *ML) {
14781ad6265SDimitry Andric   bool Changed = false;
14881ad6265SDimitry Andric 
14981ad6265SDimitry Andric   // Align with HardwareLoop pass, process inner loops first.
150bdd1243dSDimitry Andric   for (MachineLoop *I : *ML)
151bdd1243dSDimitry Andric     Changed |= processLoop(I);
15281ad6265SDimitry Andric 
15381ad6265SDimitry Andric   // If any inner loop is changed, outter loop must be without hardware loop
15481ad6265SDimitry Andric   // intrinsics.
15581ad6265SDimitry Andric   if (Changed)
15681ad6265SDimitry Andric     return true;
15781ad6265SDimitry Andric 
15881ad6265SDimitry Andric   auto IsLoopStart = [](MachineInstr &MI) {
159bdd1243dSDimitry Andric     return MI.getOpcode() == PPC::MTCTRloop ||
160bdd1243dSDimitry Andric            MI.getOpcode() == PPC::MTCTR8loop;
1610b57cec5SDimitry Andric   };
1620b57cec5SDimitry Andric 
16381ad6265SDimitry Andric   auto SearchForStart =
16481ad6265SDimitry Andric       [&IsLoopStart](MachineBasicBlock *MBB) -> MachineInstr * {
16581ad6265SDimitry Andric     for (auto &MI : *MBB) {
16681ad6265SDimitry Andric       if (IsLoopStart(MI))
16781ad6265SDimitry Andric         return &MI;
1680b57cec5SDimitry Andric     }
16981ad6265SDimitry Andric     return nullptr;
17081ad6265SDimitry Andric   };
1710b57cec5SDimitry Andric 
17281ad6265SDimitry Andric   MachineInstr *Start = nullptr;
17381ad6265SDimitry Andric   MachineInstr *Dec = nullptr;
17481ad6265SDimitry Andric   bool InvalidCTRLoop = false;
1750b57cec5SDimitry Andric 
17681ad6265SDimitry Andric   MachineBasicBlock *Preheader = ML->getLoopPreheader();
177bdd1243dSDimitry Andric   // If there is no preheader for this loop, there must be no MTCTRloop
17881ad6265SDimitry Andric   // either.
17981ad6265SDimitry Andric   if (!Preheader)
1800b57cec5SDimitry Andric     return false;
18181ad6265SDimitry Andric 
18281ad6265SDimitry Andric   Start = SearchForStart(Preheader);
18381ad6265SDimitry Andric   // This is not a CTR loop candidate.
18481ad6265SDimitry Andric   if (!Start)
18581ad6265SDimitry Andric     return false;
18681ad6265SDimitry Andric 
18781ad6265SDimitry Andric   // If CTR is live to the preheader, we can not redefine the CTR register.
18881ad6265SDimitry Andric   if (Preheader->isLiveIn(PPC::CTR) || Preheader->isLiveIn(PPC::CTR8))
18981ad6265SDimitry Andric     InvalidCTRLoop = true;
19081ad6265SDimitry Andric 
19181ad6265SDimitry Andric   // Make sure there is also no CTR clobber in the block preheader between the
19281ad6265SDimitry Andric   // begin and MTCTR.
19381ad6265SDimitry Andric   for (MachineBasicBlock::reverse_instr_iterator I =
19481ad6265SDimitry Andric            std::next(Start->getReverseIterator());
19581ad6265SDimitry Andric        I != Preheader->instr_rend(); ++I)
19681ad6265SDimitry Andric     // Only check the definitions of CTR. If there is non-dead definition for
19781ad6265SDimitry Andric     // the CTR, we conservatively don't generate a CTR loop.
19881ad6265SDimitry Andric     if (isCTRClobber(&*I, /* CheckReads */ false)) {
19981ad6265SDimitry Andric       InvalidCTRLoop = true;
20081ad6265SDimitry Andric       break;
2010b57cec5SDimitry Andric     }
2020b57cec5SDimitry Andric 
20381ad6265SDimitry Andric   // Make sure there is also no CTR clobber/user in the block preheader between
20481ad6265SDimitry Andric   // MTCTR and the end.
20581ad6265SDimitry Andric   for (MachineBasicBlock::instr_iterator I = std::next(Start->getIterator());
20681ad6265SDimitry Andric        I != Preheader->instr_end(); ++I)
20781ad6265SDimitry Andric     if (isCTRClobber(&*I, /* CheckReads */ true)) {
20881ad6265SDimitry Andric       InvalidCTRLoop = true;
20981ad6265SDimitry Andric       break;
21081ad6265SDimitry Andric     }
2110b57cec5SDimitry Andric 
21281ad6265SDimitry Andric   // Find the CTR loop components and decide whether or not to fall back to a
21381ad6265SDimitry Andric   // normal loop.
21481ad6265SDimitry Andric   for (auto *MBB : reverse(ML->getBlocks())) {
21581ad6265SDimitry Andric     for (auto &MI : *MBB) {
216bdd1243dSDimitry Andric       if (MI.getOpcode() == PPC::DecreaseCTRloop ||
217bdd1243dSDimitry Andric           MI.getOpcode() == PPC::DecreaseCTR8loop)
21881ad6265SDimitry Andric         Dec = &MI;
21981ad6265SDimitry Andric       else if (!InvalidCTRLoop)
22081ad6265SDimitry Andric         // If any instruction clobber CTR, then we can not generate a CTR loop.
22181ad6265SDimitry Andric         InvalidCTRLoop |= isCTRClobber(&MI, /* CheckReads */ true);
22281ad6265SDimitry Andric     }
22381ad6265SDimitry Andric     if (Dec && InvalidCTRLoop)
22481ad6265SDimitry Andric       break;
22581ad6265SDimitry Andric   }
22681ad6265SDimitry Andric 
22781ad6265SDimitry Andric   assert(Dec && "CTR loop is not complete!");
22881ad6265SDimitry Andric 
22981ad6265SDimitry Andric   if (InvalidCTRLoop) {
23081ad6265SDimitry Andric     expandNormalLoops(ML, Start, Dec);
23181ad6265SDimitry Andric     ++NumNormalLoops;
23281ad6265SDimitry Andric   }
23381ad6265SDimitry Andric   else {
23481ad6265SDimitry Andric     expandCTRLoops(ML, Start, Dec);
23581ad6265SDimitry Andric     ++NumCTRLoops;
23681ad6265SDimitry Andric   }
23781ad6265SDimitry Andric   return true;
23881ad6265SDimitry Andric }
23981ad6265SDimitry Andric 
expandNormalLoops(MachineLoop * ML,MachineInstr * Start,MachineInstr * Dec)24081ad6265SDimitry Andric void PPCCTRLoops::expandNormalLoops(MachineLoop *ML, MachineInstr *Start,
24181ad6265SDimitry Andric                                     MachineInstr *Dec) {
24281ad6265SDimitry Andric   bool Is64Bit =
24381ad6265SDimitry Andric       Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
24481ad6265SDimitry Andric 
24581ad6265SDimitry Andric   MachineBasicBlock *Preheader = Start->getParent();
24681ad6265SDimitry Andric   MachineBasicBlock *Exiting = Dec->getParent();
24781ad6265SDimitry Andric   assert((Preheader && Exiting) &&
24881ad6265SDimitry Andric          "Preheader and exiting should exist for CTR loop!");
24981ad6265SDimitry Andric 
25081ad6265SDimitry Andric   assert(Dec->getOperand(1).getImm() == 1 &&
25181ad6265SDimitry Andric          "Loop decrement stride must be 1");
25281ad6265SDimitry Andric 
25381ad6265SDimitry Andric   unsigned ADDIOpcode = Is64Bit ? PPC::ADDI8 : PPC::ADDI;
25481ad6265SDimitry Andric   unsigned CMPOpcode = Is64Bit ? PPC::CMPLDI : PPC::CMPLWI;
25581ad6265SDimitry Andric 
25681ad6265SDimitry Andric   Register PHIDef =
25781ad6265SDimitry Andric       MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
25881ad6265SDimitry Andric                                          : &PPC::GPRC_and_GPRC_NOR0RegClass);
25981ad6265SDimitry Andric 
26081ad6265SDimitry Andric   Start->getParent()->getParent()->getProperties().reset(
26181ad6265SDimitry Andric       MachineFunctionProperties::Property::NoPHIs);
26281ad6265SDimitry Andric 
26381ad6265SDimitry Andric   // Generate "PHI" in the header block.
26481ad6265SDimitry Andric   auto PHIMIB = BuildMI(*ML->getHeader(), ML->getHeader()->getFirstNonPHI(),
26581ad6265SDimitry Andric                         DebugLoc(), TII->get(TargetOpcode::PHI), PHIDef);
26681ad6265SDimitry Andric   PHIMIB.addReg(Start->getOperand(0).getReg()).addMBB(Preheader);
26781ad6265SDimitry Andric 
26881ad6265SDimitry Andric   Register ADDIDef =
26981ad6265SDimitry Andric       MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
27081ad6265SDimitry Andric                                          : &PPC::GPRC_and_GPRC_NOR0RegClass);
27181ad6265SDimitry Andric   // Generate "addi -1" in the exiting block.
27281ad6265SDimitry Andric   BuildMI(*Exiting, Dec, Dec->getDebugLoc(), TII->get(ADDIOpcode), ADDIDef)
27381ad6265SDimitry Andric       .addReg(PHIDef)
27481ad6265SDimitry Andric       .addImm(-1);
27581ad6265SDimitry Andric 
27681ad6265SDimitry Andric   // Add other inputs for the PHI node.
27781ad6265SDimitry Andric   if (ML->isLoopLatch(Exiting)) {
27881ad6265SDimitry Andric     // There must be only two predecessors for the loop header, one is the
27981ad6265SDimitry Andric     // Preheader and the other one is loop latch Exiting. In hardware loop
28081ad6265SDimitry Andric     // insertion pass, the block containing DecreaseCTRloop must dominate all
28181ad6265SDimitry Andric     // loop latches. So there must be only one latch.
28281ad6265SDimitry Andric     assert(ML->getHeader()->pred_size() == 2 &&
28381ad6265SDimitry Andric            "Loop header predecessor is not right!");
28481ad6265SDimitry Andric     PHIMIB.addReg(ADDIDef).addMBB(Exiting);
28581ad6265SDimitry Andric   } else {
28681ad6265SDimitry Andric     // If the block containing DecreaseCTRloop is not a loop latch, we can use
28781ad6265SDimitry Andric     // ADDIDef as the value for all other blocks for the PHI. In hardware loop
28881ad6265SDimitry Andric     // insertion pass, the block containing DecreaseCTRloop must dominate all
28981ad6265SDimitry Andric     // loop latches.
29081ad6265SDimitry Andric     for (MachineBasicBlock *P : ML->getHeader()->predecessors()) {
29181ad6265SDimitry Andric       if (ML->contains(P)) {
29281ad6265SDimitry Andric         assert(ML->isLoopLatch(P) &&
29381ad6265SDimitry Andric                "Loop's header in-loop predecessor is not loop latch!");
29481ad6265SDimitry Andric         PHIMIB.addReg(ADDIDef).addMBB(P);
2950b57cec5SDimitry Andric       } else
29681ad6265SDimitry Andric         assert(P == Preheader &&
29781ad6265SDimitry Andric                "CTR loop should not be generated for irreducible loop!");
29881ad6265SDimitry Andric     }
29981ad6265SDimitry Andric   }
3000b57cec5SDimitry Andric 
30181ad6265SDimitry Andric   // Generate the compare in the exiting block.
30281ad6265SDimitry Andric   Register CMPDef = MRI->createVirtualRegister(&PPC::CRRCRegClass);
30381ad6265SDimitry Andric   auto CMPMIB =
30481ad6265SDimitry Andric       BuildMI(*Exiting, Dec, Dec->getDebugLoc(), TII->get(CMPOpcode), CMPDef)
30581ad6265SDimitry Andric           .addReg(ADDIDef)
30681ad6265SDimitry Andric           .addImm(0);
3070b57cec5SDimitry Andric 
30881ad6265SDimitry Andric   BuildMI(*Exiting, Dec, Dec->getDebugLoc(), TII->get(TargetOpcode::COPY),
30981ad6265SDimitry Andric           Dec->getOperand(0).getReg())
31081ad6265SDimitry Andric       .addReg(CMPMIB->getOperand(0).getReg(), 0, PPC::sub_gt);
31181ad6265SDimitry Andric 
31281ad6265SDimitry Andric   // Remove the pseudo instructions.
31381ad6265SDimitry Andric   Start->eraseFromParent();
31481ad6265SDimitry Andric   Dec->eraseFromParent();
31581ad6265SDimitry Andric }
31681ad6265SDimitry Andric 
expandCTRLoops(MachineLoop * ML,MachineInstr * Start,MachineInstr * Dec)31781ad6265SDimitry Andric void PPCCTRLoops::expandCTRLoops(MachineLoop *ML, MachineInstr *Start,
31881ad6265SDimitry Andric                                  MachineInstr *Dec) {
31981ad6265SDimitry Andric   bool Is64Bit =
32081ad6265SDimitry Andric       Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
32181ad6265SDimitry Andric 
32281ad6265SDimitry Andric   MachineBasicBlock *Preheader = Start->getParent();
32381ad6265SDimitry Andric   MachineBasicBlock *Exiting = Dec->getParent();
324bdd1243dSDimitry Andric 
325bdd1243dSDimitry Andric   (void)Preheader;
32681ad6265SDimitry Andric   assert((Preheader && Exiting) &&
32781ad6265SDimitry Andric          "Preheader and exiting should exist for CTR loop!");
32881ad6265SDimitry Andric 
32981ad6265SDimitry Andric   assert(Dec->getOperand(1).getImm() == 1 && "Loop decrement must be 1!");
33081ad6265SDimitry Andric 
33181ad6265SDimitry Andric   unsigned BDNZOpcode = Is64Bit ? PPC::BDNZ8 : PPC::BDNZ;
33281ad6265SDimitry Andric   unsigned BDZOpcode = Is64Bit ? PPC::BDZ8 : PPC::BDZ;
33381ad6265SDimitry Andric   auto BrInstr = MRI->use_instr_begin(Dec->getOperand(0).getReg());
33481ad6265SDimitry Andric   assert(MRI->hasOneUse(Dec->getOperand(0).getReg()) &&
33581ad6265SDimitry Andric          "There should be only one user for loop decrement pseudo!");
33681ad6265SDimitry Andric 
33781ad6265SDimitry Andric   unsigned Opcode = 0;
33881ad6265SDimitry Andric   switch (BrInstr->getOpcode()) {
33981ad6265SDimitry Andric   case PPC::BC:
34081ad6265SDimitry Andric     Opcode = BDNZOpcode;
34181ad6265SDimitry Andric     (void) ML;
34281ad6265SDimitry Andric     assert(ML->contains(BrInstr->getOperand(1).getMBB()) &&
34381ad6265SDimitry Andric            "Invalid ctr loop!");
3440b57cec5SDimitry Andric     break;
34581ad6265SDimitry Andric   case PPC::BCn:
34681ad6265SDimitry Andric     Opcode = BDZOpcode;
34781ad6265SDimitry Andric     assert(!ML->contains(BrInstr->getOperand(1).getMBB()) &&
34881ad6265SDimitry Andric            "Invalid ctr loop!");
3490b57cec5SDimitry Andric     break;
35081ad6265SDimitry Andric   default:
35181ad6265SDimitry Andric     llvm_unreachable("Unhandled branch user for DecreaseCTRloop.");
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric 
35481ad6265SDimitry Andric   // Generate "bdnz/bdz" in the exiting block just before the terminator.
35581ad6265SDimitry Andric   BuildMI(*Exiting, &*BrInstr, BrInstr->getDebugLoc(), TII->get(Opcode))
35681ad6265SDimitry Andric       .addMBB(BrInstr->getOperand(1).getMBB());
35781ad6265SDimitry Andric 
35881ad6265SDimitry Andric   // Remove the pseudo instructions.
35981ad6265SDimitry Andric   BrInstr->eraseFromParent();
36081ad6265SDimitry Andric   Dec->eraseFromParent();
3610b57cec5SDimitry Andric }
362