@@ -289,6 +289,8 @@ namespace {
289289
290290 void InitCSEMap (MachineBasicBlock *BB);
291291
292+ void InitializeLoadsHoistableLoops ();
293+
292294 bool isTgtHotterThanSrc (MachineBasicBlock *SrcBlock,
293295 MachineBasicBlock *TgtBlock);
294296 MachineBasicBlock *getCurPreheader (MachineLoop *CurLoop,
@@ -376,37 +378,10 @@ bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) {
376378 DT = &getAnalysis<MachineDominatorTree>();
377379 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults ();
378380
379- SmallVector<MachineLoop *, 8 > Worklist (MLI->begin (), MLI->end ());
380-
381- // Initialize `AllowedToHoistLoads' if needed.
382- if (HoistConstLoads) {
383- auto TmpWorklist = Worklist;
384- // Initialize all loops with true values
385- while (!TmpWorklist.empty ()) {
386- auto *L = TmpWorklist.pop_back_val ();
387- AllowedToHoistLoads[L] = true ;
388- TmpWorklist.insert (TmpWorklist.end (), L->getSubLoops ().begin (),
389- L->getSubLoops ().end ());
390- }
391- // Go through all the instructions inside top-level loops and, after finding
392- // one that makes it potentially unsafe to move loads, update load hoisting
393- // information for each loop containing this instruction.
394- for (auto *TopLoop : Worklist) {
395- for (auto *MBB : TopLoop->blocks ()) {
396- for (auto &MI : *MBB) {
397- if (!MI.mayStore () && !MI.isCall () &&
398- !(MI.mayLoad () && MI.hasOrderedMemoryRef ()))
399- continue ;
400- for (MachineLoop *L = MLI->getLoopFor (MI.getParent ()); L != TopLoop;
401- L = L->getParentLoop ())
402- AllowedToHoistLoads[L] = false ;
403- AllowedToHoistLoads[TopLoop] = false ;
404- break ;
405- }
406- }
407- }
408- }
381+ if (HoistConstLoads)
382+ InitializeLoadsHoistableLoops ();
409383
384+ SmallVector<MachineLoop *, 8 > Worklist (MLI->begin (), MLI->end ());
410385 while (!Worklist.empty ()) {
411386 MachineLoop *CurLoop = Worklist.pop_back_val ();
412387 MachineBasicBlock *CurPreheader = nullptr ;
@@ -1371,6 +1346,46 @@ void MachineLICMBase::InitCSEMap(MachineBasicBlock *BB) {
13711346 CSEMap[BB][MI.getOpcode ()].push_back (&MI);
13721347}
13731348
1349+ // / Initialize AllowedToHoistLoads with information about whether invariant
1350+ // / loads can be moved outside a given loop
1351+ void MachineLICMBase::InitializeLoadsHoistableLoops () {
1352+ SmallVector<MachineLoop *, 8 > Worklist (MLI->begin (), MLI->end ());
1353+ SmallVector<MachineLoop *, 8 > LoopsInPreOrder;
1354+
1355+ // Mark all loops as hoistable initially and prepare a list of loops in
1356+ // pre-order DFS.
1357+ while (!Worklist.empty ()) {
1358+ auto *L = Worklist.pop_back_val ();
1359+ AllowedToHoistLoads[L] = true ;
1360+ LoopsInPreOrder.push_back (L);
1361+ Worklist.insert (Worklist.end (), L->getSubLoops ().begin (),
1362+ L->getSubLoops ().end ());
1363+ }
1364+
1365+ // Going from the innermost to outermost loops, check if a loop has
1366+ // instructions preventing invariant load hoisting. If such instruction is
1367+ // found, mark this loop and its parent as non-hoistable and continue
1368+ // investigating the next loop.
1369+ // Visiting in a reversed pre-ordered DFS manner
1370+ // allows us to not process all the instructions of the outer loop if the
1371+ // inner loop is proved to be non-load-hoistable.
1372+ for (auto *Loop : reverse (LoopsInPreOrder)) {
1373+ for (auto *MBB : Loop->blocks ()) {
1374+ // If this loop has already been marked as non-hoistable, skip it.
1375+ if (!AllowedToHoistLoads[Loop])
1376+ continue ;
1377+ for (auto &MI : *MBB) {
1378+ if (!MI.mayStore () && !MI.isCall () &&
1379+ !(MI.mayLoad () && MI.hasOrderedMemoryRef ()))
1380+ continue ;
1381+ for (MachineLoop *L = Loop; L != nullptr ; L = L->getParentLoop ())
1382+ AllowedToHoistLoads[L] = false ;
1383+ break ;
1384+ }
1385+ }
1386+ }
1387+ }
1388+
13741389// / Find an instruction amount PrevMIs that is a duplicate of MI.
13751390// / Return this instruction if it's found.
13761391MachineInstr *
0 commit comments