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;
2830STATISTIC (NumSunk, " Number of instructions sunk" );
2931STATISTIC (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-
4833static 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-
8666static 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
9171using 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.
166157static 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
239236static 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
276273static 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