49#define DEBUG_TYPE "ppc-ctrloops"
51STATISTIC(NumCTRLoops,
"Number of CTR loops generated");
52STATISTIC(NumNormalLoops,
"Number of normal compare + branch loops generated");
61 void getAnalysisUsage(AnalysisUsage &AU)
const override {
66 bool runOnMachineFunction(MachineFunction &MF)
override;
69 const PPCInstrInfo *TII =
nullptr;
70 MachineRegisterInfo *MRI =
nullptr;
72 bool processLoop(MachineLoop *
ML);
73 bool isCTRClobber(MachineInstr *
MI,
bool CheckReads)
const;
74 void expandNormalLoops(MachineLoop *
ML, MachineInstr *Start,
76 void expandCTRLoops(MachineLoop *
ML, MachineInstr *Start, MachineInstr *Dec);
80char PPCCTRLoops::ID = 0;
93 auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
97 for (
auto *
ML : MLI) {
98 if (
ML->isOutermost())
103 for (
const MachineBasicBlock &BB : MF) {
104 for (
const MachineInstr &
I : BB)
105 assert((
I.getOpcode() != PPC::DecreaseCTRloop &&
106 I.getOpcode() != PPC::DecreaseCTR8loop) &&
107 "CTR loop pseudo is not expanded!");
114bool PPCCTRLoops::isCTRClobber(MachineInstr *
MI,
bool CheckReads)
const {
121 return MI->definesRegister(PPC::CTR,
nullptr) ||
122 MI->definesRegister(PPC::CTR8,
nullptr);
125 if (
MI->modifiesRegister(PPC::CTR,
nullptr) ||
126 MI->modifiesRegister(PPC::CTR8,
nullptr))
129 if (
MI->getDesc().isCall())
134 if (
MI->readsRegister(PPC::CTR,
nullptr) ||
135 MI->readsRegister(PPC::CTR8,
nullptr))
141bool PPCCTRLoops::processLoop(MachineLoop *
ML) {
145 for (MachineLoop *
I : *
ML)
153 auto IsLoopStart = [](MachineInstr &
MI) {
154 return MI.getOpcode() == PPC::MTCTRloop ||
155 MI.getOpcode() == PPC::MTCTR8loop;
158 auto SearchForStart =
159 [&IsLoopStart](MachineBasicBlock *
MBB) -> MachineInstr * {
160 for (
auto &
MI : *
MBB) {
167 MachineInstr *
Start =
nullptr;
168 MachineInstr *Dec =
nullptr;
169 bool InvalidCTRLoop =
false;
171 MachineBasicBlock *Preheader =
ML->getLoopPreheader();
177 Start = SearchForStart(Preheader);
184 InvalidCTRLoop =
true;
189 std::next(
Start->getReverseIterator());
193 if (isCTRClobber(&*
I,
false)) {
194 InvalidCTRLoop =
true;
202 if (isCTRClobber(&*
I,
true)) {
203 InvalidCTRLoop =
true;
210 for (
auto &
MI : *
MBB) {
211 if (
MI.getOpcode() == PPC::DecreaseCTRloop ||
212 MI.getOpcode() == PPC::DecreaseCTR8loop)
214 else if (!InvalidCTRLoop)
216 InvalidCTRLoop |= isCTRClobber(&
MI,
true);
218 if (Dec && InvalidCTRLoop)
222 assert(Dec &&
"CTR loop is not complete!");
224 if (InvalidCTRLoop) {
225 expandNormalLoops(
ML, Start, Dec);
229 expandCTRLoops(
ML, Start, Dec);
235void PPCCTRLoops::expandNormalLoops(MachineLoop *
ML, MachineInstr *Start,
238 Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
240 MachineBasicBlock *Preheader =
Start->getParent();
241 MachineBasicBlock *Exiting = Dec->
getParent();
242 assert((Preheader && Exiting) &&
243 "Preheader and exiting should exist for CTR loop!");
246 "Loop decrement stride must be 1");
248 unsigned ADDIOpcode = Is64Bit ? PPC::ADDI8 : PPC::ADDI;
249 unsigned CMPOpcode = Is64Bit ? PPC::CMPLDI : PPC::CMPLWI;
252 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
253 : &PPC::GPRC_and_GPRC_NOR0RegClass);
255 Start->getParent()->getParent()->getProperties().resetNoPHIs();
258 auto PHIMIB =
BuildMI(*
ML->getHeader(),
ML->getHeader()->getFirstNonPHI(),
260 PHIMIB.addReg(
Start->getOperand(0).getReg()).addMBB(Preheader);
263 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
264 : &PPC::GPRC_and_GPRC_NOR0RegClass);
271 if (
ML->isLoopLatch(Exiting)) {
276 assert(
ML->getHeader()->pred_size() == 2 &&
277 "Loop header predecessor is not right!");
278 PHIMIB.addReg(ADDIDef).addMBB(Exiting);
284 for (MachineBasicBlock *
P :
ML->getHeader()->predecessors()) {
285 if (
ML->contains(
P)) {
287 "Loop's header in-loop predecessor is not loop latch!");
288 PHIMIB.addReg(ADDIDef).addMBB(
P);
291 "CTR loop should not be generated for irreducible loop!");
296 Register CMPDef =
MRI->createVirtualRegister(&PPC::CRRCRegClass);
304 .
addReg(CMPMIB->getOperand(0).getReg(), {}, PPC::sub_gt);
307 Start->eraseFromParent();
311void PPCCTRLoops::expandCTRLoops(MachineLoop *
ML, MachineInstr *Start,
314 Start->getParent()->getParent()->getSubtarget<PPCSubtarget>().isPPC64();
316 MachineBasicBlock *Preheader =
Start->getParent();
317 MachineBasicBlock *Exiting = Dec->
getParent();
320 assert((Preheader && Exiting) &&
321 "Preheader and exiting should exist for CTR loop!");
325 unsigned BDNZOpcode = Is64Bit ? PPC::BDNZ8 : PPC::BDNZ;
326 unsigned BDZOpcode = Is64Bit ? PPC::BDZ8 : PPC::BDZ;
329 "There should be only one user for loop decrement pseudo!");
332 switch (BrInstr->getOpcode()) {
336 assert(
ML->contains(BrInstr->getOperand(1).getMBB()) &&
337 "Invalid ctr loop!");
341 assert(!
ML->contains(BrInstr->getOperand(1).getMBB()) &&
342 "Invalid ctr loop!");
349 BuildMI(*Exiting, &*BrInstr, BrInstr->getDebugLoc(),
TII->get(Opcode))
350 .
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate 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)