1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2018-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #include "GenCodeGenModule.h"
10 #include "Probe/Assertion.h"
11 #include "CLElfLib/ElfReader.h"
12 
13 #include "DebugInfo/ScalarVISAModule.h"
14 #include "DebugInfo/DwarfDebug.hpp"
15 #include "Compiler/CISACodeGen/DebugInfo.hpp"
16 
17 using namespace llvm;
18 using namespace IGC;
19 using namespace IGC::IGCMD;
20 using namespace std;
21 // ElfReader related typedefs
22 using namespace CLElfLib;
23 
24 char DebugInfoPass::ID = 0;
25 char CatchAllLineNumber::ID = 0;
26 
DebugInfoPass(CShaderProgram::KernelShaderMap & k)27 DebugInfoPass::DebugInfoPass(CShaderProgram::KernelShaderMap& k) :
28     ModulePass(ID),
29     kernels(k)
30 {
31     initializeMetaDataUtilsWrapperPass(*PassRegistry::getPassRegistry());
32 }
33 
~DebugInfoPass()34 DebugInfoPass::~DebugInfoPass()
35 {
36 }
37 
doInitialization(llvm::Module & M)38 bool DebugInfoPass::doInitialization(llvm::Module& M)
39 {
40     return true;
41 }
42 
doFinalization(llvm::Module & M)43 bool DebugInfoPass::doFinalization(llvm::Module& M)
44 {
45     return true;
46 }
47 
runOnModule(llvm::Module & M)48 bool DebugInfoPass::runOnModule(llvm::Module& M)
49 {
50     std::vector<CShader*> units;
51 
52     auto isCandidate = [](CShaderProgram* shaderProgram, SIMDMode m, ShaderDispatchMode mode = ShaderDispatchMode::NOT_APPLICABLE)
53     {
54         auto currShader = shaderProgram->GetShader(m, mode);
55         if (!currShader || !currShader->GetDebugInfoData().m_pDebugEmitter)
56             return (CShader*)nullptr;
57 
58         if (currShader->ProgramOutput()->m_programSize == 0)
59             return (CShader*)nullptr;
60 
61         return currShader;
62     };
63 
64     for (auto& k : kernels)
65     {
66         auto shaderProgram = k.second;
67         auto simd8 = isCandidate(shaderProgram, SIMDMode::SIMD8);
68         auto simd16 = isCandidate(shaderProgram, SIMDMode::SIMD16);
69         auto simd32 = isCandidate(shaderProgram, SIMDMode::SIMD32);
70 
71         if (simd8) units.push_back(simd8);
72         if (simd16) units.push_back(simd16);
73         if (simd32) units.push_back(simd32);
74     }
75 
76     DwarfDISubprogramCache DISPCache;
77 
78     for (auto& currShader : units)
79     {
80         // Look for the right CShaderProgram instance
81         m_currShader = currShader;
82 
83         MetaDataUtils* pMdUtils = m_currShader->GetMetaDataUtils();
84         if (!isEntryFunc(pMdUtils, m_currShader->entry))
85             continue;
86 
87         bool finalize = false;
88         unsigned int size = m_currShader->GetDebugInfoData().m_VISAModules.size();
89         m_pDebugEmitter = m_currShader->GetDebugInfoData().m_pDebugEmitter;
90         std::vector<std::pair<unsigned int, std::pair<llvm::Function*, IGC::VISAModule*>>> sortedVISAModules;
91 
92         // Sort modules in order of their placement in binary
93         DbgDecoder decodedDbg(m_currShader->ProgramOutput()->m_debugDataGenISA);
94         auto getGenOff = [&decodedDbg](std::vector<std::pair<unsigned int, unsigned int>>& data, unsigned int VISAIndex)
95         {
96             unsigned retval = 0;
97             for (auto& item : data)
98             {
99                 if (item.first == VISAIndex)
100                 {
101                     retval = item.second;
102                 }
103             }
104             return retval;
105         };
106 
107         auto getLastGenOff = [this, &decodedDbg, &getGenOff](IGC::VISAModule* v)
108         {
109             unsigned int genOff = 0;
110             // Detect last instructions of kernel. This information is absent in
111             // dbg info. So detect is as first instruction of first subroutine - 1.
112             // reloc_index, first sub inst's VISA id
113             std::unordered_map<uint32_t, unsigned int> firstSubVISAIndex;
114 
115             for (auto& item : decodedDbg.compiledObjs)
116             {
117                 firstSubVISAIndex[item.relocOffset] = item.CISAIndexMap.back().first;
118                 for (auto& sub : item.subs)
119                 {
120                     auto subStartVISAIndex = sub.startVISAIndex;
121                     if (firstSubVISAIndex[item.relocOffset] > subStartVISAIndex)
122                         firstSubVISAIndex[item.relocOffset] = subStartVISAIndex - 1;
123                 }
124             }
125 
126             for (auto& item : decodedDbg.compiledObjs)
127             {
128                 auto& name = item.kernelName;
129                 auto firstInst = (v->GetInstInfoMap()->begin())->first;
130                 auto funcName = firstInst->getParent()->getParent()->getName();
131                 if (item.subs.size() == 0 && funcName.compare(name) == 0)
132                 {
133                     genOff = item.CISAIndexMap.back().second;
134                 }
135                 else
136                 {
137                     if (funcName.compare(name) == 0)
138                     {
139                         genOff = getGenOff(item.CISAIndexMap, firstSubVISAIndex[item.relocOffset]);
140                         break;
141                     }
142                     for (auto& sub : item.subs)
143                     {
144                         auto& subName = sub.name;
145                         if (funcName.compare(subName) == 0)
146                         {
147                             genOff = getGenOff(item.CISAIndexMap, sub.endVISAIndex);
148                             break;
149                         }
150                     }
151                 }
152 
153                 if (genOff)
154                     break;
155             }
156 
157             return genOff;
158         };
159 
160         auto setType = [&decodedDbg](VISAModule* v)
161         {
162             auto firstInst = (v->GetInstInfoMap()->begin())->first;
163             auto funcName = firstInst->getParent()->getParent()->getName();
164 
165             for (auto& item : decodedDbg.compiledObjs)
166             {
167                 auto& name = item.kernelName;
168                 if (funcName.compare(name) == 0)
169                 {
170                     if (item.relocOffset == 0)
171                         v->SetType(VISAModule::ObjectType::KERNEL);
172                     else
173                         v->SetType(VISAModule::ObjectType::STACKCALL_FUNC);
174                     return;
175                 }
176                 for (auto& sub : item.subs)
177                 {
178                     auto& subName = sub.name;
179                     if (funcName.compare(subName) == 0)
180                     {
181                         v->SetType(VISAModule::ObjectType::SUBROUTINE);
182                         return;
183                     }
184                 }
185             }
186         };
187 
188         for (auto& m : m_currShader->GetDebugInfoData().m_VISAModules)
189         {
190             setType(m.second);
191             auto lastVISAId = getLastGenOff(m.second);
192             // getLastGenOffset returns zero iff debug info for given function
193             // was not found, skip the function in such case. This can happen,
194             // when the function was optimized away but the definition is still
195             // present inside the module.
196             if (lastVISAId == 0)
197               continue;
198             sortedVISAModules.push_back(std::make_pair(lastVISAId, std::make_pair(m.first, m.second)));
199         }
200 
201         std::sort(sortedVISAModules.begin(), sortedVISAModules.end(),
202             [](std::pair<unsigned int, std::pair<llvm::Function*, IGC::VISAModule*>>& p1,
203                 std::pair<unsigned int, std::pair<llvm::Function*, IGC::VISAModule*>>& p2)
204         {
205             return p1.first < p2.first;
206         });
207 
208         m_pDebugEmitter->SetDISPCache(&DISPCache);
209         for (auto& m : sortedVISAModules)
210         {
211             m_pDebugEmitter->registerVISA(m.second.second);
212         }
213 
214         std::vector<llvm::Function*> functions;
215         std::for_each(sortedVISAModules.begin(), sortedVISAModules.end(),
216             [&functions](auto& item) { functions.push_back(item.second.first); });
217 
218         for (auto& m : sortedVISAModules)
219         {
220             m_pDebugEmitter->setCurrentVISA(m.second.second);
221 
222             if (--size == 0)
223                 finalize = true;
224 
225             EmitDebugInfo(finalize, &decodedDbg);
226         }
227 
228         // set VISA dbg info to nullptr to indicate 1-step debug is enabled
229         currShader->ProgramOutput()->m_debugDataGenISASize = 0;
230         currShader->ProgramOutput()->m_debugDataGenISA = nullptr;
231 
232         if (finalize)
233         {
234             IDebugEmitter::Release(m_pDebugEmitter);
235         }
236     }
237 
238     return false;
239 }
240 
debugDump(const CShader * Shader,llvm::StringRef Ext,ArrayRef<char> Blob)241 static void debugDump(const CShader* Shader, llvm::StringRef Ext,
242                       ArrayRef<char> Blob)
243 {
244     if (Blob.empty())
245         return;
246 
247     auto ExtStr = Ext.str();
248     std::string DumpName = IGC::Debug::GetDumpName(Shader, ExtStr.c_str());
249     FILE* const DumpFile = fopen(DumpName.c_str(), "wb+");
250     if (nullptr == DumpFile)
251         return;
252 
253     fwrite(Blob.data(), Blob.size(), 1, DumpFile);
254     fclose(DumpFile);
255 }
256 
EmitDebugInfo(bool finalize,DbgDecoder * decodedDbg)257 void DebugInfoPass::EmitDebugInfo(bool finalize, DbgDecoder* decodedDbg)
258 {
259     IGC_ASSERT(m_pDebugEmitter);
260 
261     std::vector<char> buffer = m_pDebugEmitter->Finalize(finalize, decodedDbg);
262 
263     if (IGC_IS_FLAG_ENABLED(ShaderDumpEnable) || IGC_IS_FLAG_ENABLED(ElfDumpEnable))
264         debugDump(m_currShader, "elf", { buffer.data(), buffer.size() });
265 
266     const std::string& DbgErrors = m_pDebugEmitter->getErrors();
267     if (IGC_IS_FLAG_ENABLED(ShaderDumpEnable))
268         debugDump(m_currShader, "dbgerr", { DbgErrors.data(), DbgErrors.size() });
269 
270     void* dbgInfo = IGC::aligned_malloc(buffer.size(), sizeof(void*));
271     if (dbgInfo)
272         memcpy_s(dbgInfo, buffer.size(), buffer.data(), buffer.size());
273 
274     SProgramOutput* pOutput = m_currShader->ProgramOutput();
275     pOutput->m_debugData = dbgInfo;
276     pOutput->m_debugDataSize = dbgInfo ? buffer.size() : 0;
277 }
278 
279 // Mark privateBase aka ImplicitArg::PRIVATE_BASE as Output for debugging
markOutputPrivateBase(CShader * pShader,IDebugEmitter * pDebugEmitter)280 void DebugInfoData::markOutputPrivateBase(CShader* pShader, IDebugEmitter* pDebugEmitter)
281 {
282     IGC_ASSERT_MESSAGE(IGC_IS_FLAG_ENABLED(UseOffsetInLocation), "UseOffsetInLocation not enabled");
283 
284     if (pShader->GetContext()->getModuleMetaData()->compOpt.OptDisable)
285     {
286         CVariable* pVar = pShader->GetPrivateBase();
287         if (pVar)
288         {
289             // cache privateBase as it may be destroyed if subroutine
290             // is emitted.
291             pDebugEmitter->getCurrentVISA()->setPrivateBase(pVar);
292             pShader->GetEncoder().GetVISAKernel()->AddAttributeToVar(pVar->visaGenVariable[0], "Output", 0, nullptr);
293             if (pShader->m_dispatchSize == SIMDMode::SIMD32 && pVar->visaGenVariable[1])
294             {
295                 IGC_ASSERT_MESSAGE(false, "Private base expected to be a scalar!");  // Should never happen
296                 pShader->GetEncoder().GetVISAKernel()->AddAttributeToVar(pVar->visaGenVariable[1], "Output", 0, nullptr);
297             }
298         }
299     }
300 }
301 
markOutputVar(CShader * pShader,IDebugEmitter * pDebugEmitter,llvm::Instruction * pInst,const char * pMetaDataName)302 void DebugInfoData::markOutputVar(CShader* pShader, IDebugEmitter* pDebugEmitter, llvm::Instruction* pInst, const char* pMetaDataName)
303 {
304     Value* pValue = dyn_cast<Value>(pInst);
305 
306     IGC_ASSERT_MESSAGE(IGC_IS_FLAG_ENABLED(UseOffsetInLocation), "UseOffsetInLocation not enabled");
307     IGC_ASSERT_MESSAGE(pInst, "Missing instruction");
308 
309     CVariable* pVar = pShader->GetSymbol(pValue);
310     if (pVar->GetVarType() == EVARTYPE_GENERAL)
311     {
312         // If UseOffsetInLocation is enabled, we want to attach "Output" attribute to:
313         // 1. Per thread offset only, and/or
314         // 2. Compute thread and global identification variables.
315         // So that finalizer can extend their liveness to end of the program.
316         // This will help debugger examine their values anywhere in the code till they
317         // are in scope. However, emit "Output" attribute when -g and -cl-opt-disable
318         // are both passed -g by itself shouldnt alter generated code.
319         if (pShader->GetContext()->getModuleMetaData()->compOpt.OptDisable)
320         {
321             // If "Output" attribute is emitted for perThreadOffset variable(s)
322             // then debug info emission is preserved for this:
323             // privateBaseMem + perThreadOffset + (simdSize*offImm + simd_lane*sizeof(elem))
324             if (Instruction* pPTOorImplicitGIDInst = dyn_cast<Instruction>(pValue))
325             {
326                 MDNode* pPTOorImplicitGIDInstMD = pPTOorImplicitGIDInst->getMetadata(pMetaDataName); // "perThreadOffset" or "implicitGlobalID"
327                 if (pPTOorImplicitGIDInstMD)
328                 {
329                     pShader->GetEncoder().GetVISAKernel()->AddAttributeToVar(pVar->visaGenVariable[0], "Output", 0, nullptr);
330                     if (pShader->m_dispatchSize == SIMDMode::SIMD32 && pVar->visaGenVariable[1])
331                     {
332                         pShader->GetEncoder().GetVISAKernel()->AddAttributeToVar(pVar->visaGenVariable[1], "Output", 0, nullptr);
333                     }
334                 }
335             }
336         }
337     }
338     else
339     {
340         // Unexpected return empty location!
341         IGC_ASSERT_MESSAGE(false, "No debug info value!");
342     }
343 }
344 
markOutput(llvm::Function & F,CShader * pShader,IDebugEmitter * pDebugEmitter)345 void DebugInfoData::markOutput(llvm::Function& F, CShader* pShader, IDebugEmitter* pDebugEmitter)
346 {
347     IGC_ASSERT_MESSAGE(pDebugEmitter, "Missing debug emitter");
348     VISAModule* visaModule = pDebugEmitter->getCurrentVISA();
349     IGC_ASSERT_MESSAGE(visaModule, "Missing visa module");
350 
351     for (auto& bb : F)
352     {
353         for (auto& pInst : bb)
354         {
355             if (MDNode* perThreadOffsetMD = pInst.getMetadata("perThreadOffset"))
356             {
357                 // Per Thread Offset non-debug instruction must have 'Output' attribute
358                 // added in the function to be called.
359                 markOutputVar(pShader, pDebugEmitter, &pInst, "perThreadOffset");
360                 if (F.getCallingConv() == CallingConv::SPIR_KERNEL)
361                 {
362                     markOutputPrivateBase(pShader, pDebugEmitter); // Mark privateBase aka ImplicitArg::PRIVATE_BASE as Output for debugging
363                 }
364                 else
365                 {
366                     // TODO: Apply privateBase of kernel to SPIR_FUNC if its a subroutine
367                 }
368                 ScalarVisaModule* scVISAModule = (ScalarVisaModule*)visaModule;
369                 IGC_ASSERT_MESSAGE(scVISAModule->getPerThreadOffset()==nullptr, "setPerThreadOffset was set earlier");
370                 scVISAModule->setPerThreadOffset(&pInst);
371                 if (((OpenCLProgramContext*)(pShader->GetContext()))->m_InternalOptions.KernelDebugEnable == false)
372                 {
373                     return;
374                 }
375             }
376         }
377     }
378 
379     if (((OpenCLProgramContext*)(pShader->GetContext()))->m_InternalOptions.KernelDebugEnable)
380     {
381         // Compute thread and group identification instructions will be marked here
382         // regardless of stack calls detection in this shader, so not only when per thread offset
383         // as well as a private base have been marked as Output earlier in this function.
384         // When stack calls are in use then only these group ID instructions are marked as Output.
385         for (auto& bb : F)
386         {
387             for (auto& pInst : bb)
388             {
389                 if (MDNode* implicitGlobalIDMD = pInst.getMetadata("implicitGlobalID"))
390                 {
391                     // Compute thread and group identification instructions must have
392                     // 'Output' attribute added in the function to be called.
393                     markOutputVar(pShader, pDebugEmitter, &pInst, "implicitGlobalID");
394                 }
395             }
396         }
397     }
398 }
399 
markOutput(llvm::Function & F,CShader * m_currShader)400 void DebugInfoData::markOutput(llvm::Function& F, CShader* m_currShader)
401 {
402     for (auto& bb : F)
403     {
404         for (auto& pInst : bb)
405         {
406             markOutputVars(&pInst);
407         }
408     }
409 }
410 
markOutputVars(const llvm::Instruction * pInst)411 void DebugInfoData::markOutputVars(const llvm::Instruction* pInst)
412 {
413     const Value* pVal = nullptr;
414     if (const DbgDeclareInst * pDbgAddrInst = dyn_cast<DbgDeclareInst>(pInst))
415     {
416         pVal = pDbgAddrInst->getAddress();
417     }
418     else if (const DbgValueInst * pDbgValInst = dyn_cast<DbgValueInst>(pInst))
419     {
420         pVal = pDbgValInst->getValue();
421     }
422     else
423     {
424         return;
425     }
426 
427     if (!pVal || isa<UndefValue>(pVal))
428     {
429         // No debug info value, return empty location!
430         return;
431     }
432 
433     if (dyn_cast<Constant>(pVal))
434     {
435         if (!isa<GlobalVariable>(pVal) && !isa<ConstantExpr>(pVal))
436         {
437             return;
438         }
439     }
440 
441     Value* pValue = const_cast<Value*>(pVal);
442     if (isa<GlobalVariable>(pValue))
443     {
444         return;
445     }
446 
447     if (!m_pShader->IsValueUsed(pValue)) {
448         return;
449     }
450 
451     CVariable* pVar = m_pShader->GetSymbol(pValue);
452     if (pVar->GetVarType() == EVARTYPE_GENERAL)
453     {
454         // We want to attach "Output" attribute to all variables:
455         // - if UseOffsetInLocation is disabled, or
456         // - if UseOffsetInLocation is enabled but there is a stack call in use,
457         // so that finalizer can extend their liveness to end of
458         // the program. This will help debugger examine their
459         // values anywhere in the code till they are in scope.
460         if (m_outputVals.find(pVar) == m_outputVals.end())
461         {
462             if (m_pShader->GetContext()->getModuleMetaData()->compOpt.OptDisable)
463             {
464                 // Emit "Output" attribute only when -g and -cl-opt-disable are both passed
465                 // -g by itself shouldnt alter generated code
466                 m_pShader->GetEncoder().GetVISAKernel()->AddAttributeToVar(pVar->visaGenVariable[0], "Output", 0, nullptr);
467                 if (m_pShader->m_dispatchSize == SIMDMode::SIMD32 && pVar->visaGenVariable[1])
468                 {
469                     m_pShader->GetEncoder().GetVISAKernel()->AddAttributeToVar(pVar->visaGenVariable[1], "Output", 0, nullptr);
470                 }
471                 (void)m_outputVals.insert(pVar);
472             }
473         }
474     }
475 }
476 
hasDebugInfo(CShader * pShader)477 bool IGC::DebugInfoData::hasDebugInfo(CShader* pShader)
478 {
479     return pShader->GetContext()->m_instrTypes.hasDebugInfo;
480 }
481 
transferMappings(const llvm::Function & F)482 void DebugInfoData::transferMappings(const llvm::Function& F)
483 {
484     auto cacheMapping = [this](llvm::DenseMap<llvm::Value*, CVariable*>& Map)
485     {
486         for (auto& mapping : Map)
487         {
488             auto CVar = mapping.second;
489             if (CVar->visaGenVariable[0])
490             {
491                 unsigned int lower16Channels = (unsigned int)m_pShader->GetEncoder().GetVISAKernel()->getDeclarationID(CVar->visaGenVariable[0]);
492                 unsigned int higher16Channels = 0;
493                 if (numLanes(m_pShader->m_dispatchSize) == 32 && !CVar->IsUniform() && CVar->visaGenVariable[1])
494                     higher16Channels = m_pShader->GetEncoder().GetVISAKernel()->getDeclarationID(CVar->visaGenVariable[1]);
495                 CVarToVISADclId[CVar] = std::make_pair(lower16Channels, higher16Channels);
496             }
497         }
498     };
499 
500     // Store llvm::Value->CVariable mappings from CShader.
501     // CShader clears these mappings before compiling a new function.
502     // Debug info is computed after all functions are compiled.
503     // This instance stores mappings per llvm::Function so debug
504     // info generation can emit variable locations correctly.
505     auto& SymbolMapping = m_pShader->GetSymbolMapping();
506     m_FunctionSymbols[&F] = SymbolMapping;
507 
508     // VISA builder gets destroyed at end of EmitVISAPass.
509     // Debug info pass is invoked later. We need a way to
510     // preserve mapping of CVariable -> VISA reg# so that
511     // we can emit location information in debug info. This
512     // code below iterates over all CVariable instances and
513     // retrieves and stored their VISA reg# in a map. This
514     // map is later queried by debug info pass.
515     cacheMapping(SymbolMapping);
516 
517     auto& GlobalSymbolMapping = m_pShader->GetGlobalMapping();
518     cacheMapping(GlobalSymbolMapping);
519 
520     if (m_pShader->hasFP())
521     {
522         auto FP = m_pShader->GetFP();
523         auto VISADclIdx = m_pShader->GetEncoder().GetVISAKernel()->getDeclarationID(FP->visaGenVariable[0]);
524         CVarToVISADclId[FP] = std::make_pair(VISADclIdx, 0);
525     }
526 }
527 
getMapping(const llvm::Function & F,const llvm::Value * V)528 CVariable* DebugInfoData::getMapping(const llvm::Function& F, const llvm::Value* V)
529 {
530     auto& Data = m_FunctionSymbols[&F];
531     auto Iter = Data.find(V);
532     if (Iter != Data.end())
533         return (*Iter).second;
534     return nullptr;
535 }
536 
537 // Register pass to igc-opt
538 #define PASS_FLAG "igc-catch-all-linenum"
539 #define PASS_DESCRIPTION "CatchAllLineNumber pass"
540 #define PASS_CFG_ONLY false
541 #define PASS_ANALYSIS false
IGC_INITIALIZE_PASS_BEGIN(CatchAllLineNumber,PASS_FLAG,PASS_DESCRIPTION,PASS_CFG_ONLY,PASS_ANALYSIS)542 IGC_INITIALIZE_PASS_BEGIN(CatchAllLineNumber, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
543 IGC_INITIALIZE_PASS_END(CatchAllLineNumber, PASS_FLAG, PASS_DESCRIPTION, PASS_CFG_ONLY, PASS_ANALYSIS)
544 
545 CatchAllLineNumber::CatchAllLineNumber() :
546     FunctionPass(ID)
547 {
548     initializeMetaDataUtilsWrapperPass(*PassRegistry::getPassRegistry());
549 }
550 
~CatchAllLineNumber()551 CatchAllLineNumber::~CatchAllLineNumber()
552 {
553 }
554 
runOnFunction(llvm::Function & F)555 bool CatchAllLineNumber::runOnFunction(llvm::Function& F)
556 {
557     // Insert placeholder intrinsic instruction in each kernel.
558     if (!F.getSubprogram() || F.isDeclaration())
559         return false;
560 
561     if (F.getCallingConv() != llvm::CallingConv::SPIR_KERNEL)
562         return false;
563 
564     llvm::IRBuilder<> Builder(F.getParent()->getContext());
565     DIBuilder di(*F.getParent());
566     Function* lineNumPlaceholder = GenISAIntrinsic::getDeclaration(F.getParent(), GenISAIntrinsic::ID::GenISA_CatchAllDebugLine);
567     auto intCall = Builder.CreateCall(lineNumPlaceholder);
568 
569     auto line = F.getSubprogram()->getLine();
570     auto scope = F.getSubprogram();
571 
572     auto dbg = DILocation::get(F.getParent()->getContext(), line, 0, scope);
573 
574     intCall->setDebugLoc(dbg);
575 
576     intCall->insertBefore(&*F.getEntryBlock().getFirstInsertionPt());
577 
578     return true;
579 }
580