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;
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;
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);
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!");
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());
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)
static bool processLoop(Loop &L, const AArch64Subtarget &ST, DataLayout DL)
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.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Register getReg() const
getReg - Returns the register number.
use_instr_iterator use_instr_begin(Register RegNo) const
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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)