@@ -194,8 +194,10 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
194194 MachineInstr *LII = nullptr ; // LOOPINIT instruction
195195 MachineInstr *LEI = nullptr ; // LOOPEND instruction
196196 MachineBasicBlock *LEMBB = nullptr ;
197- MachineBasicBlock *PH = L->getLoopPreheader ();
197+ MachineBasicBlock *LH = L->getHeader ();
198198 MachineBasicBlock *LastMBB = L->getLoopLatch ();
199+ std::vector<MachineInstr *> LoopInitInsts;
200+ std::map<MachineBasicBlock *, MachineInstr *> LoopInitMap;
199201
200202 // Try to find LOOPEND instruction in the loop latch
201203 for (auto MBI = L->block_begin (), MBIE = L->block_end (); MBI != MBIE; ++MBI) {
@@ -207,40 +209,56 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
207209 LEI = LMI;
208210 LEMBB = *MBI;
209211 }
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+ }
210228 }
211229 VisitedMBBs.insert (*MBI);
212230 }
213231
214232 if (LEI != nullptr ) {
215- MachineBasicBlock *LH = L->getHeader ();
216233 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+ }
235253 }
254+ if (LII == nullptr )
255+ LIMBB = *LIMBB->pred_begin ();
236256 }
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;
244262 }
245263
246264 DebugLoc DL = LII->getDebugLoc ();
@@ -250,22 +268,30 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
250268 // sub a, a, 1
251269 // bnez a, LH
252270 if (!checkLoopSize (L) || containsInvalidInstruction (L) ||
253- (LEMBB != LastMBB) || (!checkLoopEndDisplacement (*LH->getParent (), LH, LEMBB))) {
271+ (LEMBB != LastMBB) ||
272+ (!checkLoopEndDisplacement (*LH->getParent (), LH, LEMBB))) {
254273 const MCInstrDesc &PD = TII->get (TargetOpcode::PHI);
255274 MachineInstr *NewPN = LH->getParent ()->CreateMachineInstr (PD, DL);
256275 LH->insert (LH->begin (), NewPN);
257276 Register PR = MRI->createVirtualRegister (&Xtensa::ARRegClass);
258277 NewPN->addOperand (MachineOperand::CreateReg (PR, true ));
259278
260- MachineOperand MO =
261- MachineOperand::CreateReg (LII->getOperand (0 ).getReg (), false );
262- NewPN->addOperand (MO);
263- NewPN->addOperand (MachineOperand::CreateMBB (PH));
264-
265279 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+ }
269295
270296 MachineInstrBuilder MIB =
271297 BuildMI (*LEMBB, LEI, LEI->getDebugLoc (), TII->get (Xtensa::ADDI), IndR)
@@ -276,15 +302,42 @@ bool XtensaHardwareLoops::processLoop(MachineLoop *L) {
276302 .addReg (IndR)
277303 .addMBB (LEI->getOperand (0 ).getMBB ());
278304 LEMBB->erase (LEI);
279- PH->erase (LII);
280305 return false ;
281306 }
282307
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+
284334 BuildMI (*LH, LHI, DL, TII->get (Xtensa::LOOPSTART))
285335 .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+
288341 return true ;
289342 }
290343
0 commit comments