@@ -194,8 +194,10 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
194
194
MachineInstr *LII = nullptr ; // LOOPINIT instruction
195
195
MachineInstr *LEI = nullptr ; // LOOPEND instruction
196
196
MachineBasicBlock *LEMBB = nullptr ;
197
- MachineBasicBlock *PH = L->getLoopPreheader ();
197
+ MachineBasicBlock *LH = L->getHeader ();
198
198
MachineBasicBlock *LastMBB = L->getLoopLatch ();
199
+ std::vector<MachineInstr *> LoopInitInsts;
200
+ std::map<MachineBasicBlock *, MachineInstr *> LoopInitMap;
199
201
200
202
// Try to find LOOPEND instruction in the loop latch
201
203
for (auto MBI = L->block_begin (), MBIE = L->block_end (); MBI != MBIE; ++MBI) {
@@ -207,40 +209,56 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
207
209
LEI = LMI;
208
210
LEMBB = *MBI;
209
211
}
212
+ // Collect LOOPINIT instructions inside the loop
213
+ if (LMI->getOpcode () == Xtensa::LOOPINIT) {
214
+ LoopInitInsts.push_back (LMI);
215
+ MachineBasicBlock *SB = LMI->getParent ();
216
+ while (!SB->isSuccessor (LH)) {
217
+ for (auto SBI : SB->successors ()) {
218
+ if (!L->contains (SBI))
219
+ continue ;
220
+ SB = SBI;
221
+ break ;
222
+ }
223
+ if (!L->contains (SB))
224
+ llvm_unreachable (" Wrong hardware loop" );
225
+ }
226
+ LoopInitMap[SB] = LMI;
227
+ }
210
228
}
211
229
VisitedMBBs.insert (*MBI);
212
230
}
213
231
214
232
if (LEI != nullptr ) {
215
- MachineBasicBlock *LH = L->getHeader ();
216
233
MachineBasicBlock::iterator LHI = LH->getFirstNonPHI ();
217
-
218
- if (!PH) {
219
- llvm_unreachable (" Hardware loop predecessor not found" );
220
- return false ;
221
- }
222
-
223
- MachineBasicBlock *LIMBB = PH;
224
-
225
- // Try to find LOOPINIT instruction in predecessors chain
226
- while ((LII == nullptr ) && (LIMBB != nullptr ) &&
227
- ((L->getParentLoop () == nullptr ) ||
228
- (L->getParentLoop ()->contains (LIMBB)))) {
229
- for (instr_iterator I = LIMBB->instr_begin (), E = LIMBB->instr_end ();
230
- I != E; ++I) {
231
- MachineInstr *MI = &*I;
232
- if (MI->getOpcode () == Xtensa::LOOPINIT) {
233
- LII = MI;
234
- break ;
234
+ MachineBasicBlock *LIMBB = nullptr ;
235
+
236
+ // Collect LOOPINIT instructions in predecessors from outter loop
237
+ for (auto PBI : LH->predecessors ()) {
238
+ if (L->contains (PBI))
239
+ continue ;
240
+ LIMBB = PBI;
241
+ LII = nullptr ;
242
+ // Try to find LOOPINIT instructions in predecessor
243
+ while ((LII == nullptr ) && (LIMBB != nullptr ) &&
244
+ ((L->getParentLoop () == nullptr ) ||
245
+ (L->getParentLoop ()->contains (LIMBB)))) {
246
+ for (instr_iterator I = LIMBB->instr_begin (), E = LIMBB->instr_end ();
247
+ I != E; ++I) {
248
+ MachineInstr *MI = &*I;
249
+ if (MI->getOpcode () == Xtensa::LOOPINIT) {
250
+ LII = MI;
251
+ break ;
252
+ }
235
253
}
254
+ if (LII == nullptr )
255
+ LIMBB = *LIMBB->pred_begin ();
236
256
}
237
- if (LII == nullptr )
238
- LIMBB = *LIMBB->pred_begin ();
239
- }
240
-
241
- if (LII == nullptr ) {
242
- llvm_unreachable (" Hardware loop init instruction not found" );
243
- return false ;
257
+ if (LII == nullptr ) {
258
+ llvm_unreachable (" Hardware loop init instruction not found" );
259
+ return false ;
260
+ }
261
+ LoopInitMap[PBI] = LII;
244
262
}
245
263
246
264
DebugLoc DL = LII->getDebugLoc ();
@@ -250,22 +268,30 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
250
268
// sub a, a, 1
251
269
// bnez a, LH
252
270
if (!checkLoopSize (L) || containsInvalidInstruction (L) ||
253
- (LEMBB != LastMBB) || (!checkLoopEndDisplacement (*LH->getParent (), LH, LEMBB))) {
271
+ (LEMBB != LastMBB) ||
272
+ (!checkLoopEndDisplacement (*LH->getParent (), LH, LEMBB))) {
254
273
const MCInstrDesc &PD = TII->get (TargetOpcode::PHI);
255
274
MachineInstr *NewPN = LH->getParent ()->CreateMachineInstr (PD, DL);
256
275
LH->insert (LH->begin (), NewPN);
257
276
Register PR = MRI->createVirtualRegister (&Xtensa::ARRegClass);
258
277
NewPN->addOperand (MachineOperand::CreateReg (PR, true ));
259
278
260
- MachineOperand MO =
261
- MachineOperand::CreateReg (LII->getOperand (0 ).getReg (), false );
262
- NewPN->addOperand (MO);
263
- NewPN->addOperand (MachineOperand::CreateMBB (PH));
264
-
265
279
Register IndR = MRI->createVirtualRegister (&Xtensa::ARRegClass);
266
- MO = MachineOperand::CreateReg (IndR, false );
267
- NewPN->addOperand (MO);
268
- NewPN->addOperand (MachineOperand::CreateMBB (LastMBB));
280
+
281
+ for (auto PB : LH->predecessors ()) {
282
+
283
+ if (LoopInitMap.find (PB) != LoopInitMap.end ()) {
284
+ MachineOperand MO = MachineOperand::CreateReg (
285
+ LoopInitMap[PB]->getOperand (0 ).getReg (), false );
286
+ NewPN->addOperand (MO);
287
+ NewPN->addOperand (MachineOperand::CreateMBB (PB));
288
+ LoopInitMap[PB]->getParent ()->erase (LoopInitMap[PB]);
289
+ } else {
290
+ MachineOperand MO = MachineOperand::CreateReg (IndR, false );
291
+ NewPN->addOperand (MO);
292
+ NewPN->addOperand (MachineOperand::CreateMBB (PB));
293
+ }
294
+ }
269
295
270
296
MachineInstrBuilder MIB =
271
297
BuildMI (*LEMBB, LEI, LEI->getDebugLoc (), TII->get (Xtensa::ADDI), IndR)
@@ -276,15 +302,42 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
276
302
.addReg (IndR)
277
303
.addMBB (LEI->getOperand (0 ).getMBB ());
278
304
LEMBB->erase (LEI);
279
- PH->erase (LII);
280
305
return false ;
281
306
}
282
307
283
- // Place LOOPSTART instruction in loop header
308
+ // If several LOOPINIT instructions are dicovered then create PHI
309
+ // function
310
+ if (LoopInitMap.size () > 1 ) {
311
+ const MCInstrDesc &PD = TII->get (TargetOpcode::PHI);
312
+ MachineInstr *NewPN = LH->getParent ()->CreateMachineInstr (PD, DL);
313
+ LH->insert (LH->begin (), NewPN);
314
+ Register PR = MRI->createVirtualRegister (&Xtensa::ARRegClass);
315
+ NewPN->addOperand (MachineOperand::CreateReg (PR, true ));
316
+
317
+ for (auto PB : LH->predecessors ()) {
318
+
319
+ if (LoopInitMap.find (PB) != LoopInitMap.end ()) {
320
+ MachineOperand MO = MachineOperand::CreateReg (
321
+ LoopInitMap[PB]->getOperand (0 ).getReg (), false );
322
+ NewPN->addOperand (MO);
323
+ NewPN->addOperand (MachineOperand::CreateMBB (PB));
324
+ LoopInitMap[PB]->getParent ()->erase (LoopInitMap[PB]);
325
+ } else {
326
+ MachineOperand MO = MachineOperand::CreateReg (PR, false );
327
+ NewPN->addOperand (MO);
328
+ NewPN->addOperand (MachineOperand::CreateMBB (PB));
329
+ }
330
+ }
331
+ LII = NewPN;
332
+ }
333
+
284
334
BuildMI (*LH, LHI, DL, TII->get (Xtensa::LOOPSTART))
285
335
.addReg (LII->getOperand (0 ).getReg ())
286
- .addMBB (LastMBB);
287
- PH->erase (LII);
336
+ .addMBB (LEMBB);
337
+
338
+ if (LII->getOpcode () == Xtensa::LOOPINIT)
339
+ LII->getParent ()->erase (LII);
340
+
288
341
return true ;
289
342
}
290
343
0 commit comments