1717#include " llvm/Analysis/LoopInfo.h"
1818#include " llvm/IR/Dominators.h"
1919#include " llvm/InitializePasses.h"
20+ #include " llvm/Support/CommandLine.h"
2021#include " llvm/Support/Debug.h"
2122#include " llvm/Support/raw_ostream.h"
2223#include " llvm/Transforms/Scalar.h"
@@ -77,18 +78,36 @@ static bool isSafeToMove(Instruction *Inst, AliasAnalysis &AA,
7778 return true ;
7879}
7980
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+
86+ static cl::opt<unsigned > SinkLoadStoreLimit (
87+ " sink-load-store-limit" , cl::Hidden, cl::init(3 ),
88+ cl::desc(" Maximum number of stores in descendant blocks that will be "
89+ " analyzed when attempting to sink a load." ));
90+
8091using BlocksSet = SmallPtrSet<BasicBlock *, 8 >;
81- static void findStores (SmallPtrSetImpl<Instruction *> &Stores,
92+ // Return false if finding stores is too complex. True otherwise.
93+ static bool findStores (SmallPtrSetImpl<Instruction *> &Stores,
8294 BasicBlock *LoadBB, BasicBlock *BB,
8395 BlocksSet &VisitedBlocksSet) {
8496 if (BB == LoadBB || !VisitedBlocksSet.insert (BB).second )
85- return ;
97+ return true ;
8698
99+ if (VisitedBlocksSet.size () > SinkLoadBlockLimit)
100+ return false ;
87101 for (Instruction &Inst : *BB)
88- if (Inst.mayWriteToMemory ())
102+ if (Inst.mayWriteToMemory ()) {
89103 Stores.insert (&Inst);
104+ if (Stores.size () > SinkLoadStoreLimit)
105+ return false ;
106+ }
90107 for (BasicBlock *Pred : predecessors (BB))
91- findStores (Stores, LoadBB, Pred, VisitedBlocksSet);
108+ if (!findStores (Stores, LoadBB, Pred, VisitedBlocksSet))
109+ return false ;
110+ return true ;
92111}
93112
94113static bool hasConflictingStoreBeforeSuccToSinkTo (AliasAnalysis &AA,
@@ -98,7 +117,9 @@ static bool hasConflictingStoreBeforeSuccToSinkTo(AliasAnalysis &AA,
98117 SmallPtrSet<Instruction *, 8 > Stores;
99118 BasicBlock *LoadBB = ReadMemInst->getParent ();
100119 for (BasicBlock *Pred : predecessors (SuccToSinkTo))
101- findStores (Stores, LoadBB, Pred, VisitedBlocksSet);
120+ // If finding stores is too complex, assume there is a conflict.
121+ if (!findStores (Stores, LoadBB, Pred, VisitedBlocksSet))
122+ return true ;
102123 return hasStoreConflict (ReadMemInst, AA, Stores);
103124}
104125
0 commit comments