@@ -14,9 +14,11 @@ SPDX-License-Identifier: MIT
14
14
#include " Compiler/CISACodeGen/OpenCLKernelCodeGen.hpp"
15
15
#include " Compiler/IGCPassSupport.h"
16
16
#include " Compiler/MetaDataUtilsWrapper.h"
17
+
17
18
#include " common/LLVMWarningsPush.hpp"
18
19
#include " llvmWrapper/Support/Alignment.h"
19
20
#include " llvmWrapper/IR/DerivedTypes.h"
21
+ #include < llvm/ADT/SmallVector.h>
20
22
#include < llvm/IR/Module.h>
21
23
#include < llvm/IR/Instructions.h>
22
24
#include < llvm/IR/DataLayout.h>
@@ -32,34 +34,33 @@ namespace {
32
34
class GenericAddressDynamicResolution : public FunctionPass {
33
35
public:
34
36
static char ID;
35
- Module* m_module = nullptr ;
36
- CodeGenContext* m_ctx = nullptr ;
37
37
38
38
GenericAddressDynamicResolution ()
39
39
: FunctionPass(ID)
40
40
{
41
41
}
42
42
~GenericAddressDynamicResolution () = default ;
43
43
44
- virtual StringRef getPassName () const override
44
+ StringRef getPassName () const override
45
45
{
46
46
return " GenericAddressDynamicResolution" ;
47
47
}
48
48
49
- virtual void getAnalysisUsage (AnalysisUsage& AU) const override
49
+ void getAnalysisUsage (AnalysisUsage& AU) const override
50
50
{
51
51
AU.addRequired <MetaDataUtilsWrapper>();
52
52
AU.addRequired <CodeGenContextWrapper>();
53
53
AU.addRequired <CastToGASAnalysis>();
54
54
}
55
55
56
- virtual bool runOnFunction (Function& F) override ;
57
-
56
+ bool runOnFunction (Function& F) override ;
57
+ private:
58
58
bool visitLoadStoreInst (Instruction& I);
59
59
bool visitIntrinsicCall (CallInst& I);
60
- Module* getModule () { return m_module; }
61
60
62
- private:
61
+ Module* m_module = nullptr ;
62
+ CodeGenContext* m_ctx = nullptr ;
63
+ llvm::SmallVector<Instruction*, 32 > generatedLoadStores;
63
64
bool m_needPrivateBranches = false ;
64
65
bool m_needLocalBranches = false ;
65
66
@@ -96,43 +97,37 @@ bool GenericAddressDynamicResolution::runOnFunction(Function& F)
96
97
m_needLocalBranches = !GI.isNoLocalToGenericOptionEnabled () && GI.canGenericPointToLocal (F);
97
98
98
99
bool modified = false ;
99
- bool changed = false ;
100
100
101
- // iterate for all the intrinisics used by to_local, to_global, and to_private
102
- do {
103
- changed = false ;
104
-
105
- for (inst_iterator i = inst_begin (F); i != inst_end (F); ++i) {
106
- Instruction& instruction = (*i);
101
+ llvm::SmallVector<Instruction*, 32 > callInstructions;
102
+ llvm::SmallVector<Instruction*, 32 > loadStoreInstructions;
107
103
108
- if (CallInst * intrinsic = dyn_cast<CallInst>(&instruction)) {
109
- changed = visitIntrinsicCall (*intrinsic);
110
- }
104
+ for (auto & instruction: llvm::instructions (F)) {
111
105
112
- if (changed) {
113
- modified = true ;
114
- break ;
115
- }
106
+ if (isa<CallInst>(&instruction)) {
107
+ callInstructions.push_back (&instruction);
108
+ }
109
+ if (isa<LoadInst, StoreInst>(instruction)) {
110
+ loadStoreInstructions.push_back (&instruction);
116
111
}
117
- } while (changed);
112
+ }
113
+ // iterate for all the intrinisics used by to_local, to_global, and to_private
114
+ for (auto * callInst : callInstructions) {
115
+ modified |= visitIntrinsicCall (cast<CallInst>(*callInst));
116
+ }
118
117
119
118
// iterate over all loads/stores with generic address space pointers
120
- do {
121
- changed = false ;
122
-
123
- for (inst_iterator i = inst_begin (F); i != inst_end (F); ++i) {
124
- Instruction& instruction = (*i);
125
-
126
- if (isa<LoadInst>(instruction) || isa<StoreInst>(instruction)) {
127
- changed = visitLoadStoreInst (instruction);
128
- }
119
+ for (auto * loadStoreInst : loadStoreInstructions) {
120
+ modified |= visitLoadStoreInst (*loadStoreInst);
121
+ }
129
122
130
- if (changed) {
131
- modified = true ;
132
- break ;
133
- }
123
+ // iterate over all newly generated load/stores
124
+ while (!generatedLoadStores.empty ()) {
125
+ llvm::SmallVector<Instruction*, 32 > newInstructions = generatedLoadStores;
126
+ generatedLoadStores.clear ();
127
+ for (auto * loadStoreInst : newInstructions) {
128
+ modified |= visitLoadStoreInst (*loadStoreInst);
134
129
}
135
- } while (changed);
130
+ }
136
131
137
132
if (m_numAdditionalControlFlows)
138
133
{
@@ -155,8 +150,7 @@ bool GenericAddressDynamicResolution::runOnFunction(Function& F)
155
150
156
151
Type* GenericAddressDynamicResolution::getPointerAsIntType (LLVMContext& ctx, const unsigned AS)
157
152
{
158
- Module* pModule = getModule ();
159
- DataLayout dataLayout = pModule->getDataLayout ();
153
+ DataLayout dataLayout = m_module->getDataLayout ();
160
154
unsigned ptrBits (dataLayout.getPointerSizeInBits (AS));
161
155
return IntegerType::get (ctx, ptrBits);
162
156
}
@@ -168,11 +162,11 @@ bool GenericAddressDynamicResolution::visitLoadStoreInst(Instruction& I)
168
162
Value* pointerOperand = nullptr ;
169
163
unsigned int pointerAddressSpace = ADDRESS_SPACE_NUM_ADDRESSES;
170
164
171
- if (LoadInst * load = dyn_cast<LoadInst>(&I)) {
165
+ if (auto * load = dyn_cast<LoadInst>(&I)) {
172
166
pointerOperand = load->getPointerOperand ();
173
167
pointerAddressSpace = load->getPointerAddressSpace ();
174
168
}
175
- else if (StoreInst * store = dyn_cast<StoreInst>(&I)) {
169
+ else if (auto * store = dyn_cast<StoreInst>(&I)) {
176
170
pointerOperand = store->getPointerOperand ();
177
171
pointerAddressSpace = store->getPointerAddressSpace ();
178
172
}
@@ -241,7 +235,7 @@ void GenericAddressDynamicResolution::resolveGAS(Instruction& I, Value* pointerO
241
235
// with the corresponding address space.
242
236
243
237
IGCLLVM::IRBuilder<> builder (&I);
244
- PointerType * pointerType = dyn_cast<PointerType>(pointerOperand->getType ());
238
+ auto * pointerType = dyn_cast<PointerType>(pointerOperand->getType ());
245
239
IGC_ASSERT ( pointerType != nullptr );
246
240
ConstantInt* privateTag = builder.getInt64 (1 ); // tag 001
247
241
ConstantInt* localTag = builder.getInt64 (2 ); // tag 010
@@ -275,15 +269,18 @@ void GenericAddressDynamicResolution::resolveGAS(Instruction& I, Value* pointerO
275
269
builder.SetInsertPoint (BB);
276
270
PointerType* ptrType = IGCLLVM::getWithSamePointeeType (pointerType, addressSpace);
277
271
Value* ptr = builder.CreateAddrSpaceCast (pointerOperand, ptrType);
272
+ Instruction* generatedLoadStore = nullptr ;
278
273
279
- if (LoadInst * LI = dyn_cast<LoadInst>(&I))
274
+ if (auto * LI = dyn_cast<LoadInst>(&I))
280
275
{
281
276
load = builder.CreateAlignedLoad (LI->getType (), ptr, getAlign (*LI), LI->isVolatile (), LoadName);
277
+ generatedLoadStore = cast<Instruction>(load);
282
278
}
283
- else if (StoreInst * SI = dyn_cast<StoreInst>(&I))
279
+ else if (auto * SI = dyn_cast<StoreInst>(&I))
284
280
{
285
- builder.CreateAlignedStore (I.getOperand (0 ), ptr, getAlign (*SI), SI->isVolatile ());
281
+ generatedLoadStore = builder.CreateAlignedStore (I.getOperand (0 ), ptr, getAlign (*SI), SI->isVolatile ());
286
282
}
283
+ generatedLoadStores.push_back (generatedLoadStore);
287
284
288
285
builder.CreateBr (convergeBlock);
289
286
return BB;
@@ -345,22 +342,25 @@ void GenericAddressDynamicResolution::resolveGAS(Instruction& I, Value* pointerO
345
342
void GenericAddressDynamicResolution::resolveGASWithoutBranches (Instruction& I, Value* pointerOperand)
346
343
{
347
344
IGCLLVM::IRBuilder<> builder (&I);
348
- PointerType * pointerType = dyn_cast<PointerType>(pointerOperand->getType ());
345
+ auto * pointerType = dyn_cast<PointerType>(pointerOperand->getType ());
349
346
IGC_ASSERT ( pointerType != nullptr );
350
347
351
348
Value* nonLocalLoad = nullptr ;
349
+ Instruction* generatedLoadStore = nullptr ;
352
350
353
351
PointerType* ptrType = IGCLLVM::getWithSamePointeeType (pointerType, ADDRESS_SPACE_GLOBAL);
354
352
Value* globalPtr = builder.CreateAddrSpaceCast (pointerOperand, ptrType);
355
353
356
- if (LoadInst * LI = dyn_cast<LoadInst>(&I))
354
+ if (auto * LI = dyn_cast<LoadInst>(&I))
357
355
{
358
356
nonLocalLoad = builder.CreateAlignedLoad (LI->getType (), globalPtr, getAlign (*LI), LI->isVolatile (), " globalOrPrivateLoad" );
357
+ generatedLoadStore = cast<Instruction>(nonLocalLoad);
359
358
}
360
- else if (StoreInst * SI = dyn_cast<StoreInst>(&I))
359
+ else if (auto * SI = dyn_cast<StoreInst>(&I))
361
360
{
362
- builder.CreateAlignedStore (I.getOperand (0 ), globalPtr, getAlign (*SI), SI->isVolatile ());
361
+ generatedLoadStore = builder.CreateAlignedStore (I.getOperand (0 ), globalPtr, getAlign (*SI), SI->isVolatile ());
363
362
}
363
+ generatedLoadStores.push_back (generatedLoadStore);
364
364
365
365
if (nonLocalLoad != nullptr )
366
366
{
@@ -386,12 +386,12 @@ bool GenericAddressDynamicResolution::visitIntrinsicCall(CallInst& I)
386
386
{
387
387
IGC_ASSERT (IGCLLVM::getNumArgOperands (&I) == 1 );
388
388
Value* arg = I.getArgOperand (0 );
389
- PointerType * dstType = dyn_cast<PointerType>(I.getType ());
389
+ auto * dstType = dyn_cast<PointerType>(I.getType ());
390
390
IGC_ASSERT ( dstType != nullptr );
391
391
const unsigned targetAS = cast<PointerType>(I.getType ())->getAddressSpace ();
392
392
393
393
IGCLLVM::IRBuilder<> builder (&I);
394
- PointerType * pointerType = dyn_cast<PointerType>(arg->getType ());
394
+ auto * pointerType = dyn_cast<PointerType>(arg->getType ());
395
395
IGC_ASSERT ( pointerType != nullptr );
396
396
ConstantInt* globalTag = builder.getInt64 (0 ); // tag 000/111
397
397
ConstantInt* privateTag = builder.getInt64 (1 ); // tag 001
@@ -411,7 +411,7 @@ bool GenericAddressDynamicResolution::visitIntrinsicCall(CallInst& I)
411
411
// Force distinguishing private and global pointers if a kernel uses explicit casts.
412
412
// For more details please refer to section "Generic Address Space Explicit Casts" in
413
413
// documentation directory under igc/generic-pointers/generic-pointers.md
414
- auto ClContext = static_cast <OpenCLProgramContext*>(m_ctx);
414
+ auto * ClContext = static_cast <OpenCLProgramContext*>(m_ctx);
415
415
ClContext->setDistinguishBetweenPrivateAndGlobalPtr (true );
416
416
}
417
417
0 commit comments