Skip to content

Commit e6cec74

Browse files
committed
Use MemorySSA to find stores
Signed-off-by: John Lu <[email protected]>
1 parent 1539a5c commit e6cec74

File tree

1 file changed

+60
-59
lines changed

1 file changed

+60
-59
lines changed

llvm/lib/Transforms/Scalar/Sink.cpp

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "llvm/ADT/Statistic.h"
1616
#include "llvm/Analysis/AliasAnalysis.h"
1717
#include "llvm/Analysis/LoopInfo.h"
18+
#include "llvm/Analysis/MemorySSA.h"
19+
#include "llvm/Analysis/MemorySSAUpdater.h"
1820
#include "llvm/IR/Dominators.h"
1921
#include "llvm/InitializePasses.h"
2022
#include "llvm/Support/CommandLine.h"
@@ -28,23 +30,6 @@ using namespace llvm;
2830
STATISTIC(NumSunk, "Number of instructions sunk");
2931
STATISTIC(NumSinkIter, "Number of sinking iterations");
3032

31-
static bool hasStoreConflict(Instruction *Inst, AliasAnalysis &AA,
32-
SmallPtrSetImpl<Instruction *> &Stores) {
33-
BatchAAResults BatchAA(AA);
34-
35-
if (LoadInst *L = dyn_cast<LoadInst>(Inst)) {
36-
MemoryLocation Loc = MemoryLocation::get(L);
37-
for (Instruction *S : Stores)
38-
if (isModSet(BatchAA.getModRefInfo(S, Loc)))
39-
return true;
40-
} else if (auto *Call = dyn_cast<CallBase>(Inst)) {
41-
for (Instruction *S : Stores)
42-
if (isModSet(BatchAA.getModRefInfo(S, Call)))
43-
return true;
44-
}
45-
return false;
46-
}
47-
4833
static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA,
4934
SmallPtrSetImpl<Instruction *> &Stores) {
5035

@@ -78,56 +63,62 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA,
7863
return true;
7964
}
8065

81-
static cl::opt<unsigned>
82-
SinkLoadBlockLimit("sink-load-block-limit", cl::Hidden, cl::init(15),
83-
cl::desc("Maximum number of descendant blocks that will "
84-
"be analyzed when attempting to sink a load."));
85-
8666
static cl::opt<unsigned> SinkLoadStoreLimit(
87-
"sink-load-store-limit", cl::Hidden, cl::init(3),
67+
"sink-load-store-limit", cl::Hidden, cl::init(4),
8868
cl::desc("Maximum number of stores in descendant blocks that will be "
8969
"analyzed when attempting to sink a load."));
9070

9171
using BlocksSet = SmallPtrSet<BasicBlock *, 8>;
92-
// Return false if finding stores is too complex. True otherwise.
93-
static bool findStores(SmallPtrSetImpl<Instruction *> &Stores,
94-
BasicBlock *LoadBB, BasicBlock *BB,
95-
BlocksSet &VisitedBlocksSet) {
72+
static bool hasStoreConflict(BasicBlock *LoadBB, BasicBlock *BB,
73+
BlocksSet &VisitedBlocksSet,
74+
MemorySSAUpdater &MSSAU, BatchAAResults &BAA,
75+
Instruction *ReadMemInst, unsigned &StoreCnt) {
9676
if (BB == LoadBB || !VisitedBlocksSet.insert(BB).second)
97-
return true;
98-
99-
if (VisitedBlocksSet.size() > SinkLoadBlockLimit)
10077
return false;
101-
for (Instruction &Inst : *BB)
102-
if (Inst.mayWriteToMemory()) {
103-
Stores.insert(&Inst);
104-
if (Stores.size() > SinkLoadStoreLimit)
105-
return false;
106-
}
78+
if (auto *Accesses = MSSAU.getMemorySSA()->getBlockDefs(BB)) {
79+
StoreCnt += Accesses->size();
80+
if (StoreCnt > SinkLoadStoreLimit)
81+
return true;
82+
for (auto &MA : *Accesses)
83+
if (auto *MD = dyn_cast<MemoryDef>(&MA)) {
84+
Instruction *S = MD->getMemoryInst();
85+
if (LoadInst *L = dyn_cast<LoadInst>(ReadMemInst)) {
86+
MemoryLocation Loc = MemoryLocation::get(L);
87+
if (isModSet(BAA.getModRefInfo(S, Loc)))
88+
return true;
89+
} else if (auto *Call = dyn_cast<CallBase>(ReadMemInst)) {
90+
if (isModSet(BAA.getModRefInfo(S, Call)))
91+
return true;
92+
}
93+
}
94+
}
10795
for (BasicBlock *Pred : predecessors(BB))
108-
if (!findStores(Stores, LoadBB, Pred, VisitedBlocksSet))
109-
return false;
110-
return true;
96+
if (hasStoreConflict(LoadBB, Pred, VisitedBlocksSet, MSSAU, BAA,
97+
ReadMemInst, StoreCnt))
98+
return true;
99+
return false;
111100
}
112101

113-
static bool hasConflictingStoreBeforeSuccToSinkTo(AliasAnalysis &AA,
114-
Instruction *ReadMemInst,
115-
BasicBlock *SuccToSinkTo) {
102+
static bool hasConflictingStoreBeforeSuccToSinkTo(Instruction *ReadMemInst,
103+
BasicBlock *SuccToSinkTo,
104+
MemorySSAUpdater &MSSAU,
105+
BatchAAResults &BAA) {
116106
BlocksSet VisitedBlocksSet;
117-
SmallPtrSet<Instruction *, 8> Stores;
118107
BasicBlock *LoadBB = ReadMemInst->getParent();
108+
unsigned StoreCnt{0};
109+
119110
for (BasicBlock *Pred : predecessors(SuccToSinkTo))
120-
// If finding stores is too complex, assume there is a conflict.
121-
if (!findStores(Stores, LoadBB, Pred, VisitedBlocksSet))
111+
if (hasStoreConflict(LoadBB, Pred, VisitedBlocksSet, MSSAU, BAA,
112+
ReadMemInst, StoreCnt))
122113
return true;
123-
return hasStoreConflict(ReadMemInst, AA, Stores);
114+
return false;
124115
}
125116

126117
/// IsAcceptableTarget - Return true if it is possible to sink the instruction
127118
/// in the specified basic block.
128-
static bool IsAcceptableTarget(AliasAnalysis &AA, Instruction *Inst,
129-
BasicBlock *SuccToSinkTo, DominatorTree &DT,
130-
LoopInfo &LI) {
119+
static bool IsAcceptableTarget(Instruction *Inst, BasicBlock *SuccToSinkTo,
120+
DominatorTree &DT, LoopInfo &LI,
121+
MemorySSAUpdater &MSSAU, BatchAAResults &BAA) {
131122
assert(Inst && "Instruction to be sunk is null");
132123
assert(SuccToSinkTo && "Candidate sink target is null");
133124

@@ -143,7 +134,7 @@ static bool IsAcceptableTarget(AliasAnalysis &AA, Instruction *Inst,
143134
// Ensure that there is no conflicting store on any path to SuccToSinkTo.
144135
if (Inst->mayReadFromMemory() &&
145136
!Inst->hasMetadata(LLVMContext::MD_invariant_load) &&
146-
hasConflictingStoreBeforeSuccToSinkTo(AA, Inst, SuccToSinkTo))
137+
hasConflictingStoreBeforeSuccToSinkTo(Inst, SuccToSinkTo, MSSAU, BAA))
147138
return false;
148139

149140
// We don't want to sink across a critical edge if we don't dominate the
@@ -165,7 +156,8 @@ static bool IsAcceptableTarget(AliasAnalysis &AA, Instruction *Inst,
165156
/// instruction out of its current block into a successor.
166157
static bool SinkInstruction(Instruction *Inst,
167158
SmallPtrSetImpl<Instruction *> &Stores,
168-
DominatorTree &DT, LoopInfo &LI, AAResults &AA) {
159+
DominatorTree &DT, LoopInfo &LI, AAResults &AA,
160+
MemorySSAUpdater &MSSAU) {
169161

170162
// Don't sink static alloca instructions. CodeGen assumes allocas outside the
171163
// entry block are dynamically sized stack objects.
@@ -216,8 +208,9 @@ static bool SinkInstruction(Instruction *Inst,
216208
if (SuccToSinkTo) {
217209
// The nearest common dominator may be in a parent loop of BB, which may not
218210
// be beneficial. Find an ancestor.
211+
BatchAAResults BAA(AA);
219212
while (SuccToSinkTo != BB &&
220-
!IsAcceptableTarget(AA, Inst, SuccToSinkTo, DT, LI))
213+
!IsAcceptableTarget(Inst, SuccToSinkTo, DT, LI, MSSAU, BAA))
221214
SuccToSinkTo = DT.getNode(SuccToSinkTo)->getIDom()->getBlock();
222215
if (SuccToSinkTo == BB)
223216
SuccToSinkTo = nullptr;
@@ -233,11 +226,15 @@ static bool SinkInstruction(Instruction *Inst,
233226

234227
// Move the instruction.
235228
Inst->moveBefore(SuccToSinkTo->getFirstInsertionPt());
229+
if (MemoryUseOrDef *OldMemAcc = cast_or_null<MemoryUseOrDef>(
230+
MSSAU.getMemorySSA()->getMemoryAccess(Inst)))
231+
MSSAU.moveToPlace(OldMemAcc, SuccToSinkTo, MemorySSA::Beginning);
232+
236233
return true;
237234
}
238235

239236
static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI,
240-
AAResults &AA) {
237+
AAResults &AA, MemorySSAUpdater &MSSAU) {
241238
// Don't bother sinking code out of unreachable blocks. In addition to being
242239
// unprofitable, it can also lead to infinite looping, because in an
243240
// unreachable loop there may be nowhere to stop.
@@ -262,7 +259,7 @@ static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI,
262259
if (Inst->isDebugOrPseudoInst())
263260
continue;
264261

265-
if (SinkInstruction(Inst, Stores, DT, LI, AA)) {
262+
if (SinkInstruction(Inst, Stores, DT, LI, AA, MSSAU)) {
266263
++NumSunk;
267264
MadeChange = true;
268265
}
@@ -274,15 +271,16 @@ static bool ProcessBlock(BasicBlock &BB, DominatorTree &DT, LoopInfo &LI,
274271
}
275272

276273
static bool iterativelySinkInstructions(Function &F, DominatorTree &DT,
277-
LoopInfo &LI, AAResults &AA) {
274+
LoopInfo &LI, AAResults &AA,
275+
MemorySSAUpdater &MSSAU) {
278276
bool MadeChange, EverMadeChange = false;
279277

280278
do {
281279
MadeChange = false;
282280
LLVM_DEBUG(dbgs() << "Sinking iteration " << NumSinkIter << "\n");
283281
// Process all basic blocks.
284282
for (BasicBlock &I : F)
285-
MadeChange |= ProcessBlock(I, DT, LI, AA);
283+
MadeChange |= ProcessBlock(I, DT, LI, AA, MSSAU);
286284
EverMadeChange |= MadeChange;
287285
NumSinkIter++;
288286
} while (MadeChange);
@@ -294,8 +292,10 @@ PreservedAnalyses SinkingPass::run(Function &F, FunctionAnalysisManager &AM) {
294292
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
295293
auto &LI = AM.getResult<LoopAnalysis>(F);
296294
auto &AA = AM.getResult<AAManager>(F);
295+
MemorySSA &MSSA = AM.getResult<MemorySSAAnalysis>(F).getMSSA();
296+
MemorySSAUpdater MSSAU(&MSSA);
297297

298-
if (!iterativelySinkInstructions(F, DT, LI, AA))
298+
if (!iterativelySinkInstructions(F, DT, LI, AA, MSSAU))
299299
return PreservedAnalyses::all();
300300

301301
PreservedAnalyses PA;
@@ -315,8 +315,9 @@ namespace {
315315
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
316316
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
317317
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
318-
319-
return iterativelySinkInstructions(F, DT, LI, AA);
318+
MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
319+
MemorySSAUpdater MSSAU(MSSA);
320+
return iterativelySinkInstructions(F, DT, LI, AA, MSSAU);
320321
}
321322

322323
void getAnalysisUsage(AnalysisUsage &AU) const override {

0 commit comments

Comments
 (0)