@@ -72,6 +72,11 @@ static cl::opt<bool>
72
72
HoistConstStores (" hoist-const-stores" ,
73
73
cl::desc (" Hoist invariant stores" ),
74
74
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
+
75
80
// The default threshold of 100 (i.e. if target block is 100 times hotter)
76
81
// is based on empirical data on a single target and is subject to tuning.
77
82
static cl::opt<unsigned >
@@ -132,6 +137,9 @@ namespace {
132
137
bool Changed = false ; // True if a loop is changed.
133
138
bool FirstInLoop = false ; // True if it's the first LICM in the loop.
134
139
140
+ // Holds information about whether it is allowed to move load instructions
141
+ // out of the loop
142
+ SmallDenseMap<MachineLoop *, bool > AllowedToHoistLoads;
135
143
136
144
// Exit blocks of each Loop.
137
145
DenseMap<MachineLoop *, SmallVector<MachineBasicBlock *, 8 >> ExitBlockMap;
@@ -281,6 +289,8 @@ namespace {
281
289
282
290
void InitCSEMap (MachineBasicBlock *BB);
283
291
292
+ void InitializeLoadsHoistableLoops ();
293
+
284
294
bool isTgtHotterThanSrc (MachineBasicBlock *SrcBlock,
285
295
MachineBasicBlock *TgtBlock);
286
296
MachineBasicBlock *getCurPreheader (MachineLoop *CurLoop,
@@ -368,6 +378,9 @@ bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) {
368
378
DT = &getAnalysis<MachineDominatorTree>();
369
379
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults ();
370
380
381
+ if (HoistConstLoads)
382
+ InitializeLoadsHoistableLoops ();
383
+
371
384
SmallVector<MachineLoop *, 8 > Worklist (MLI->begin (), MLI->end ());
372
385
while (!Worklist.empty ()) {
373
386
MachineLoop *CurLoop = Worklist.pop_back_val ();
@@ -992,7 +1005,7 @@ static bool isCopyFeedingInvariantStore(const MachineInstr &MI,
992
1005
// / e.g. If the instruction is a call, then it's obviously not safe to hoist it.
993
1006
bool MachineLICMBase::IsLICMCandidate (MachineInstr &I, MachineLoop *CurLoop) {
994
1007
// Check if it's safe to move the instruction.
995
- bool DontMoveAcrossStore = true ;
1008
+ bool DontMoveAcrossStore = !HoistConstLoads || !AllowedToHoistLoads[CurLoop] ;
996
1009
if ((!I.isSafeToMove (AA, DontMoveAcrossStore)) &&
997
1010
!(HoistConstStores && isInvariantStore (I, TRI, MRI))) {
998
1011
LLVM_DEBUG (dbgs () << " LICM: Instruction not safe to move.\n " );
@@ -1333,6 +1346,46 @@ void MachineLICMBase::InitCSEMap(MachineBasicBlock *BB) {
1333
1346
CSEMap[BB][MI.getOpcode ()].push_back (&MI);
1334
1347
}
1335
1348
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
+
1336
1389
// / Find an instruction amount PrevMIs that is a duplicate of MI.
1337
1390
// / Return this instruction if it's found.
1338
1391
MachineInstr *
0 commit comments