LLVM: lib/Target/PowerPC/PPCCTRLoops.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
44#include
45
46using namespace llvm;
47
48#define DEBUG_TYPE "ppc-ctrloops"
49
50STATISTIC(NumCTRLoops, "Number of CTR loops generated");
51STATISTIC(NumNormalLoops, "Number of normal compare + branch loops generated");
52
53namespace {
55public:
56 static char ID;
57
59
60 void getAnalysisUsage(AnalysisUsage &AU) const override {
61 AU.addRequired();
63 }
64
65 bool runOnMachineFunction(MachineFunction &MF) override;
66
67private:
68 const PPCInstrInfo *TII = nullptr;
69 MachineRegisterInfo *MRI = nullptr;
70
71 bool processLoop(MachineLoop *ML);
72 bool isCTRClobber(MachineInstr *MI, bool CheckReads) const;
73 void expandNormalLoops(MachineLoop *ML, MachineInstr *Start,
74 MachineInstr *Dec);
75 void expandCTRLoops(MachineLoop *ML, MachineInstr *Start, MachineInstr *Dec);
76};
77}
78
79char PPCCTRLoops::ID = 0;
80
82 false, false)
86
88
89bool PPCCTRLoops::runOnMachineFunction(MachineFunction &MF) {
91
92 auto &MLI = getAnalysis().getLI();
95
96 for (auto *ML : MLI) {
97 if (ML->isOutermost())
99 }
100
101#ifndef NDEBUG
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!");
107 }
108#endif
109
111}
112
113bool PPCCTRLoops::isCTRClobber(MachineInstr *MI, bool CheckReads) const {
114 if (!CheckReads) {
115
116
117
118
119
120 return MI->definesRegister(PPC::CTR, nullptr) ||
121 MI->definesRegister(PPC::CTR8, nullptr);
122 }
123
124 if (MI->modifiesRegister(PPC::CTR, nullptr) ||
125 MI->modifiesRegister(PPC::CTR8, nullptr))
126 return true;
127
128 if (MI->getDesc().isCall())
129 return true;
130
131
132
133 if (MI->readsRegister(PPC::CTR, nullptr) ||
134 MI->readsRegister(PPC::CTR8, nullptr))
135 return true;
136
137 return false;
138}
139
140bool PPCCTRLoops::processLoop(MachineLoop *ML) {
142
143
144 for (MachineLoop *I : *ML)
146
147
148
150 return true;
151
152 auto IsLoopStart = [](MachineInstr &MI) {
153 return MI.getOpcode() == PPC::MTCTRloop ||
154 MI.getOpcode() == PPC::MTCTR8loop;
155 };
156
157 auto SearchForStart =
158 [&IsLoopStart](MachineBasicBlock *MBB) -> MachineInstr * {
160 if (IsLoopStart(MI))
161 return &MI;
162 }
163 return nullptr;
164 };
165
166 MachineInstr *Start = nullptr;
167 MachineInstr *Dec = nullptr;
168 bool InvalidCTRLoop = false;
169
170 MachineBasicBlock *Preheader = ML->getLoopPreheader();
171
172
173 if (!Preheader)
174 return false;
175
176 Start = SearchForStart(Preheader);
177
178 if (!Start)
179 return false;
180
181
182 if (Preheader->isLiveIn(PPC::CTR) || Preheader->isLiveIn(PPC::CTR8))
183 InvalidCTRLoop = true;
184
185
186
188 std::next(Start->getReverseIterator());
190
191
192 if (isCTRClobber(&*I, false)) {
193 InvalidCTRLoop = true;
194 break;
195 }
196
197
198
201 if (isCTRClobber(&*I, true)) {
202 InvalidCTRLoop = true;
203 break;
204 }
205
206
207
210 if (MI.getOpcode() == PPC::DecreaseCTRloop ||
211 MI.getOpcode() == PPC::DecreaseCTR8loop)
212 Dec = &MI;
213 else if (!InvalidCTRLoop)
214
215 InvalidCTRLoop |= isCTRClobber(&MI, true);
216 }
217 if (Dec && InvalidCTRLoop)
218 break;
219 }
220
221 assert(Dec && "CTR loop is not complete!");
222
223 if (InvalidCTRLoop) {
224 expandNormalLoops(ML, Start, Dec);
225 ++NumNormalLoops;
226 }
227 else {
228 expandCTRLoops(ML, Start, Dec);
229 ++NumCTRLoops;
230 }
231 return true;
232}
233
234void PPCCTRLoops::expandNormalLoops(MachineLoop *ML, MachineInstr *Start,
235 MachineInstr *Dec) {
236 bool Is64Bit =
237 Start->getParent()->getParent()->getSubtarget().isPPC64();
238
239 MachineBasicBlock *Preheader = Start->getParent();
240 MachineBasicBlock *Exiting = Dec->getParent();
241 assert((Preheader && Exiting) &&
242 "Preheader and exiting should exist for CTR loop!");
243
245 "Loop decrement stride must be 1");
246
247 unsigned ADDIOpcode = Is64Bit ? PPC::ADDI8 : PPC::ADDI;
248 unsigned CMPOpcode = Is64Bit ? PPC::CMPLDI : PPC::CMPLWI;
249
251 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
252 : &PPC::GPRC_and_GPRC_NOR0RegClass);
253
254 Start->getParent()->getParent()->getProperties().resetNoPHIs();
255
256
257 auto PHIMIB = BuildMI(*ML->getHeader(), ML->getHeader()->getFirstNonPHI(),
259 PHIMIB.addReg(Start->getOperand(0).getReg()).addMBB(Preheader);
260
262 MRI->createVirtualRegister(Is64Bit ? &PPC::G8RC_and_G8RC_NOX0RegClass
263 : &PPC::GPRC_and_GPRC_NOR0RegClass);
264
268
269
270 if (ML->isLoopLatch(Exiting)) {
271
272
273
274
275 assert(ML->getHeader()->pred_size() == 2 &&
276 "Loop header predecessor is not right!");
277 PHIMIB.addReg(ADDIDef).addMBB(Exiting);
278 } else {
279
280
281
282
283 for (MachineBasicBlock *P : ML->getHeader()->predecessors()) {
286 "Loop's header in-loop predecessor is not loop latch!");
287 PHIMIB.addReg(ADDIDef).addMBB(P);
288 } else
290 "CTR loop should not be generated for irreducible loop!");
291 }
292 }
293
294
295 Register CMPDef = MRI->createVirtualRegister(&PPC::CRRCRegClass);
296 auto CMPMIB =
300
303 .addReg(CMPMIB->getOperand(0).getReg(), 0, PPC::sub_gt);
304
305
306 Start->eraseFromParent();
308}
309
310void PPCCTRLoops::expandCTRLoops(MachineLoop *ML, MachineInstr *Start,
311 MachineInstr *Dec) {
312 bool Is64Bit =
313 Start->getParent()->getParent()->getSubtarget().isPPC64();
314
315 MachineBasicBlock *Preheader = Start->getParent();
316 MachineBasicBlock *Exiting = Dec->getParent();
317
318 (void)Preheader;
319 assert((Preheader && Exiting) &&
320 "Preheader and exiting should exist for CTR loop!");
321
323
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!");
329
330 unsigned Opcode = 0;
331 switch (BrInstr->getOpcode()) {
332 case PPC::BC:
333 Opcode = BDNZOpcode;
334 (void) ML;
335 assert(ML->contains(BrInstr->getOperand(1).getMBB()) &&
336 "Invalid ctr loop!");
337 break;
338 case PPC::BCn:
339 Opcode = BDZOpcode;
340 assert(->contains(BrInstr->getOperand(1).getMBB()) &&
341 "Invalid ctr loop!");
342 break;
343 default:
344 llvm_unreachable("Unhandled branch user for DecreaseCTRloop.");
345 }
346
347
348 BuildMI(*Exiting, &*BrInstr, BrInstr->getDebugLoc(), TII->get(Opcode))
349 .addMBB(BrInstr->getOperand(1).getMBB());
350
351
354}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & 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.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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()
Definition PPCCTRLoops.cpp:87
auto reverse(ContainerTy &&C)