@@ -19,8 +19,10 @@ SPDX-License-Identifier: MIT
19
19
#include < llvm/IR/Instructions.h>
20
20
#include < llvm/Demangle/Demangle.h>
21
21
#include < llvm/IR/Mangler.h>
22
+ #include < llvm/Support/Regex.h>
22
23
#include " common/LLVMWarningsPop.hpp"
23
24
#include < iostream>
25
+
24
26
using namespace llvm ;
25
27
using namespace IGC ;
26
28
@@ -124,6 +126,65 @@ void HandleSpirvDecorationMetadata::visitStoreInst(StoreInst& I)
124
126
}
125
127
}
126
128
129
+ void HandleSpirvDecorationMetadata::visit2DBlockReadCallInst (CallInst& I, StringRef unmangledName)
130
+ {
131
+ Value* ptr = I.getArgOperand (0 );
132
+ auto spirvDecorations = parseSPIRVDecorationsFromMD (ptr);
133
+ for (auto & [DecorationId, MDNodes] : spirvDecorations)
134
+ {
135
+ switch (DecorationId)
136
+ {
137
+ // IDecCacheControlLoadINTEL
138
+ case DecorationIdCacheControlLoad:
139
+ {
140
+ handleCacheControlINTELFor2DBlockIO<LoadCacheControl>(I, MDNodes, unmangledName);
141
+ break ;
142
+ }
143
+ }
144
+ }
145
+ }
146
+
147
+ void HandleSpirvDecorationMetadata::visit2DBlockWriteCallInst (CallInst& I, StringRef unmangledName)
148
+ {
149
+ Value* ptr = I.getArgOperand (0 );
150
+ auto spirvDecorations = parseSPIRVDecorationsFromMD (ptr);
151
+ for (auto & [DecorationId, MDNodes] : spirvDecorations)
152
+ {
153
+ switch (DecorationId)
154
+ {
155
+ // IDecCacheControlStoreINTEL
156
+ case DecorationIdCacheControlStore:
157
+ {
158
+ handleCacheControlINTELFor2DBlockIO<StoreCacheControl>(I, MDNodes, unmangledName);
159
+ break ;
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+ void HandleSpirvDecorationMetadata::visitCallInst (CallInst& I)
166
+ {
167
+ Function* F = I.getCalledFunction ();
168
+ if (!F) return ;
169
+
170
+ Regex pattern2DBlockRead (
171
+ " _Z[0-9]+(intel_sub_group_2d_block_(prefetch|read|read_transform|read_transpose)_[0-9]+b_[0-9]+r[0-9]+x[0-9]+c)" );
172
+ Regex pattern2DBlockWrite (
173
+ " _Z[0-9]+(intel_sub_group_2d_block_write_[0-9]+b_[0-9]+r[0-9]+x[0-9]+c)" );
174
+
175
+ SmallVector<StringRef, 4 > Matches;
176
+ StringRef funcName = F->getName ();
177
+
178
+ if (pattern2DBlockRead.match (funcName, &Matches))
179
+ {
180
+ visit2DBlockReadCallInst (I, Matches[1 ]);
181
+ }
182
+ else if (pattern2DBlockWrite.match (funcName, &Matches))
183
+ {
184
+ visit2DBlockWriteCallInst (I, Matches[1 ]);
185
+ }
186
+ }
187
+
127
188
template <typename T>
128
189
void HandleSpirvDecorationMetadata::handleCacheControlINTEL (Instruction& I, SmallPtrSetImpl<MDNode*>& MDNodes)
129
190
{
@@ -141,3 +202,38 @@ void HandleSpirvDecorationMetadata::handleCacheControlINTEL(Instruction& I, Smal
141
202
I.setMetadata (" lsc.cache.ctrl" , CacheCtrlNode);
142
203
m_changed = true ;
143
204
}
205
+
206
+ template <typename T>
207
+ void HandleSpirvDecorationMetadata::handleCacheControlINTELFor2DBlockIO (CallInst& I, SmallPtrSetImpl<MDNode*>& MDNodes, StringRef unmangledName)
208
+ {
209
+ static_assert (std::is_same_v<T, LoadCacheControl> || std::is_same_v<T, StoreCacheControl>);
210
+ CacheControlFromMDNodes cacheControl = resolveCacheControlFromMDNodes<T>(m_pCtx, MDNodes);
211
+ if (cacheControl.isEmpty ) return ;
212
+ if (cacheControl.isInvalid )
213
+ {
214
+ m_pCtx->EmitWarning (" Unsupported cache controls configuration requested. Applying default configuration." );
215
+ return ;
216
+ }
217
+
218
+ Function* F = I.getCalledFunction ();
219
+ IGC_ASSERT (F);
220
+
221
+ SmallVector<Value*, 4 > args (I.args ());
222
+ args.push_back (ConstantInt::get (Type::getInt32Ty (I.getContext ()), cacheControl.value ));
223
+
224
+ SmallVector<Type*, 4 > argTypes;
225
+ for (const auto & arg : args)
226
+ argTypes.push_back (arg->getType ());
227
+
228
+ FunctionType* FT = FunctionType::get (I.getType (), argTypes, false );
229
+ std::string newFuncName = " __internal_" + unmangledName.str () + " _cache_controls" ;
230
+ auto newFunction = m_Module->getOrInsertFunction (newFuncName, FT);
231
+
232
+ auto newCall = CallInst::Create (newFunction, args, " " , &I);
233
+ I.replaceAllUsesWith (newCall);
234
+ I.eraseFromParent ();
235
+
236
+ // Cleanup unused function if all calls have been replaced with the internal version
237
+ if (F->getNumUses () == 0 )
238
+ F->eraseFromParent ();
239
+ }
0 commit comments