79
79
#include " llvm/Analysis/Loads.h"
80
80
#include " llvm/Analysis/MemoryBuiltins.h"
81
81
#include " llvm/Analysis/MemoryDependenceAnalysis.h"
82
- #include " llvm/Analysis/TargetLibraryInfo.h"
83
82
#include " llvm/IR/Metadata.h"
84
83
#include " llvm/IR/PatternMatch.h"
85
84
#include " llvm/Support/Debug.h"
@@ -114,7 +113,6 @@ class MergedLoadStoreMotion : public FunctionPass {
114
113
// This transformation requires dominator postdominator info
115
114
void getAnalysisUsage (AnalysisUsage &AU) const override {
116
115
AU.setPreservesCFG ();
117
- AU.addRequired <TargetLibraryInfoWrapperPass>();
118
116
AU.addRequired <AAResultsWrapperPass>();
119
117
AU.addPreserved <GlobalsAAWrapperPass>();
120
118
AU.addPreserved <MemoryDependenceWrapperPass>();
@@ -130,9 +128,9 @@ class MergedLoadStoreMotion : public FunctionPass {
130
128
BasicBlock *getDiamondTail (BasicBlock *BB);
131
129
bool isDiamondHead (BasicBlock *BB);
132
130
// Routines for hoisting loads
133
- bool isLoadHoistBarrierInRange (const Instruction& Start,
134
- const Instruction& End,
135
- LoadInst* LI );
131
+ bool isLoadHoistBarrierInRange (const Instruction & Start,
132
+ const Instruction & End, LoadInst *LI ,
133
+ bool SafeToLoadUnconditionally );
136
134
LoadInst *canHoistFromBlock (BasicBlock *BB, LoadInst *LI);
137
135
void hoistInstruction (BasicBlock *BB, Instruction *HoistCand,
138
136
Instruction *ElseInst);
@@ -166,7 +164,6 @@ FunctionPass *llvm::createMergedLoadStoreMotionPass() {
166
164
INITIALIZE_PASS_BEGIN (MergedLoadStoreMotion, " mldst-motion" ,
167
165
" MergedLoadStoreMotion" , false , false )
168
166
INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
169
- INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
170
167
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
171
168
INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
172
169
INITIALIZE_PASS_END(MergedLoadStoreMotion, " mldst-motion" ,
@@ -229,9 +226,14 @@ bool MergedLoadStoreMotion::isDiamondHead(BasicBlock *BB) {
229
226
// / being loaded or protect against the load from happening
230
227
// / it is considered a hoist barrier.
231
228
// /
232
- bool MergedLoadStoreMotion::isLoadHoistBarrierInRange (const Instruction& Start,
233
- const Instruction& End,
234
- LoadInst* LI) {
229
+ bool MergedLoadStoreMotion::isLoadHoistBarrierInRange (
230
+ const Instruction &Start, const Instruction &End, LoadInst *LI,
231
+ bool SafeToLoadUnconditionally) {
232
+ if (!SafeToLoadUnconditionally)
233
+ for (const Instruction &Inst :
234
+ make_range (Start.getIterator (), End.getIterator ()))
235
+ if (Inst.mayThrow ())
236
+ return true ;
235
237
MemoryLocation Loc = MemoryLocation::get (LI);
236
238
return AA->canInstructionRangeModRef (Start, End, Loc, MRI_Mod);
237
239
}
@@ -245,23 +247,28 @@ bool MergedLoadStoreMotion::isLoadHoistBarrierInRange(const Instruction& Start,
245
247
// /
246
248
LoadInst *MergedLoadStoreMotion::canHoistFromBlock (BasicBlock *BB1,
247
249
LoadInst *Load0) {
248
-
250
+ BasicBlock *BB0 = Load0->getParent ();
251
+ BasicBlock *Head = BB0->getSinglePredecessor ();
252
+ bool SafeToLoadUnconditionally = isSafeToLoadUnconditionally (
253
+ Load0->getPointerOperand (), Load0->getAlignment (),
254
+ Load0->getModule ()->getDataLayout (),
255
+ /* ScanFrom=*/ Head->getTerminator ());
249
256
for (BasicBlock::iterator BBI = BB1->begin (), BBE = BB1->end (); BBI != BBE;
250
257
++BBI) {
251
258
Instruction *Inst = &*BBI;
252
259
253
260
// Only merge and hoist loads when their result in used only in BB
254
- if (!isa<LoadInst>(Inst) || Inst->isUsedOutsideOfBlock (BB1))
261
+ auto *Load1 = dyn_cast<LoadInst>(Inst);
262
+ if (!Load1 || Inst->isUsedOutsideOfBlock (BB1))
255
263
continue ;
256
264
257
- auto *Load1 = cast<LoadInst>(Inst);
258
- BasicBlock *BB0 = Load0->getParent ();
259
-
260
265
MemoryLocation Loc0 = MemoryLocation::get (Load0);
261
266
MemoryLocation Loc1 = MemoryLocation::get (Load1);
262
267
if (AA->isMustAlias (Loc0, Loc1) && Load0->isSameOperationAs (Load1) &&
263
- !isLoadHoistBarrierInRange (BB1->front (), *Load1, Load1) &&
264
- !isLoadHoistBarrierInRange (BB0->front (), *Load0, Load0)) {
268
+ !isLoadHoistBarrierInRange (BB1->front (), *Load1, Load1,
269
+ SafeToLoadUnconditionally) &&
270
+ !isLoadHoistBarrierInRange (BB0->front (), *Load0, Load0,
271
+ SafeToLoadUnconditionally)) {
265
272
return Load1;
266
273
}
267
274
}
@@ -387,6 +394,10 @@ bool MergedLoadStoreMotion::mergeLoads(BasicBlock *BB) {
387
394
bool MergedLoadStoreMotion::isStoreSinkBarrierInRange (const Instruction &Start,
388
395
const Instruction &End,
389
396
MemoryLocation Loc) {
397
+ for (const Instruction &Inst :
398
+ make_range (Start.getIterator (), End.getIterator ()))
399
+ if (Inst.mayThrow ())
400
+ return true ;
390
401
return AA->canInstructionRangeModRef (Start, End, Loc, MRI_ModRef);
391
402
}
392
403
@@ -403,18 +414,15 @@ StoreInst *MergedLoadStoreMotion::canSinkFromBlock(BasicBlock *BB1,
403
414
RBI != RBE; ++RBI) {
404
415
Instruction *Inst = &*RBI;
405
416
406
- if (!isa<StoreInst>(Inst))
407
- continue ;
408
-
409
- StoreInst *Store1 = cast<StoreInst>(Inst);
417
+ auto *Store1 = dyn_cast<StoreInst>(Inst);
418
+ if (!Store1)
419
+ continue ;
410
420
411
421
MemoryLocation Loc0 = MemoryLocation::get (Store0);
412
422
MemoryLocation Loc1 = MemoryLocation::get (Store1);
413
423
if (AA->isMustAlias (Loc0, Loc1) && Store0->isSameOperationAs (Store1) &&
414
- !isStoreSinkBarrierInRange (*(std::next (BasicBlock::iterator (Store1))),
415
- BB1->back (), Loc1) &&
416
- !isStoreSinkBarrierInRange (*(std::next (BasicBlock::iterator (Store0))),
417
- BB0->back (), Loc0)) {
424
+ !isStoreSinkBarrierInRange (*Store1->getNextNode (), BB1->back (), Loc1) &&
425
+ !isStoreSinkBarrierInRange (*Store0->getNextNode (), BB0->back (), Loc0)) {
418
426
return Store1;
419
427
}
420
428
}
0 commit comments