Skip to content

Commit ac6d87c

Browse files
ovvengerigcbot
authored andcommitted
Relax constraints for PromoteConstantStruct
Removed the restriction to have all stores to the struct in one BB
1 parent 068e5e3 commit ac6d87c

File tree

1 file changed

+62
-35
lines changed

1 file changed

+62
-35
lines changed

IGC/Compiler/CISACodeGen/PromoteConstantStructs.cpp

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1518
using 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

9295
class AllocaChecker : public PtrUseVisitor<AllocaChecker> {
@@ -95,28 +98,23 @@ class AllocaChecker : public PtrUseVisitor<AllocaChecker> {
9598

9699
public:
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

108111
private:
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

Comments
 (0)