@@ -106,6 +106,97 @@ char OpenCLPrintfResolution::ID = 0;
106
106
// | < vec_element_3 > |
107
107
// |------------------------------|
108
108
109
+ // Looks for a GlobalVariable related with given value.
110
+ // Returns nullptr if on the way to the global variable
111
+ // found anything that is not :
112
+ // * a CastInst
113
+ // * a GEP with non-zero indices
114
+ // * a SelectInst
115
+ // * a PHINode
116
+ // In case of select or phi instruction two operands are added to the vector.
117
+ // In another case only one is added.
118
+ inline SmallVector<Value*, 2 > getGlobalVariable (Value* const v)
119
+ {
120
+ SmallVector<Value *, 2 > curr;
121
+ curr.push_back (v);
122
+
123
+ while (nullptr != curr.front () || nullptr != curr.back ())
124
+ {
125
+ if (curr.size () == 1 && isa<GlobalVariable>(curr.front ()))
126
+ {
127
+ break ;
128
+ }
129
+ else if (curr.size () == 2 && (isa<GlobalVariable>(curr.front ()) && isa<GlobalVariable>(curr.back ())))
130
+ {
131
+ break ;
132
+ }
133
+
134
+ if (CastInst* castInst = dyn_cast<CastInst>(curr.front ()))
135
+ {
136
+ curr.pop_back ();
137
+ curr.push_back (castInst->getOperand (0 ));
138
+ }
139
+ else if (GetElementPtrInst* getElemPtrInst = dyn_cast<GetElementPtrInst>(curr.front ()))
140
+ {
141
+ if (curr.size () == 2 )
142
+ {
143
+ if (GetElementPtrInst* getElemPtrInst2 = dyn_cast<GetElementPtrInst>(curr.back ()))
144
+ {
145
+ curr.pop_back ();
146
+ curr.pop_back ();
147
+ curr.push_back (getElemPtrInst->hasAllZeroIndices () ? getElemPtrInst->getPointerOperand () : nullptr );
148
+ curr.push_back (getElemPtrInst2->hasAllZeroIndices () ? getElemPtrInst2->getPointerOperand () : nullptr );
149
+ }
150
+ }
151
+ else
152
+ {
153
+ curr.pop_back ();
154
+ curr.push_back (getElemPtrInst->hasAllZeroIndices () ? getElemPtrInst->getPointerOperand () : nullptr );
155
+ }
156
+ }
157
+ else if (SelectInst* selectInst = dyn_cast<SelectInst>(curr.front ()))
158
+ {
159
+ if (curr.size () == 2 )
160
+ {
161
+ // Nested select instruction is not supported
162
+ curr.front () = nullptr ;
163
+ curr.back () = nullptr ;
164
+ }
165
+ else
166
+ {
167
+ curr.pop_back ();
168
+ curr.push_back (selectInst->getOperand (1 ));
169
+ curr.push_back (selectInst->getOperand (2 ));
170
+ }
171
+ }
172
+ else if (PHINode* phiNode = dyn_cast<PHINode>(curr.front ()))
173
+ {
174
+ if (curr.size () == 2 )
175
+ {
176
+ // Nested phi instruction is not supported
177
+ curr.front () = nullptr ;
178
+ curr.back () = nullptr ;
179
+ }
180
+ else
181
+ {
182
+ curr.pop_back ();
183
+ curr.push_back (phiNode->getOperand (0 ));
184
+ curr.push_back (phiNode->getOperand (1 ));
185
+ }
186
+ }
187
+ else
188
+ {
189
+ // Unhandled value type
190
+ curr.front () = nullptr ;
191
+ if (curr.size () == 2 )
192
+ {
193
+ curr.back () = nullptr ;
194
+ }
195
+ }
196
+ }
197
+ return curr;
198
+ }
199
+
109
200
OpenCLPrintfResolution::OpenCLPrintfResolution () : FunctionPass(ID), m_atomicAddFunc(nullptr )
110
201
{
111
202
initializeOpenCLPrintfResolutionPass (*PassRegistry::getPassRegistry ());
@@ -225,24 +316,24 @@ std::string OpenCLPrintfResolution::getEscapedString(const ConstantDataSequentia
225
316
return Name;
226
317
}
227
318
228
- Value* OpenCLPrintfResolution::processPrintfString (Value* arg , Function& F)
319
+ Value* OpenCLPrintfResolution::processPrintfString (Value* printfArg , Function& F)
229
320
{
230
321
GlobalVariable* formatString = nullptr ;
231
-
232
- if (isa<GlobalVariable>(arg))
322
+ SmallVector<Value*, 2 > curr = getGlobalVariable (printfArg);
323
+ SmallVector<unsigned int , 2 > sv;
324
+ for (auto curr_i : curr)
233
325
{
234
- formatString = dyn_cast_or_null<GlobalVariable>(arg);
235
- if ((nullptr == formatString) || !formatString->hasInitializer ())
326
+ auto & curr_e = *curr_i;
327
+
328
+ formatString = dyn_cast_or_null<GlobalVariable>(&curr_e);
329
+ ConstantDataArray* formatStringConst = ((nullptr != formatString) && (formatString->hasInitializer ())) ?
330
+ dyn_cast<ConstantDataArray>(formatString->getInitializer ()) :
331
+ nullptr ;
332
+
333
+ if (nullptr == formatStringConst)
236
334
{
237
335
IGC_ASSERT_MESSAGE (0 , " Unexpected printf argument (expected string literal)" );
238
- return ConstantInt::get (m_int32Type, -1 );
239
- }
240
- ConstantDataArray* formatStringConst = dyn_cast<ConstantDataArray>(formatString->getInitializer ());
241
- std::string escaped_string = getEscapedString (formatStringConst);
242
-
243
- // preventing MD enries duplication
244
- if (m_MapStringStringIndex.find (escaped_string) != m_MapStringStringIndex.end ()) {
245
- return ConstantInt::get (m_int32Type, m_MapStringStringIndex[escaped_string]);
336
+ return 0 ;
246
337
}
247
338
248
339
if (m_CGContext->type == ShaderType::RAYTRACING_SHADER)
@@ -259,107 +350,78 @@ Value* OpenCLPrintfResolution::processPrintfString(Value* arg, Function& F)
259
350
Metadata* stringIndexVal = ConstantAsMetadata::get (
260
351
ConstantInt::get (m_int32Type, m_stringIndex));
261
352
353
+ sv.push_back (m_stringIndex++);
354
+
355
+ std::string escaped_string = getEscapedString (formatStringConst);
262
356
MDString* final_string = MDString::get (*m_context, escaped_string);
263
357
264
358
args.push_back (stringIndexVal);
265
359
args.push_back (final_string);
266
360
267
361
MDNode* itemMDNode = MDNode::get (*m_context, args);
268
362
namedMDNode->addOperand (itemMDNode);
269
-
270
- m_MapStringStringIndex[escaped_string] = m_stringIndex;
271
-
272
- return ConstantInt::get (m_int32Type, m_stringIndex++);
273
- }
274
- else if (CastInst* castInst = dyn_cast<CastInst>(arg))
275
- {
276
- return processPrintfString (castInst->getOperand (0 ), F);
277
- }
278
- else if (GetElementPtrInst* getElemPtrInst = dyn_cast<GetElementPtrInst>(arg))
279
- {
280
- IGC_ASSERT_MESSAGE (getElemPtrInst->hasAllZeroIndices (), " Only All Zero indices GEP supported" );
281
- return processPrintfString (getElemPtrInst->getPointerOperand (), F);
282
363
}
283
- else if (SelectInst* selectInst = dyn_cast<SelectInst>(arg))
284
- {
285
- SelectInst* selectInst2 = SelectInst::Create (selectInst->getOperand (0 ),
286
- processPrintfString (selectInst->getOperand (1 ), F),
287
- processPrintfString (selectInst->getOperand (2 ), F),
288
- " " , selectInst);
289
- return selectInst2;
290
- }
291
- else if (PHINode* phiNode = dyn_cast<PHINode>(arg))
364
+
365
+ // Checks if the vector have two elements.
366
+ // If it has it adds a new phi/select instruction that is responsible
367
+ // for the correct execution of the basic instruction.
368
+ // This information is forwarded to the store instruction.
369
+ if (curr.size () == 2 )
292
370
{
293
- unsigned inNum = phiNode->getNumIncomingValues ();
294
- PHINode* phiNode2 = PHINode::Create (m_int32Type, inNum, " " , phiNode);
295
- for (unsigned i = 0 ; i < inNum; i++)
371
+ if (GetElementPtrInst* getElemPtrInst = dyn_cast<GetElementPtrInst>(printfArg))
296
372
{
297
- phiNode2->addIncoming (processPrintfString (phiNode->getIncomingValue (i), F), phiNode->getIncomingBlock (i));
373
+ if (PHINode* phiNode = dyn_cast<PHINode>(getElemPtrInst->getPointerOperand ()))
374
+ {
375
+ PHINode* phiNode2 = PHINode::Create (m_int32Type, 2 , " " , phiNode);
376
+ phiNode2->addIncoming (ConstantInt::get (m_int32Type, sv.front ()), phiNode->getIncomingBlock (0 ));
377
+ phiNode2->addIncoming (ConstantInt::get (m_int32Type, sv.back ()), phiNode->getIncomingBlock (1 ));
378
+ return phiNode2;
379
+ }
380
+ }
381
+ else if (SelectInst* selectInst = dyn_cast<SelectInst>(printfArg))
382
+ {
383
+ SelectInst* selectInst2 = SelectInst::Create (selectInst->getOperand (0 ), ConstantInt::get (m_int32Type, sv.front ()),
384
+ ConstantInt::get (m_int32Type, sv.back ()), " " , selectInst);
385
+ return selectInst2;
386
+ }
387
+ else
388
+ {
389
+ IGC_ASSERT_MESSAGE (0 , " Instructions in the vector are not supported!" );
298
390
}
299
- return phiNode2;
300
- }
301
- else
302
- {
303
- IGC_ASSERT_MESSAGE (0 , " Unsupported Instruction!" );
304
391
}
305
392
306
393
ModuleMetaData* modMd = getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData ();
307
394
if (IGC_IS_FLAG_ENABLED (EnableZEBinary) || modMd->compOpt .EnableZEBinary )
308
395
{
309
- return arg ;
396
+ return printfArg ;
310
397
}
311
398
else
312
399
{
313
- return ConstantInt::get (m_int32Type, - 1 );
400
+ return ConstantInt::get (m_int32Type, m_stringIndex - 1 );
314
401
}
315
402
}
316
403
317
- // Checks pathes to global variables and returns true if all paths lead to constant strings.
318
- // Only these instructions acepted in pathes:
319
- // * a CastInst
320
- // * a GEP with all-zero indices
321
- // * a SelectInst
322
- // * a PHINode
323
- // It is expected that the paths are not looped.
324
- bool OpenCLPrintfResolution::argIsString (Value* arg)
404
+
405
+ bool OpenCLPrintfResolution::argIsString (Value* printfArg)
325
406
{
326
- if (isa<GlobalVariable>(arg))
407
+ GlobalVariable* formatString = nullptr ;
408
+ SmallVector<Value*, 2 > curr = getGlobalVariable (printfArg);
409
+
410
+ for (auto curr_i : curr)
327
411
{
328
- GlobalVariable* formatString = dyn_cast_or_null<GlobalVariable>(arg);
412
+ auto & curr_e = *curr_i;
413
+ formatString = dyn_cast_or_null<GlobalVariable>(&curr_e);
329
414
if (nullptr == formatString || !formatString->hasInitializer ())
330
415
{
331
416
return false ;
332
417
}
333
418
ConstantDataArray* formatStringConst = dyn_cast<ConstantDataArray>(formatString->getInitializer ());
334
419
if (!formatStringConst || !formatStringConst->isCString ())
335
420
{
336
- return false ;
337
- }
338
- return true ;
339
- }
340
- else if (CastInst* castInst = dyn_cast<CastInst>(arg))
341
- {
342
- return argIsString (castInst->getOperand (0 ));
343
- }
344
- if (GetElementPtrInst* getElemPtrInst = dyn_cast<GetElementPtrInst>(arg))
345
- {
346
- return getElemPtrInst->hasAllZeroIndices () && argIsString (getElemPtrInst->getPointerOperand ());
347
- }
348
- else if (SelectInst* selectInst = dyn_cast<SelectInst>(arg))
349
- {
350
- return argIsString (selectInst->getOperand (1 )) &&
351
- argIsString (selectInst->getOperand (2 ));
352
- }
353
- else if (PHINode* phiNode = dyn_cast<PHINode>(arg))
354
- {
355
- for (unsigned i = 0 ; i < phiNode->getNumIncomingValues (); i++)
356
- {
357
- if (!argIsString (phiNode->getIncomingValue (i)))
358
- return false ;
421
+ return false ;
359
422
}
360
- return true ;
361
423
}
362
- return false ;
424
+ return true ;
363
425
}
364
426
365
427
std::string OpenCLPrintfResolution::getPrintfStringsMDNodeName (Function& F)
0 commit comments