@@ -72,6 +72,11 @@ static cl::opt<bool>
7272HoistConstStores (" hoist-const-stores" ,
7373 cl::desc (" Hoist invariant stores" ),
7474 cl::init(true ), cl::Hidden);
75+
76+ static cl::opt<bool > HoistConstLoads (" hoist-const-loads" ,
77+ cl::desc (" Hoist invariant loads" ),
78+ cl::init(true ), cl::Hidden);
79+
7580// The default threshold of 100 (i.e. if target block is 100 times hotter)
7681// is based on empirical data on a single target and is subject to tuning.
7782static cl::opt<unsigned >
@@ -132,6 +137,9 @@ namespace {
132137 bool Changed = false ; // True if a loop is changed.
133138 bool FirstInLoop = false ; // True if it's the first LICM in the loop.
134139
140+ // Holds information about whether it is allowed to move load instructions
141+ // out of the loop
142+ SmallDenseMap<MachineLoop *, bool > AllowedToHoistLoads;
135143
136144 // Exit blocks of each Loop.
137145 DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8 >> ExitBlockMap;
@@ -281,6 +289,8 @@ namespace {
281289
282290 void InitCSEMap (MachineBasicBlock *BB);
283291
292+ void InitializeLoadsHoistableLoops ();
293+
284294 bool isTgtHotterThanSrc (MachineBasicBlock *SrcBlock,
285295 MachineBasicBlock *TgtBlock);
286296 MachineBasicBlock *getCurPreheader (MachineLoop *CurLoop,
@@ -368,6 +378,9 @@ bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) {
368378 DT = &getAnalysis<MachineDominatorTree>();
369379 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults ();
370380
381+ if (HoistConstLoads)
382+ InitializeLoadsHoistableLoops ();
383+
371384 SmallVector<MachineLoop *, 8 > Worklist (MLI->begin (), MLI->end ());
372385 while (!Worklist.empty ()) {
373386 MachineLoop *CurLoop = Worklist.pop_back_val ();
@@ -992,7 +1005,7 @@ static bool isCopyFeedingInvariantStore(const MachineInstr &MI,
9921005// / e.g. If the instruction is a call, then it's obviously not safe to hoist it.
9931006bool MachineLICMBase::IsLICMCandidate (MachineInstr &I, MachineLoop *CurLoop) {
9941007 // Check if it's safe to move the instruction.
995- bool DontMoveAcrossStore = true ;
1008+ bool DontMoveAcrossStore = !HoistConstLoads || !AllowedToHoistLoads[CurLoop] ;
9961009 if ((!I.isSafeToMove (AA, DontMoveAcrossStore)) &&
9971010 !(HoistConstStores && isInvariantStore (I, TRI, MRI))) {
9981011 LLVM_DEBUG (dbgs () << " LICM: Instruction not safe to move.\n " );
@@ -1333,6 +1346,46 @@ void MachineLICMBase::InitCSEMap(MachineBasicBlock *BB) {
13331346 CSEMap[BB][MI.getOpcode ()].push_back (&MI);
13341347}
13351348
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+
13361389// / Find an instruction amount PrevMIs that is a duplicate of MI.
13371390// / Return this instruction if it's found.
13381391MachineInstr *
0 commit comments