@@ -13,6 +13,7 @@ SPDX-License-Identifier: MIT
13
13
#include < llvm/Pass.h>
14
14
#include < llvm/Transforms/Utils/Local.h>
15
15
#include < llvm/ADT/Optional.h>
16
+ #include " llvmWrapper/Analysis/TargetLibraryInfo.h"
16
17
#include " llvmWrapper/Transforms/Utils/LoopUtils.h"
17
18
#include " common/LLVMWarningsPop.hpp"
18
19
#include " Compiler/CISACodeGen/ShaderCodeGen.hpp"
@@ -29,13 +30,16 @@ using namespace llvm::PatternMatch;
29
30
using namespace IGC ;
30
31
using namespace IGC ::IGCMD;
31
32
33
+ #define DEBUG_TYPE " AdvMemOpt"
34
+
32
35
namespace {
33
36
34
37
class AdvMemOpt : public FunctionPass {
35
38
DominatorTree* DT = nullptr ;
36
39
LoopInfo* LI = nullptr ;
37
40
PostDominatorTree* PDT = nullptr ;
38
41
WIAnalysis* WI = nullptr ;
42
+ TargetLibraryInfo* TLI = nullptr ;
39
43
40
44
public:
41
45
static char ID;
@@ -58,6 +62,7 @@ namespace {
58
62
AU.addRequired <DominatorTreeWrapperPass>();
59
63
AU.addRequired <LoopInfoWrapperPass>();
60
64
AU.addRequired <PostDominatorTreeWrapperPass>();
65
+ AU.addRequired <TargetLibraryInfoWrapperPass>();
61
66
}
62
67
63
68
bool collectOperandInst (SmallPtrSetImpl<Instruction*>&,
@@ -96,10 +101,13 @@ namespace IGC {
96
101
IGC_INITIALIZE_PASS_DEPENDENCY (DominatorTreeWrapperPass)
97
102
IGC_INITIALIZE_PASS_DEPENDENCY (LoopInfoWrapperPass)
98
103
IGC_INITIALIZE_PASS_DEPENDENCY (PostDominatorTreeWrapperPass);
104
+ IGC_INITIALIZE_PASS_DEPENDENCY (TargetLibraryInfoWrapperPass)
99
105
IGC_INITIALIZE_PASS_END (AdvMemOpt, PASS_FLAG, PASS_DESC, PASS_CFG_ONLY, PASS_ANALYSIS)
100
106
} // End namespace IGC
101
107
102
108
bool AdvMemOpt::runOnFunction (Function& F) {
109
+ bool Changed = false ;
110
+
103
111
// Skip non-kernel function.
104
112
MetaDataUtils* MDU = nullptr ;
105
113
MDU = getAnalysis<MetaDataUtilsWrapper>().getMetaDataUtils ();
@@ -111,6 +119,7 @@ bool AdvMemOpt::runOnFunction(Function& F) {
111
119
PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree ();
112
120
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo ();
113
121
WI = &getAnalysis<WIAnalysis>();
122
+ TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI ();
114
123
115
124
SmallVector<Loop*, 8 > InnermostLoops;
116
125
for (auto I = LI->begin (), E = LI->end (); I != E; ++I)
@@ -138,7 +147,7 @@ bool AdvMemOpt::runOnFunction(Function& F) {
138
147
}
139
148
}
140
149
}
141
- hoistUniformLoad (Line);
150
+ Changed |= hoistUniformLoad (Line);
142
151
}
143
152
144
153
auto * Ctx = getAnalysis<CodeGenContextWrapper>().getCodeGenContext ();
@@ -151,8 +160,8 @@ bool AdvMemOpt::runOnFunction(Function& F) {
151
160
// because, once ballot-loop is added, vISA finalizer cannot schedule
152
161
// those sample operations.
153
162
auto & DL = F.getParent ()->getDataLayout ();
154
- IRBuilder <> IRB (F.getContext ());
155
- Cluster.init (Ctx, &DL, nullptr /* AA*/ , 32 );
163
+ IGCIRBuilder <> IRB (F.getContext ());
164
+ Cluster.init (Ctx, &DL, nullptr /* AA*/ , TLI, 32 );
156
165
for (Function::iterator I = F.begin (), E = F.end (); I != E;
157
166
++I) {
158
167
BasicBlock *BB = &*I;
@@ -182,24 +191,26 @@ bool AdvMemOpt::runOnFunction(Function& F) {
182
191
if (!WI->isUniform (LI->getResourceValue ())) {
183
192
NumResourceVarying++;
184
193
}
185
- } else if (auto * SI = dyn_cast<StoreInst>(I )) {
186
- if (!WI->isUniform (SI))
194
+ } else if (auto SI = AStoreInst::get (I); SI. has_value ( )) {
195
+ if (!WI->isUniform (SI-> inst () ))
187
196
continue ;
188
197
189
198
unsigned AS = SI->getPointerAddressSpace ();
190
199
if (AS != ADDRESS_SPACE_PRIVATE &&
191
200
AS != ADDRESS_SPACE_GLOBAL)
192
201
continue ;
193
202
194
- IRB.SetInsertPoint (SI);
203
+ IRB.SetInsertPoint (SI-> inst () );
195
204
196
- if (auto NewSI = expand64BitStore (IRB, DL, SI)) {
205
+ if (auto NewSI = expand64BitStore (IRB, DL, SI.value ())) {
206
+ auto NewASI = AStoreInst::get (NewSI);
197
207
WI->incUpdateDepend (NewSI, WIAnalysis::UNIFORM_THREAD);
198
- WI->incUpdateDepend (NewSI ->getValueOperand (),
208
+ WI->incUpdateDepend (NewASI ->getValueOperand (),
199
209
WIAnalysis::UNIFORM_THREAD);
200
- WI->incUpdateDepend (NewSI ->getPointerOperand (),
210
+ WI->incUpdateDepend (NewASI ->getPointerOperand (),
201
211
WIAnalysis::UNIFORM_THREAD);
202
- SI->eraseFromParent ();
212
+ SI->inst ()->eraseFromParent ();
213
+ Changed = true ;
203
214
}
204
215
}
205
216
}
@@ -209,24 +220,29 @@ bool AdvMemOpt::runOnFunction(Function& F) {
209
220
NumResourceVarying;
210
221
// clustering method cannot handle memory dependence
211
222
if (!HasStore)
212
- Cluster.runForGFX (BB);
223
+ Changed |= Cluster.runForGFX (BB);
213
224
}
214
225
}
215
226
}
216
- return false ;
227
+ return Changed ;
217
228
}
218
229
219
230
bool AdvMemOpt::isLeadCandidate (BasicBlock* BB) const {
220
- // A candidate lead should have at least one uniform loads . In addition,
231
+ // A candidate lead should have at least one uniform load . In addition,
221
232
// there's no instruction might to write memory from the last uniform loads
222
233
// to the end.
234
+ LLVM_DEBUG (dbgs () << " Check lead candidate: " << BB->getName () << " \n " );
223
235
for (auto II = BB->rbegin (), IE = BB->rend (); II != IE; ++II) {
224
- if (II->mayWriteToMemory ())
236
+ if (II->mayWriteToMemory ()) {
237
+ LLVM_DEBUG (dbgs () <<" - May write to memory. Bail out: " << *II << " \n " );
225
238
return false ;
226
- LoadInst* LD = dyn_cast<LoadInst>(&*II);
227
- if (!LD || !WI->isUniform (LD))
239
+ }
240
+ std::optional<ALoadInst> LD = ALoadInst::get (&*II);
241
+ if (!LD.has_value () || !WI->isUniform (LD->inst ())) {
242
+ LLVM_DEBUG (dbgs () << " - Not uniform load. Skip: " << *II << " \n " );
228
243
continue ;
229
- // Found uniform loads.
244
+ }
245
+ LLVM_DEBUG (dbgs () << " Found uniform loads.\n " );
230
246
return true ;
231
247
}
232
248
return false ;
@@ -351,42 +367,66 @@ bool AdvMemOpt::hoistInst(Instruction* LD, BasicBlock* BB) const {
351
367
352
368
bool AdvMemOpt::hoistUniformLoad (ArrayRef<BasicBlock*> Line) const {
353
369
bool Changed = false ;
354
- // Find the lead BB where to hoist uniform load.
370
+ LLVM_DEBUG (dbgs () << " Find the lead BB where to hoist uniform load.\n " );
371
+
355
372
auto BI = Line.begin ();
356
373
auto BE = Line.end ();
374
+
357
375
while (BI != BE) {
358
376
if (!isLeadCandidate (*BI)) {
359
377
++BI;
360
378
continue ;
361
379
}
380
+
362
381
// Found lead.
363
382
BasicBlock* Lead = *BI++;
364
- BasicBlock* Prev = Lead;
383
+ LLVM_DEBUG (dbgs () << " Found lead to hoist to: " << Lead->getName () << " \n " );
384
+
365
385
for (; BI != BE; ++BI) {
366
386
BasicBlock* Curr = *BI;
387
+ LLVM_DEBUG (dbgs () << " - Try to hoist from: " << Curr->getName () << " \n " );
367
388
// Check whether it's safe to hoist uniform loads from Curr to Lead by
368
389
// checking all blocks between Prev and Curr.
369
- if (hasMemoryWrite (Prev, Curr))
390
+ if (hasMemoryWrite (Lead, Curr)) {
391
+ LLVM_DEBUG (dbgs () << " - Memory write between Lead and Curr. Bail out.\n " );
370
392
break ;
393
+ }
394
+
371
395
// Hoist uniform loads from Curr into Lead.
372
396
for (auto II = Curr->getFirstNonPHI ()->getIterator (),
373
397
IE = Curr->end (); II != IE; /* EMPTY*/ ) {
374
- if (II->mayWriteToMemory ())
398
+ LLVM_DEBUG (dbgs () << " - - Try hoisting: " << *II << " \n " );
399
+
400
+ if (II->mayWriteToMemory ()) {
401
+ LLVM_DEBUG (dbgs () << " - - May write to memory. Bail out.\n " );
375
402
break ;
376
- LoadInst* LD = dyn_cast<LoadInst>(&*II++);
377
- if (!LD || !WI->isUniform (LD))
403
+ }
404
+
405
+ std::optional<ALoadInst> LD = ALoadInst::get (&*II++);
406
+ if (!LD.has_value () || !WI->isUniform (LD->inst ())) {
407
+ LLVM_DEBUG (dbgs () << " - - Not uniform load. Skip.\n " );
378
408
continue ;
379
- if (!hoistInst (LD, Lead))
380
- break ; // Bail out if any uniform load could not be hoisted safely.
381
- // Reset iterator
382
- II = Curr->getFirstNonPHI ()->getIterator ();
409
+ }
410
+
411
+ if (!hoistInst (LD->inst (), Lead)) {
412
+ LLVM_DEBUG (dbgs () << " - - Uniform load could not be hoisted safely. Bail out.\n " );
413
+ break ;
414
+ }
383
415
Changed = true ;
416
+ LLVM_DEBUG (dbgs () << " - - Hoisted!\n " );
417
+
418
+ // Reset iterator
419
+ II = Curr->getFirstNonPHI ()->getIterator ();
384
420
}
421
+
385
422
// After hoisting uniform loads safely, if Curr has memory write, stop
386
423
// hoisting further.
387
- if (hasMemoryWrite (Curr))
424
+ if (hasMemoryWrite (Curr)) {
425
+ LLVM_DEBUG (dbgs () << " - Curr has memory write. Bail out.\n " );
388
426
break ;
427
+ }
389
428
}
390
429
}
430
+
391
431
return Changed;
392
432
}
0 commit comments