123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- //===-- PPCCTRLoops.cpp - Generate CTR loops ------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This pass generates machine instructions for the CTR loops related pseudos:
- // 1: MTCTRloop/DecreaseCTRloop
- // 2: MTCTR8loop/DecreaseCTR8loop
- //
- // If a CTR loop can be generated:
- // 1: MTCTRloop/MTCTR8loop will be converted to "mtctr"
- // 2: DecreaseCTRloop/DecreaseCTR8loop will be converted to "bdnz/bdz" and
- // its user branch instruction can be deleted.
- //
- // If a CTR loop can not be generated due to clobber of CTR:
- // 1: MTCTRloop/MTCTR8loop can be deleted.
- // 2: DecreaseCTRloop/DecreaseCTR8loop will be converted to "addi -1" and
- // a "cmplwi/cmpldi".
- //
- // This pass runs just before register allocation, because we don't want
- // register allocator to allocate register for DecreaseCTRloop if a CTR can be
- // generated or if a CTR loop can not be generated, we don't have any condition
- // register for the new added "cmplwi/cmpldi".
- //
- //===----------------------------------------------------------------------===//
- #include "PPC.h"
- #include "PPCInstrInfo.h"
- #include "PPCSubtarget.h"
- #include "llvm/ADT/Statistic.h"
- #include "llvm/CodeGen/MachineBasicBlock.h"
- #include "llvm/CodeGen/MachineFunction.h"
- #include "llvm/CodeGen/MachineFunctionPass.h"
- #include "llvm/CodeGen/MachineInstr.h"
- #include "llvm/CodeGen/MachineLoopInfo.h"
- #include "llvm/CodeGen/MachineOperand.h"
- #include "llvm/CodeGen/MachineRegisterInfo.h"
- #include "llvm/CodeGen/Register.h"
- #include "llvm/InitializePasses.h"
- #include "llvm/Pass.h"
- #include "llvm/PassRegistry.h"
- #include "llvm/Support/CodeGen.h"
- #include "llvm/Support/Debug.h"
- #include "llvm/Support/ErrorHandling.h"
- #include <cassert>
- using namespace llvm;
- #define DEBUG_TYPE "ppc-ctrloops"
- STATISTIC(NumCTRLoops, "Number of CTR loops generated");
- STATISTIC(NumNormalLoops, "Number of normal compare + branch loops generated");
- namespace {
- class PPCCTRLoops : public MachineFunctionPass {
- public:
- static char ID;
- PPCCTRLoops() : MachineFunctionPass(ID) {
- initializePPCCTRLoopsPass(*PassRegistry::getPassRegistry());
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<MachineLoopInfo>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
- bool runOnMachineFunction(MachineFunction &MF) override;
- private:
- const PPCInstrInfo *TII = nullptr;
- MachineRegisterInfo *MRI = nullptr;
- bool processLoop(MachineLoop *ML);
- bool isCTRClobber(MachineInstr *MI, bool CheckReads) const;
- void expandNormalLoops(MachineLoop *ML, MachineInstr *Start,
- MachineInstr *Dec);
- void expandCTRLoops(MachineLoop *ML, MachineInstr *Start, MachineInstr *Dec);
- };
- } // namespace
- char PPCCTRLoops::ID = 0;
- INITIALIZE_PASS_BEGIN(PPCCTRLoops, DEBUG_TYPE, "PowerPC CTR loops generation",
- false, false)
- INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
- INITIALIZE_PASS_END(PPCCTRLoops, DEBUG_TYPE, "PowerPC CTR loops generation",
- false, false)
- FunctionPass *llvm::createPPCCTRLoopsPass() { return new PPCCTRLoops(); }
- bool PPCCTRLoops::runOnMachineFunction(MachineFunction &MF) {
- bool Changed = false;
- auto &MLI = getAnalysis<MachineLoopInfo>();
- TII = static_cast<const PPCInstrInfo *>(MF.getSubtarget().getInstrInfo());
- MRI = &MF.getRegInfo();
- for (auto *ML : MLI) {
- if (ML->isOutermost())
- Changed |= processLoop(ML);
- }
- #ifndef NDEBUG
- for (const MachineBasicBlock &BB : MF) {
- for (const MachineInstr &I : BB)
- assert((I.getOpcode() != PPC::DecreaseCTRloop &&
- I.getOpcode() != PPC::DecreaseCTR8loop) &&
- "CTR loop pseudo is not expanded!");
- }
- #endif
- return Changed;
- }
- bool PPCCTRLoops::isCTRClobber(MachineInstr *MI, bool CheckReads) const {
- if (!CheckReads) {
- // If we are only checking for defs, that is we are going to find
- // definitions before MTCTRloop, for this case:
- // CTR defination inside the callee of a call instruction will not impact
- // the defination of MTCTRloop, so we can use definesRegister() for the
- // check, no need to check the regmask.
- return MI->definesRegister(PPC::CTR) || MI->definesRegister(PPC::CTR8);
- }
- if (MI->modifiesRegister(PPC::CTR) || MI->modifiesRegister(PPC::CTR8))
- return true;
- if (MI->getDesc().isCall())
- return true;
- // We define the CTR in the loop preheader, so if there is any CTR reader in
- // the loop, we also can not use CTR loop form.
- if (MI->readsRegister(PPC::CTR) || MI->readsRegister(PPC::CTR8))
- return true;
- return false;
- }
- bool PPCCTRLoops::processLoop(MachineLoop *ML) {
- bool Changed = false;
- // Align with HardwareLoop pass, process inner loops first.
- for (MachineLoop *I : *ML)
- Changed |= processLoop(I);
- // If any inner loop is changed, outter loop must be without hardware loop
- // intrinsics.
- if (Changed)
- return true;
- auto IsLoopStart = [](MachineInstr &MI) {
- return MI.getOpcode() == PPC::MTCTRloop ||
- MI.getOpcode() == PPC::MTCTR8loop;
- };
- auto SearchForStart =
- [&IsLoopStart](MachineBasicBlock *MBB) -> MachineInstr * {
- for (auto &MI : *MBB) {
- if (IsLoopStart(MI))
- return &MI;
- }
- return nullptr;
- };
- MachineInstr *Start = nullptr;
- MachineInstr *Dec = nullptr;
- bool InvalidCTRLoop = false;
- MachineBasicBlock *Preheader = ML->getLoopPreheader();
- // If there is no preheader for this loop, there must be no MTCTRloop
- // either.
- if (!Preheader)
- return false;
- Start = SearchForStart(Preheader);
- // This is not a CTR loop candidate.
- if (!Start)
- return false;
- // If CTR is live to the preheader, we can not redefine the CTR register.
- if (Preheader->isLiveIn(PPC::CTR) || Preheader->isLiveIn(PPC::CTR8))
- InvalidCTRLoop = true;
- // Make sure there is also no CTR clobber in the block preheader between the
- // begin and MTCTR.
- for (MachineBasicBlock::reverse_instr_iterator I =
- std::next(Start->getReverseIterator());
- I != Preheader->instr_rend(); ++I)
- // Only check the definitions of CTR. If there is non-dead definition for
- // the CTR, we conservatively don't generate a CTR loop.
- if (isCTRClobber(&*I, /* CheckReads */ false)) {
- InvalidCTRLoop = true;
- break;
- }
- // Make sure there is also no CTR clobber/user in the block preheader between
- // MTCTR and the end.
- for (MachineBasicBlock::instr_iterator I = std::next(Start->getIterator());
- I != Preheader->instr_end(); ++I)
- if (isCTRClobber(&*I, /* CheckReads */ true)) {
- InvalidCTRLoop = true;
- break;
- }
- // Find the CTR loop components and decide whether or not to fall back to a
- // normal loop.
- for (auto *MBB : reverse(ML->getBlocks())) {
- for (auto &MI : *MBB) {
- if (MI.getOpcode() == PPC::DecreaseCTRloop ||
- MI.getOpcode() == PPC::DecreaseCTR8loop)
- Dec = &MI;
- else if (!InvalidCTRLoop)
- // If any instruction clobber CTR, then we can not generate a CTR loop.
- InvalidCTRLoop |= isCTRClobber(&MI, /* CheckReads */ true);
- }
- if (Dec && InvalidCTRLoop)
- break;
- }
- assert(Dec && "CTR loop is not complete!");
- if (InvalidCTRLoop) {
- expandNormalLoops(ML, Start, Dec);
- ++NumNormalLoops;
- }
- else {
- expandCTRLoops(ML, Start, Dec);
- ++NumCTRLoops;
- }
- return true;
- }
- void PPCCTRLoops::expandNormalLoops(MachineLoop *ML, MachineInstr *Start,
- MachineInstr *Dec) {
- bool Is64Bit =
- Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
- MachineBasicBlock *Preheader = Start->getParent();
- MachineBasicBlock *Exiting = Dec->getParent();
- assert((Preheader && Exiting) &&
- "Preheader and exiting should exist for CTR loop!");
- assert(Dec->getOperand(1).getImm() == 1 &&
- "Loop decrement stride must be 1");
- unsigned ADDIOpcode = Is64Bit ? PPC::ADDI8 : PPC::ADDI;
- unsigned CMPOpcode = Is64Bit ? PPC::CMPLDI : PPC::CMPLWI;
- Register PHIDef =
- MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
- : &PPC::GPRC_and_GPRC_NOR0RegClass);
- Start->getParent()->getParent()->getProperties().reset(
- MachineFunctionProperties::Property::NoPHIs);
- // Generate "PHI" in the header block.
- auto PHIMIB = BuildMI(*ML->getHeader(), ML->getHeader()->getFirstNonPHI(),
- DebugLoc(), TII->get(TargetOpcode::PHI), PHIDef);
- PHIMIB.addReg(Start->getOperand(0).getReg()).addMBB(Preheader);
- Register ADDIDef =
- MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
- : &PPC::GPRC_and_GPRC_NOR0RegClass);
- // Generate "addi -1" in the exiting block.
- BuildMI(*Exiting, Dec, Dec->getDebugLoc(), TII->get(ADDIOpcode), ADDIDef)
- .addReg(PHIDef)
- .addImm(-1);
- // Add other inputs for the PHI node.
- if (ML->isLoopLatch(Exiting)) {
- // There must be only two predecessors for the loop header, one is the
- // Preheader and the other one is loop latch Exiting. In hardware loop
- // insertion pass, the block containing DecreaseCTRloop must dominate all
- // loop latches. So there must be only one latch.
- assert(ML->getHeader()->pred_size() == 2 &&
- "Loop header predecessor is not right!");
- PHIMIB.addReg(ADDIDef).addMBB(Exiting);
- } else {
- // If the block containing DecreaseCTRloop is not a loop latch, we can use
- // ADDIDef as the value for all other blocks for the PHI. In hardware loop
- // insertion pass, the block containing DecreaseCTRloop must dominate all
- // loop latches.
- for (MachineBasicBlock *P : ML->getHeader()->predecessors()) {
- if (ML->contains(P)) {
- assert(ML->isLoopLatch(P) &&
- "Loop's header in-loop predecessor is not loop latch!");
- PHIMIB.addReg(ADDIDef).addMBB(P);
- } else
- assert(P == Preheader &&
- "CTR loop should not be generated for irreducible loop!");
- }
- }
- // Generate the compare in the exiting block.
- Register CMPDef = MRI->createVirtualRegister(&PPC::CRRCRegClass);
- auto CMPMIB =
- BuildMI(*Exiting, Dec, Dec->getDebugLoc(), TII->get(CMPOpcode), CMPDef)
- .addReg(ADDIDef)
- .addImm(0);
- BuildMI(*Exiting, Dec, Dec->getDebugLoc(), TII->get(TargetOpcode::COPY),
- Dec->getOperand(0).getReg())
- .addReg(CMPMIB->getOperand(0).getReg(), 0, PPC::sub_gt);
- // Remove the pseudo instructions.
- Start->eraseFromParent();
- Dec->eraseFromParent();
- }
- void PPCCTRLoops::expandCTRLoops(MachineLoop *ML, MachineInstr *Start,
- MachineInstr *Dec) {
- bool Is64Bit =
- Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
- MachineBasicBlock *Preheader = Start->getParent();
- MachineBasicBlock *Exiting = Dec->getParent();
- (void)Preheader;
- assert((Preheader && Exiting) &&
- "Preheader and exiting should exist for CTR loop!");
- assert(Dec->getOperand(1).getImm() == 1 && "Loop decrement must be 1!");
- unsigned BDNZOpcode = Is64Bit ? PPC::BDNZ8 : PPC::BDNZ;
- unsigned BDZOpcode = Is64Bit ? PPC::BDZ8 : PPC::BDZ;
- auto BrInstr = MRI->use_instr_begin(Dec->getOperand(0).getReg());
- assert(MRI->hasOneUse(Dec->getOperand(0).getReg()) &&
- "There should be only one user for loop decrement pseudo!");
- unsigned Opcode = 0;
- switch (BrInstr->getOpcode()) {
- case PPC::BC:
- Opcode = BDNZOpcode;
- (void) ML;
- assert(ML->contains(BrInstr->getOperand(1).getMBB()) &&
- "Invalid ctr loop!");
- break;
- case PPC::BCn:
- Opcode = BDZOpcode;
- assert(!ML->contains(BrInstr->getOperand(1).getMBB()) &&
- "Invalid ctr loop!");
- break;
- default:
- llvm_unreachable("Unhandled branch user for DecreaseCTRloop.");
- }
- // Generate "bdnz/bdz" in the exiting block just before the terminator.
- BuildMI(*Exiting, &*BrInstr, BrInstr->getDebugLoc(), TII->get(Opcode))
- .addMBB(BrInstr->getOperand(1).getMBB());
- // Remove the pseudo instructions.
- BrInstr->eraseFromParent();
- Dec->eraseFromParent();
- }
|