@@ -106,6 +106,97 @@ char OpenCLPrintfResolution::ID = 0;
106106//  |      < vec_element_3 >       |
107107//  |------------------------------|
108108
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+ 
109200OpenCLPrintfResolution::OpenCLPrintfResolution () : FunctionPass(ID), m_atomicAddFunc(nullptr )
110201{
111202    initializeOpenCLPrintfResolutionPass (*PassRegistry::getPassRegistry ());
@@ -225,24 +316,24 @@ std::string OpenCLPrintfResolution::getEscapedString(const ConstantDataSequentia
225316    return  Name;
226317}
227318
228- Value* OpenCLPrintfResolution::processPrintfString (Value* arg , Function& F)
319+ Value* OpenCLPrintfResolution::processPrintfString (Value* printfArg , Function& F)
229320{
230321    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)
233325    {
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)
236334        {
237335            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 ;
246337        }
247338
248339        if  (m_CGContext->type  == ShaderType::RAYTRACING_SHADER)
@@ -259,107 +350,78 @@ Value* OpenCLPrintfResolution::processPrintfString(Value* arg, Function& F)
259350        Metadata* stringIndexVal = ConstantAsMetadata::get (
260351            ConstantInt::get (m_int32Type, m_stringIndex));
261352
353+         sv.push_back (m_stringIndex++);
354+ 
355+         std::string escaped_string = getEscapedString (formatStringConst);
262356        MDString* final_string = MDString::get (*m_context, escaped_string);
263357
264358        args.push_back (stringIndexVal);
265359        args.push_back (final_string);
266360
267361        MDNode* itemMDNode = MDNode::get (*m_context, args);
268362        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);
282363    }
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-             " " 
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 )
292370    {
293-         unsigned  inNum = phiNode->getNumIncomingValues ();
294-         PHINode* phiNode2 = PHINode::Create (m_int32Type, inNum, " " 
295-         for  (unsigned  i = 0 ; i < inNum; i++)
371+         if  (GetElementPtrInst* getElemPtrInst = dyn_cast<GetElementPtrInst>(printfArg))
296372        {
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 , " " 
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 ()), " " 
385+             return  selectInst2;
386+         }
387+         else 
388+         {
389+             IGC_ASSERT_MESSAGE (0 , " Instructions in the vector are not supported!" 
298390        }
299-         return  phiNode2;
300-     }
301-     else 
302-     {
303-         IGC_ASSERT_MESSAGE (0 , " Unsupported Instruction!" 
304391    }
305392
306393    ModuleMetaData* modMd = getAnalysis<MetaDataUtilsWrapper>().getModuleMetaData ();
307394    if  (IGC_IS_FLAG_ENABLED (EnableZEBinary) || modMd->compOpt .EnableZEBinary )
308395    {
309-         return  arg ;
396+         return  printfArg ;
310397    }
311398    else 
312399    {
313-         return  ConstantInt::get (m_int32Type, - 1 );
400+         return  ConstantInt::get (m_int32Type, m_stringIndex -  1 );
314401    }
315402}
316403
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)
325406{
326-     if  (isa<GlobalVariable>(arg))
407+     GlobalVariable* formatString = nullptr ;
408+     SmallVector<Value*, 2 > curr = getGlobalVariable (printfArg);
409+ 
410+     for  (auto  curr_i : curr)
327411    {
328-         GlobalVariable* formatString = dyn_cast_or_null<GlobalVariable>(arg);
412+         auto & curr_e = *curr_i;
413+         formatString = dyn_cast_or_null<GlobalVariable>(&curr_e);
329414        if  (nullptr  == formatString || !formatString->hasInitializer ())
330415        {
331416            return  false ;
332417        }
333418        ConstantDataArray* formatStringConst = dyn_cast<ConstantDataArray>(formatString->getInitializer ());
334419        if  (!formatStringConst || !formatStringConst->isCString ())
335420        {
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 ;
359422        }
360-         return  true ;
361423    }
362-     return  false ;
424+     return  true ;
363425}
364426
365427std::string OpenCLPrintfResolution::getPrintfStringsMDNodeName (Function& F)
0 commit comments