@@ -9,7 +9,10 @@ SPDX-License-Identifier: MIT
99#include " Compiler/CISACodeGen/PromoteConstantStructs.hpp"
1010#include " common/LLVMWarningsPush.hpp"
1111#include " llvm/Analysis/MemoryDependenceAnalysis.h"
12+ #include " llvm/Analysis/LoopInfo.h"
13+ #include " llvm/ADT/SetVector.h"
1214#include " llvm/Analysis/PtrUseVisitor.h"
15+ #include " llvm/Analysis/CFG.h"
1316#include " common/LLVMWarningsPop.hpp"
1417
1518using namespace llvm ;
@@ -28,7 +31,6 @@ namespace {
2831 // work for large structures. This parameter can not be tweaked inside compiler
2932 //
3033 // Restrictions to this implementation to keep it simple and save compile time:
31- // -- All stores to the structure must be in the same BB
3234 // -- The structure does not escape
3335 // -- We promote only constant values of the same type and store->load only
3436 //
@@ -53,17 +55,19 @@ namespace {
5355
5456 MemoryDependenceResults *MD = nullptr ;
5557 DominatorTree *DT = nullptr ;
58+ LoopInfo* LPI = nullptr ;
5659
5760 void getAnalysisUsage (AnalysisUsage &AU) const override {
5861 AU.addRequired <DominatorTreeWrapperPass>();
5962 AU.addRequired <MemoryDependenceWrapperPass>();
63+ AU.addRequired <LoopInfoWrapperPass>();
6064 AU.setPreservesCFG ();
6165 AU.addPreserved <DominatorTreeWrapperPass>();
6266 }
6367
6468 bool processAlloca (AllocaInst &AI);
6569
66- bool processLoad (LoadInst *LI, BasicBlock *StoreBB );
70+ bool processLoad (LoadInst *LI, SetVector< BasicBlock*>& StoreBBs );
6771
6872 };
6973
@@ -86,7 +90,6 @@ IGC_INITIALIZE_PASS_END(PromoteConstantStructs, PASS_FLAG, PASS_DESC, PASS_CFG_O
8690
8791// This class visits all alloca uses to check that
8892// -- it does not escape
89- // -- all stores are in the same BB
9093// and collect all loads with constant offsets from alloca
9194
9295class AllocaChecker : public PtrUseVisitor<AllocaChecker> {
@@ -95,28 +98,23 @@ class AllocaChecker : public PtrUseVisitor<AllocaChecker> {
9598
9699public:
97100 AllocaChecker (const DataLayout &DL)
98- : PtrUseVisitor<AllocaChecker>(DL), StoreBB ( nullptr ) {}
101+ : PtrUseVisitor<AllocaChecker>(DL), StoreBBs ( ) {}
99102
100103 SmallVector<LoadInst*, 8 >& getPotentialLoads () {
101104 return Loads;
102105 }
103106
104- BasicBlock * getStoreBB () {
105- return StoreBB ;
107+ SetVector< BasicBlock*>& getStoreBBs () {
108+ return StoreBBs ;
106109 }
107110
108111private:
109112 SmallVector<LoadInst*, 8 > Loads;
110113
111- BasicBlock *StoreBB ;
114+ SetVector< BasicBlock*> StoreBBs ;
112115
113116 void visitStoreInst (StoreInst &SI) {
114- if (!StoreBB) {
115- StoreBB = SI.getParent ();
116- }
117- else if (SI.getParent () != StoreBB) {
118- PI.setAborted (&SI);
119- }
117+ StoreBBs.insert (SI.getParent ());
120118 }
121119
122120 void visitLoadInst (LoadInst &LI) {
@@ -126,10 +124,10 @@ class AllocaChecker : public PtrUseVisitor<AllocaChecker> {
126124 }
127125};
128126
129- bool PromoteConstantStructs::runOnFunction (Function &F)
130- {
127+ bool PromoteConstantStructs::runOnFunction (Function &F) {
131128 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
132129 MD = &getAnalysis<MemoryDependenceWrapperPass>().getMemDep ();
130+ LPI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo ();
133131
134132 bool Changed = false ;
135133 BasicBlock &EntryBB = F.getEntryBlock ();
@@ -142,8 +140,7 @@ bool PromoteConstantStructs::runOnFunction(Function &F)
142140 return Changed;
143141}
144142
145- bool PromoteConstantStructs::processAlloca (AllocaInst &AI)
146- {
143+ bool PromoteConstantStructs::processAlloca (AllocaInst &AI) {
147144 // we do not process single or array allocas
148145 if (!AI.getAllocatedType ()->isStructTy ())
149146 return false ;
@@ -153,37 +150,67 @@ bool PromoteConstantStructs::processAlloca(AllocaInst &AI)
153150 if (PtrI.isEscaped () || PtrI.isAborted ())
154151 return false ;
155152
156- BasicBlock *StoreBB = AC.getStoreBB ();
157153 // if we don't have any stores, nothing to do
158- if (!StoreBB )
154+ if (AC. getStoreBBs (). empty () )
159155 return false ;
160156
161157 bool Changed = false ;
162- for (auto LI : AC.getPotentialLoads ())
163- Changed |= processLoad (LI, StoreBB);
158+ bool LocalChanged = true ;
159+ while (LocalChanged) {
160+ LocalChanged = false ;
161+
162+ auto LII = AC.getPotentialLoads ().begin ();
163+ while (LII != AC.getPotentialLoads ().end ()) {
164+ if (processLoad (*LII, AC.getStoreBBs ())) {
165+ LII = AC.getPotentialLoads ().erase (LII);
166+ LocalChanged = true ;
167+ } else {
168+ ++LII;
169+ }
170+ }
171+ Changed |= LocalChanged;
172+ }
164173
165174 return Changed;
166175}
167176
168- bool PromoteConstantStructs::processLoad (LoadInst *LI, BasicBlock *StoreBB)
169- {
170- if (!DT->dominates (StoreBB->getFirstNonPHI (), LI))
171- return false ;
177+ bool PromoteConstantStructs::processLoad (LoadInst *LI, SetVector<BasicBlock*>& StoreBBs) {
178+ unsigned limit = InstructionsLimit;
179+ StoreInst* SI = nullptr ;
172180
173- Instruction *InstPt = StoreBB->getTerminator ();
174- if (StoreBB == LI->getParent ()) InstPt = LI;
181+ auto ML = MemoryLocation::get (LI);
182+ for (auto StBB : StoreBBs) {
183+ SmallVector<BasicBlock*, 32 > Worklist;
184+ Worklist.push_back (StBB);
175185
176- unsigned limit = InstructionsLimit;
186+ if (!isPotentiallyReachableFromMany (Worklist, LI->getParent (), nullptr , DT, LPI))
187+ continue ;
177188
178- MemDepResult Dep = MD->getPointerDependencyFrom (MemoryLocation::get (LI), true ,
179- InstPt->getIterator (), StoreBB, LI, &limit);
189+ Instruction* InstPt = StBB->getTerminator ();
190+ if (StBB == LI->getParent ())
191+ InstPt = LI;
180192
181- // we care only about must aliases, no clobber dependencies
182- if (!Dep.isDef ())
183- return false ;
193+ MemDepResult Dep = MD->getPointerDependencyFrom (ML, true ,
194+ InstPt->getIterator (), StBB, LI, &limit);
195+
196+ if (Dep.isDef ()) {
197+ // skip if more than one def
198+ if (SI)
199+ return false ;
200+
201+ // we search only for stores
202+ SI = dyn_cast<StoreInst>(Dep.getInst ());
203+ if (!SI)
204+ return false ;
205+
206+ if (!DT->dominates (SI, LI))
207+ return false ;
208+ } else if (!Dep.isNonLocal ()) {
209+ return false ;
210+ }
211+ // else no memdep in this BB, can move on
212+ }
184213
185- // we search only for stores
186- StoreInst *SI = dyn_cast<StoreInst>(Dep.getInst ());
187214 if (!SI)
188215 return false ;
189216
0 commit comments