48#define DEBUG_TYPE "ppc-ctrloops"
50STATISTIC(NumCTRLoops,
"Number of CTR loops generated");
51STATISTIC(NumNormalLoops,
"Number of normal compare + branch loops generated");
60 void getAnalysisUsage(AnalysisUsage &AU)
const override {
65 bool runOnMachineFunction(MachineFunction &MF)
override;
68 const PPCInstrInfo *TII =
nullptr;
69 MachineRegisterInfo *MRI =
nullptr;
71 bool processLoop(MachineLoop *
ML);
72 bool isCTRClobber(MachineInstr *
MI,
bool CheckReads)
const;
73 void expandNormalLoops(MachineLoop *
ML, MachineInstr *Start,
75 void expandCTRLoops(MachineLoop *
ML, MachineInstr *Start, MachineInstr *Dec);
79char PPCCTRLoops::ID = 0;
92 auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
96 for (
auto *
ML : MLI) {
97 if (
ML->isOutermost())
102 for (
const MachineBasicBlock &BB : MF) {
103 for (
const MachineInstr &
I : BB)
104 assert((
I.getOpcode() != PPC::DecreaseCTRloop &&
105 I.getOpcode() != PPC::DecreaseCTR8loop) &&
106 "CTR loop pseudo is not expanded!");
113bool PPCCTRLoops::isCTRClobber(MachineInstr *
MI,
bool CheckReads)
const {
120 return MI->definesRegister(PPC::CTR,
nullptr) ||
121 MI->definesRegister(PPC::CTR8,
nullptr);
124 if (
MI->modifiesRegister(PPC::CTR,
nullptr) ||
125 MI->modifiesRegister(PPC::CTR8,
nullptr))
128 if (
MI->getDesc().isCall())
133 if (
MI->readsRegister(PPC::CTR,
nullptr) ||
134 MI->readsRegister(PPC::CTR8,
nullptr))
140bool PPCCTRLoops::processLoop(MachineLoop *
ML) {
144 for (MachineLoop *
I : *
ML)
152 auto IsLoopStart = [](MachineInstr &
MI) {
153 return MI.getOpcode() == PPC::MTCTRloop ||
154 MI.getOpcode() == PPC::MTCTR8loop;
157 auto SearchForStart =
158 [&IsLoopStart](MachineBasicBlock *
MBB) -> MachineInstr * {
159 for (
auto &
MI : *
MBB) {
166 MachineInstr *
Start =
nullptr;
167 MachineInstr *Dec =
nullptr;
168 bool InvalidCTRLoop =
false;
170 MachineBasicBlock *Preheader =
ML->getLoopPreheader();
176 Start = SearchForStart(Preheader);
183 InvalidCTRLoop =
true;
188 std::next(
Start->getReverseIterator());
192 if (isCTRClobber(&*
I,
false)) {
193 InvalidCTRLoop =
true;
201 if (isCTRClobber(&*
I,
true)) {
202 InvalidCTRLoop =
true;
209 for (
auto &
MI : *
MBB) {
210 if (
MI.getOpcode() == PPC::DecreaseCTRloop ||
211 MI.getOpcode() == PPC::DecreaseCTR8loop)
213 else if (!InvalidCTRLoop)
215 InvalidCTRLoop |= isCTRClobber(&
MI,
true);
217 if (Dec && InvalidCTRLoop)
221 assert(Dec &&
"CTR loop is not complete!");
223 if (InvalidCTRLoop) {
224 expandNormalLoops(
ML, Start, Dec);
228 expandCTRLoops(
ML, Start, Dec);
234void PPCCTRLoops::expandNormalLoops(MachineLoop *
ML, MachineInstr *Start,
237 Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
239 MachineBasicBlock *Preheader =
Start->getParent();
240 MachineBasicBlock *Exiting = Dec->
getParent();
241 assert((Preheader && Exiting) &&
242 "Preheader and exiting should exist for CTR loop!");
245 "Loop decrement stride must be 1");
247 unsigned ADDIOpcode = Is64Bit ? PPC::ADDI8 : PPC::ADDI;
248 unsigned CMPOpcode = Is64Bit ? PPC::CMPLDI : PPC::CMPLWI;
251 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
252 : &PPC::GPRC_and_GPRC_NOR0RegClass);
254 Start->getParent()->getParent()->getProperties().resetNoPHIs();
257 auto PHIMIB =
BuildMI(*
ML->getHeader(),
ML->getHeader()->getFirstNonPHI(),
259 PHIMIB.addReg(
Start->getOperand(0).getReg()).addMBB(Preheader);
262 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
263 : &PPC::GPRC_and_GPRC_NOR0RegClass);
270 if (
ML->isLoopLatch(Exiting)) {
275 assert(
ML->getHeader()->pred_size() == 2 &&
276 "Loop header predecessor is not right!");
277 PHIMIB.addReg(ADDIDef).addMBB(Exiting);
283 for (MachineBasicBlock *
P :
ML->getHeader()->predecessors()) {
284 if (
ML->contains(
P)) {
286 "Loop's header in-loop predecessor is not loop latch!");
287 PHIMIB.addReg(ADDIDef).addMBB(
P);
290 "CTR loop should not be generated for irreducible loop!");
295 Register CMPDef =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
303 .
addReg(CMPMIB->getOperand(0).getReg(), 0, PPC::sub_gt);
306 Start->eraseFromParent();
310void PPCCTRLoops::expandCTRLoops(MachineLoop *
ML, MachineInstr *Start,
313 Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
315 MachineBasicBlock *Preheader =
Start->getParent();
316 MachineBasicBlock *Exiting = Dec->
getParent();
319 assert((Preheader && Exiting) &&
320 "Preheader and exiting should exist for CTR loop!");
324 unsigned BDNZOpcode = Is64Bit ? PPC::BDNZ8 : PPC::BDNZ;
325 unsigned BDZOpcode = Is64Bit ? PPC::BDZ8 : PPC::BDZ;
328 "There should be only one user for loop decrement pseudo!");
331 switch (BrInstr->getOpcode()) {
335 assert(
ML->contains(BrInstr->getOperand(1).getMBB()) &&
336 "Invalid ctr loop!");
340 assert(!
ML->contains(BrInstr->getOperand(1).getMBB()) &&
341 "Invalid ctr loop!");
348 BuildMI(*Exiting, &*BrInstr, BrInstr->getDebugLoc(),
TII->get(Opcode))
349 .
addMBB(BrInstr->getOperand(1).getMBB());
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
AnalysisUsage & addRequired()
FunctionPass class - This class is used to implement most global optimizations.
reverse_instr_iterator instr_rend()
Instructions::iterator instr_iterator
instr_iterator instr_end()
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
Instructions::reverse_iterator reverse_instr_iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Register getReg() const
getReg - Returns the register number.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
FunctionPass * createPPCCTRLoopsPass()
auto reverse(ContainerTy &&C)