1 | /** |
2 | * Copyright (c) Glow Contributors. See CONTRIBUTORS file. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | #include "glow/LLVMIRCodeGen/AllocationsInfo.h" |
18 | #include "glow/LLVMIRCodeGen/CommandLine.h" |
19 | |
20 | #include "glow/Graph/Graph.h" |
21 | #include "glow/IR/IRUtils.h" |
22 | #include "glow/IR/Instrs.h" |
23 | #include "glow/LLVMIRCodeGen/LLVMIRGen.h" |
24 | |
25 | #include "llvm/IR/DebugInfo.h" |
26 | #include "llvm/IR/Verifier.h" |
27 | #include "llvm/Support/FileSystem.h" |
28 | #include "llvm/Support/Path.h" |
29 | #include <fstream> |
30 | |
31 | using namespace glow; |
32 | using llvm::cast; |
33 | using llvm::DISubprogram; |
34 | using llvm::dyn_cast; |
35 | using llvm::isa; |
36 | |
37 | extern llvm::cl::opt<bool> emitDebugInfo; |
38 | |
39 | void LLVMIRGen::setCurrentDebugLocation(llvm::IRBuilder<> &builder, |
40 | const glow::Instruction *I) { |
41 | if (!emitDebugInfo) |
42 | return; |
43 | auto instrNum = instrNumbering_->getInstrNumber(I); |
44 | // Get current function. |
45 | llvm::Function *F = builder.GetInsertPoint()->getParent()->getParent(); |
46 | // Get a debug scope for the current function. |
47 | auto *DIFunction = getOrCreateFunctionDebugInfo(F, dbgInfo_.mainFile_, |
48 | dbgInfo_.mainFile_, 0); |
49 | auto DILoc = llvm::DILocation::get( |
50 | getLLVMContext(), dbgInfo_.mainFileFirstInstrLineNo_ + instrNum, 0, |
51 | DIFunction); |
52 | llvm::DebugLoc loc(DILoc); |
53 | builder.SetCurrentDebugLocation(loc); |
54 | } |
55 | |
56 | llvm::DIType *LLVMIRGen::getDebugType(llvm::IRBuilder<> &builder, |
57 | llvm::Type *ty) { |
58 | // Check if the debug info for the type is in the cache and use it, if it is |
59 | // available. |
60 | if (dbgInfo_.DITypes_.count(ty)) |
61 | return dbgInfo_.DITypes_[ty]; |
62 | llvm::DIType *DITy{nullptr}; |
63 | if (ty == builder.getVoidTy()) { |
64 | DITy = nullptr; |
65 | } else if (ty == builder.getFloatTy()) { |
66 | DITy = DIBuilder_->createBasicType("float" , sizeof(float) * 8, |
67 | llvm::dwarf::DW_ATE_float); |
68 | } else if (ty == builder.getIntNTy(sizeof(size_t) * 8)) { |
69 | DITy = DIBuilder_->createBasicType("size_t" , sizeof(size_t) * 8, |
70 | llvm::dwarf::DW_ATE_unsigned); |
71 | } else if (auto *intTy = dyn_cast<llvm::IntegerType>(ty)) { |
72 | std::string tyName = "int" + std::to_string(intTy->getBitWidth()); |
73 | DITy = DIBuilder_->createBasicType(tyName, intTy->getBitWidth(), |
74 | llvm::dwarf::DW_ATE_unsigned); |
75 | } else if (ty->isPointerTy()) { |
76 | std::string tyName = "ptr" + std::to_string(dbgInfo_.DITypes_.size()); |
77 | DITy = DIBuilder_->createPointerType( |
78 | getDebugType(builder, ty->getPointerElementType()), sizeof(void *) * 8); |
79 | } else { |
80 | llvm_unreachable("Cannot create DWARF debug type for an LLVM type" ); |
81 | } |
82 | dbgInfo_.DITypes_[ty] = DITy; |
83 | return DITy; |
84 | } |
85 | |
86 | static llvm::DebugLoc getDebugLoc(unsigned Line, unsigned Col, |
87 | const llvm::MDNode *Scope) { |
88 | |
89 | #if LLVM_VERSION_MAJOR < 12 |
90 | return llvm::DebugLoc::get(Line, Col, Scope); |
91 | #else |
92 | // If no scope is available, this is an unknown location. |
93 | if (!Scope) |
94 | return llvm::DebugLoc(); |
95 | |
96 | return llvm::DILocation::get(Scope->getContext(), Line, Col, |
97 | const_cast<llvm::MDNode *>(Scope), nullptr, |
98 | false); |
99 | #endif |
100 | } |
101 | |
102 | void LLVMIRGen::generateFunctionDebugInfo(llvm::Function *F) { |
103 | if (!emitDebugInfo) |
104 | return; |
105 | // First, generate a DISubprogram for the function. |
106 | auto *DIFunction = getOrCreateFunctionDebugInfo(F, dbgInfo_.mainFile_, |
107 | dbgInfo_.mainFile_, 0); |
108 | size_t lineNo = 0; |
109 | auto file = dbgInfo_.mainFile_; |
110 | auto *currentScope = DIFunction; |
111 | lineNo = dbgInfo_.mainFileFirstInstrLineNo_; |
112 | // Find the insertion poisition for debug instructions. |
113 | llvm::IRBuilder<> builder(&F->getEntryBlock()); |
114 | if (!F->getEntryBlock().empty()) { |
115 | llvm::DebugLoc debugLoc; |
116 | // Find first instruction with non-empty debug loc. |
117 | for (const auto &BB : *F) { |
118 | for (const auto &I : BB) { |
119 | if (I.getDebugLoc()) { |
120 | debugLoc = I.getDebugLoc(); |
121 | break; |
122 | } |
123 | } |
124 | } |
125 | // Insert before the first instruction in the entry block. |
126 | builder.SetInsertPoint(&F->getEntryBlock().front()); |
127 | if (!debugLoc) { |
128 | debugLoc = getDebugLoc(lineNo, 0, currentScope); |
129 | } |
130 | builder.SetCurrentDebugLocation(debugLoc); |
131 | } |
132 | // Create debug information for the arguments, so that a debugger can expect |
133 | // their values. |
134 | for (unsigned i = 0, e = F->arg_size(); i != e; ++i) { |
135 | // Create an alloca for storing a shadow of the function argument. The |
136 | // parameter value will be copied there to make it easier for debugger to |
137 | // inspect it. |
138 | auto *paramAlloca = |
139 | builder.CreateAlloca(F->getFunctionType()->getParamType(i)); |
140 | // Create a debug descriptor for the function argument. |
141 | // TODO: Try to produce semantically meaningful parameter names, e.g. by |
142 | // analyzing the debug information of the libjit. |
143 | std::string paramName = "arg" + std::to_string(i + 1); |
144 | auto param = DIBuilder_->createParameterVariable( |
145 | currentScope, paramName, i + 1, file, lineNo, |
146 | getDebugType(builder, F->getFunctionType()->getParamType(i)), |
147 | /* alwaysPreserve */ true); |
148 | // Store the initial value into the alloca, so that the debugger can show |
149 | // it. |
150 | auto *store = builder.CreateStore(F->arg_begin() + i, paramAlloca); |
151 | DIBuilder_->insertDeclare(paramAlloca, param, |
152 | DIBuilder_->createExpression(), |
153 | getDebugLoc(lineNo, 0, currentScope), store); |
154 | } |
155 | DIBuilder_->finalizeSubprogram(F->getSubprogram()); |
156 | llvm::DIScope *scope = F->getSubprogram(); |
157 | if (!scope) { |
158 | return; |
159 | } |
160 | // Add debug locations to all instructions inside the functions which have |
161 | // debug information. This is required for the proper emission of the debug |
162 | // information into object files. If debug locations are missing, LLVM would |
163 | // not emit such information like e.g. types of function parameters, etc. |
164 | llvm::DebugLoc debugLoc; |
165 | for (auto &BB : *F) { |
166 | for (auto &I : BB) { |
167 | if (I.getDebugLoc()) { |
168 | debugLoc = I.getDebugLoc(); |
169 | continue; |
170 | } |
171 | // Use last seen debug location. |
172 | I.setDebugLoc(debugLoc); |
173 | } |
174 | } |
175 | } |
176 | |
177 | llvm::DISubprogram * |
178 | LLVMIRGen::getOrCreateFunctionDebugInfo(llvm::Function *F, llvm::DIScope *scope, |
179 | llvm::DIFile *file, unsigned lineNo) { |
180 | // Do not emit any function debug information for LLVM internal functions. |
181 | if (F->getName().empty() || F->getName().startswith("llvm." )) |
182 | return nullptr; |
183 | auto *DIFunction = F->getSubprogram(); |
184 | if (!DIFunction) { |
185 | // Create a function type. The result type should be stored in the first |
186 | // element. |
187 | llvm::SmallVector<llvm::Metadata *, 8> paramTys; |
188 | |
189 | // Add the result type. |
190 | llvm::DIType *returnTy = getDebugType(*builder_, F->getReturnType()); |
191 | paramTys.push_back(returnTy); |
192 | |
193 | // Add the argument types. |
194 | for (unsigned i = 0, e = F->arg_size(); i != e; ++i) { |
195 | paramTys.push_back( |
196 | getDebugType(*builder_, F->getFunctionType()->getParamType(i))); |
197 | } |
198 | // Create a function type. |
199 | auto *DIFunctionTy = DIBuilder_->createSubroutineType( |
200 | DIBuilder_->getOrCreateTypeArray(paramTys)); |
201 | // Create a debug information for the current function. |
202 | #if LLVM_VERSION_MAJOR == 7 || (LLVM_VERSION_MAJOR <= 8 && FACEBOOK_INTERNAL) |
203 | DIFunction = DIBuilder_->createFunction( |
204 | scope, F->getName(), "" , file, lineNo, DIFunctionTy, |
205 | false /* internal linkage */, true /* definition */, lineNo, |
206 | llvm::DINode::FlagPrototyped, true /* isOptimized */); |
207 | #else |
208 | DIFunction = DIBuilder_->createFunction( |
209 | scope, F->getName(), "" , file, lineNo, DIFunctionTy, lineNo, |
210 | llvm::DINode::FlagPrototyped, |
211 | DISubprogram::SPFlagLocalToUnit | DISubprogram::SPFlagDefinition | |
212 | DISubprogram::SPFlagOptimized); |
213 | #endif |
214 | |
215 | assert(DIFunction); |
216 | F->setSubprogram(DIFunction); |
217 | } |
218 | |
219 | assert(F->getSubprogram() == DIFunction && |
220 | "Function has been assigned wrong debug information" ); |
221 | return DIFunction; |
222 | } |
223 | |
224 | /// Create and initialize global variables holding the bases addresses of |
225 | /// different memory areas. |
226 | static void initBaseAddressesOfMemoryAreas(DebugInfo &dbgInfo, |
227 | llvm::IRBuilder<> &builder, |
228 | llvm::Module &M, |
229 | llvm::Function *mainF) { |
230 | if (!mainF) { |
231 | return; |
232 | } |
233 | auto *main = mainF; |
234 | // Initialize the names of base address variables. |
235 | // Only 3 memory areas are currently supported: constant weights, mutable |
236 | // weights and activations. If more memory areas are introduced, the assert |
237 | // and the initialization code below need to be adjusted. |
238 | constexpr unsigned expectedNumMemoryAreas = 3; |
239 | assert(MemoryAreaKind::LastMemoryArea == expectedNumMemoryAreas && |
240 | "Expected only 3 memory areas" ); |
241 | dbgInfo.baseAddressesVariablesNames_.resize(expectedNumMemoryAreas); |
242 | dbgInfo.baseAddressesVariablesNames_[MemoryAreaKind::ConstWeightsMemoryArea] = |
243 | "constWeightsBaseAddress" ; |
244 | dbgInfo |
245 | .baseAddressesVariablesNames_[MemoryAreaKind::MutableWeightsMemoryArea] = |
246 | "mutableWeightsBaseAddress" ; |
247 | dbgInfo.baseAddressesVariablesNames_[MemoryAreaKind::ActivationsMemoryArea] = |
248 | "activationsBaseAddress" ; |
249 | |
250 | dbgInfo.baseAddressesVariables_.resize(expectedNumMemoryAreas); |
251 | // Create global variables to hold base addresses of different memory areas. |
252 | for (unsigned idx = 0, e = dbgInfo.baseAddressesVariablesNames_.size(); |
253 | idx != e; ++idx) { |
254 | auto name = dbgInfo.baseAddressesVariablesNames_[idx]; |
255 | // Create a global variable to hold a base address. Use CommonLinkage to |
256 | // make sure it is not removed by optimizations. |
257 | auto baseAddressVar = new llvm::GlobalVariable( |
258 | M, builder.getInt8PtrTy(), /* isConst */ false, |
259 | llvm::GlobalValue::ExternalLinkage, nullptr, name); |
260 | baseAddressVar->setInitializer( |
261 | llvm::ConstantPointerNull::get(builder.getInt8PtrTy())); |
262 | // Initialize the variable by the corresponding base address passed to |
263 | // "main" as a parameter. |
264 | builder.CreateStore(main->args().begin() + idx, baseAddressVar); |
265 | dbgInfo.baseAddressesVariables_[idx] = baseAddressVar; |
266 | } |
267 | } |
268 | |
269 | void LLVMIRGen::initDebugInfo() { |
270 | if (!emitDebugInfo) { |
271 | // No debug information is going to be emitted for the code generated from |
272 | // the Glow IR. But any debug information from the Glow's library (e.g. |
273 | // libjit) should be stripped as well. Let's strip the debug info as early |
274 | // as possible, so that the LLVM's optimizer does not need to spend any time |
275 | // to preserve the debug info during optimizations. |
276 | // The debug info stripping is enabled only for LLVM >= 6.0.0, because |
277 | // earlier versions of LLVM had a bug in this function which resulted in |
278 | // compiler crashes. |
279 | llvm::StripDebugInfo(getModule()); |
280 | return; |
281 | } |
282 | // Remove any existing debug info version flags from the module to |
283 | // avoid possible conflicts, which may happen if libjit was compiled |
284 | // using an older version of Clang which uses the old debug info format. |
285 | llvm::NamedMDNode *NMD = llmodule_->getModuleFlagsMetadata(); |
286 | if (NMD) { |
287 | NMD->eraseFromParent(); |
288 | } |
289 | // Add the current debug info version into the module. |
290 | llmodule_->addModuleFlag(llvm::Module::Override, "Debug Info Version" , |
291 | llvm::DEBUG_METADATA_VERSION); |
292 | llmodule_->addModuleFlag(llvm::Module::Override, "Dwarf Version" , 4); |
293 | llmodule_->addModuleFlag(llvm::Module::Override, "PIC Level" , 2); |
294 | |
295 | // Construct the DIBuilder. |
296 | DIBuilder_ = glow::make_unique<llvm::DIBuilder>(getModule()); |
297 | |
298 | // Remove the old content of the Glow IR file. |
299 | // The name of the file for the IR, without a path. |
300 | auto irfileName = getBundleName().str() + ".glow" ; |
301 | // Use the absolute path, so that a debugger can always find a file. |
302 | llvm::SmallVector<char, 128> path(getOutputDir().begin(), |
303 | getOutputDir().end()); |
304 | std::error_code EC = llvm::sys::fs::make_absolute(path); |
305 | assert(!EC && "Could not create absolute path for a file" ); |
306 | auto irfileFullPath = (path + "/" + irfileName).str(); |
307 | EC = llvm::sys::fs::remove(irfileFullPath); |
308 | assert(!EC && "Could not remove the Glow IR file" ); |
309 | |
310 | // Create the debug information for the current file. It does not create a |
311 | // real file. It is just a file name and path used for the debug locations. |
312 | dbgInfo_.mainFile_ = DIBuilder_->createFile( |
313 | irfileName, llvm::StringRef(path.data(), path.size())); |
314 | |
315 | // Create the compile unit for the module. |
316 | dbgInfo_.compilationUnit_ = DIBuilder_->createCompileUnit( |
317 | llvm::dwarf::DW_LANG_C, dbgInfo_.mainFile_, "Glow Compiler" , 0, "" , 0, "" , |
318 | llvm::DICompileUnit::DebugEmissionKind::FullDebug, |
319 | /* SplitDebugInlining */ true, |
320 | /* DebugInfoForProfiling */ true); |
321 | } |
322 | |
323 | void LLVMIRGen::generateFunctionDebugInfo() { |
324 | if (!emitDebugInfo) { |
325 | return; |
326 | } |
327 | // Init global variables holding base address of different memory areas. |
328 | initBaseAddressesOfMemoryAreas(dbgInfo_, *builder_, getModule(), |
329 | getLLVMFunction()); |
330 | |
331 | // Create a textual representation of the IR for the main function. |
332 | // First store the textual IR into a string. |
333 | std::string irContent; |
334 | llvm::raw_string_ostream irfileContent(irContent); |
335 | F_->dump(irfileContent); |
336 | irfileContent.str(); |
337 | |
338 | // Write the IR into a file. |
339 | std::error_code EC; |
340 | // The name of the file for the IR, without a path. |
341 | auto irfileName = getBundleName().str() + ".glow" ; |
342 | // Use the absolute path, so that a debugger can always find a file. |
343 | llvm::SmallVector<char, 128> path(getOutputDir().begin(), |
344 | getOutputDir().end()); |
345 | EC = llvm::sys::fs::make_absolute(path); |
346 | assert(!EC && "Could not create absolute path for a file" ); |
347 | auto irfileFullPath = (path + "/" + irfileName).str(); |
348 | llvm::raw_fd_ostream irfile(irfileFullPath, EC, |
349 | llvm::sys::fs::OpenFlags::F_Text | |
350 | llvm::sys::fs::OpenFlags::F_Append); |
351 | assert(!EC && "Error opening output file" ); |
352 | irfile << irContent; |
353 | irfile.close(); |
354 | |
355 | // Find out the line number of the first IR instruction. It is required to |
356 | // enable stepping in the debugger. |
357 | std::ifstream in(irfileFullPath); |
358 | std::string s; |
359 | size_t lineNo = 0; |
360 | // Find the last code section, because this is the section for the last bundle |
361 | // entry. |
362 | while (getline(in, s)) { |
363 | lineNo++; |
364 | // The first IR instruction comes right after the line "code {". |
365 | if (s.substr(0, 6) == "code {" ) { |
366 | dbgInfo_.mainFileFirstInstrLineNo_ = lineNo + 1; |
367 | } |
368 | } |
369 | assert(dbgInfo_.mainFileFirstInstrLineNo_ && |
370 | "No IR code was found in the textual IR representation" ); |
371 | |
372 | // Create the debug info for the main function. |
373 | auto *main = getLLVMFunction(); |
374 | dbgInfo_.mainF_ = main ? getOrCreateFunctionDebugInfo( |
375 | main, dbgInfo_.mainFile_, dbgInfo_.mainFile_, |
376 | dbgInfo_.mainFileFirstInstrLineNo_) |
377 | : nullptr; |
378 | } |
379 | |
380 | void LLVMIRGen::emitDebugGlobalVariableForValue(const Value *val) { |
381 | auto name = val->getName(); |
382 | // Create a proper type for the variable. |
383 | // Represent Glow's N-dimensional tensors as N-dimensional C arrays in the |
384 | // debug information. This allows for inspecting them in the debugger using a |
385 | // natural array notation, i.e. tensor[idx1][idx2]...[idxN]. |
386 | auto *ty = val->getType(); |
387 | auto dims = ty->dims(); |
388 | auto dbgElemTy = getDebugType(*builder_, getElementType(*builder_, val)); |
389 | llvm::SmallVector<llvm::Metadata *, 8> subranges; |
390 | for (auto dim : dims) { |
391 | subranges.push_back(llvm::DISubrange::get(getLLVMContext(), dim)); |
392 | } |
393 | auto subscripts = llvm::MDTuple::get(getLLVMContext(), subranges); |
394 | auto dbgArrayTy = DIBuilder_->createArrayType( |
395 | ty->getSizeInBytes() * 8, sizeof(float), dbgElemTy, subscripts); |
396 | |
397 | // Create a debug info for the logical global variable representing a weight |
398 | // or an activation. This allows for inspecting the values of weights and |
399 | // activations when using a debugger. The address of this logical global |
400 | // variable is computed as (base address of the memory area + offset) using |
401 | // the information from the AllocationsInfo. |
402 | llvm::GlobalVariable *baseAddress{nullptr}; |
403 | |
404 | MemoryAreaKind memoryAreaKind = MemoryAreaKind::LastMemoryArea; |
405 | |
406 | switch (allocationsInfo_.valueNumbers_[val].first) { |
407 | case AllocationsInfo::ValueKind::Activation: { |
408 | memoryAreaKind = MemoryAreaKind::ActivationsMemoryArea; |
409 | break; |
410 | } |
411 | case AllocationsInfo::ValueKind::ConstantWeight: { |
412 | memoryAreaKind = MemoryAreaKind::ConstWeightsMemoryArea; |
413 | break; |
414 | } |
415 | case AllocationsInfo::ValueKind::MutableWeight: { |
416 | memoryAreaKind = MemoryAreaKind::MutableWeightsMemoryArea; |
417 | break; |
418 | default: |
419 | LOG(FATAL) << "Unknown memory area kind" ; |
420 | } |
421 | } |
422 | |
423 | baseAddress = dbgInfo_.baseAddressesVariables_[memoryAreaKind]; |
424 | |
425 | // DWARF operations to be performed with the base address to compute the |
426 | // address of the logical global variable. |
427 | llvm::SmallVector<uint64_t, 4> ops; |
428 | assert(allocationsInfo_.allocatedAddress_.count(val) && |
429 | "The weight should be in the map" ); |
430 | auto offset = allocationsInfo_.allocatedAddress_[val]; |
431 | // Get the value of the global var. |
432 | ops.push_back(llvm::dwarf::DW_OP_deref); |
433 | // Add the offset to the value of the global var to get the address of the |
434 | // logical debug variable being created. |
435 | ops.push_back(llvm::dwarf::DW_OP_constu); |
436 | ops.push_back(offset); |
437 | ops.push_back(llvm::dwarf::DW_OP_plus); |
438 | llvm::DIExpression *DIexpr{nullptr}; |
439 | DIexpr = DIBuilder_->createExpression(ops); |
440 | auto *DIgv = DIBuilder_->createGlobalVariableExpression( |
441 | dbgInfo_.compilationUnit_, name, "" , dbgInfo_.mainFile_, 0, dbgArrayTy, |
442 | /* isLocalToUnit */ false, DIexpr); |
443 | baseAddress->addDebugInfo(DIgv); |
444 | } |
445 | |
446 | void LLVMIRGen::generateModuleDebugInfo() { |
447 | if (!emitDebugInfo) |
448 | return; |
449 | |
450 | // Check that global variables representing base-addresses are not eliminated |
451 | // e.g. by optimization passes. These variables are needed for emitting the |
452 | // debug info for weights and activations, because it uses relative addressing |
453 | // based on these variables. |
454 | for (auto name : dbgInfo_.baseAddressesVariablesNames_) { |
455 | (void)name; |
456 | assert(getModule().getGlobalVariable(name, |
457 | /* allowInternal */ true) && |
458 | "Base address variable should be present in the LLVM module" ); |
459 | } |
460 | |
461 | // Now iterate over the module and add debug locations to all instructions |
462 | // inside the functions which have debug information. This is required for the |
463 | // proper emission of the debug information into object files. If debug |
464 | // locations are missing, LLVM would not emit such information like e.g. types |
465 | // of function parameters, etc. |
466 | for (auto &F : getModule()) { |
467 | if (F.isDeclaration()) |
468 | continue; |
469 | // Bail if the function has no debug information. |
470 | llvm::DIScope *scope = F.getSubprogram(); |
471 | if (!scope) |
472 | continue; |
473 | size_t lineNo = dbgInfo_.mainFileFirstInstrLineNo_; |
474 | llvm::DebugLoc debugLoc( |
475 | llvm::DILocation::get(getLLVMContext(), lineNo, 0, scope)); |
476 | for (auto &BB : F) { |
477 | for (auto &I : BB) { |
478 | // Do not update debug locations that are not belonging to the current |
479 | // scope. |
480 | if (I.getDebugLoc() && |
481 | I.getDebugLoc()->getScope()->getName() != F.getName()) |
482 | continue; |
483 | // Do not update existing debug information in the current scope. |
484 | if (I.getDebugLoc()) { |
485 | // Use the last seen debug location in the current scope. |
486 | debugLoc = I.getDebugLoc(); |
487 | continue; |
488 | } |
489 | I.setDebugLoc(debugLoc); |
490 | } |
491 | } |
492 | } |
493 | |
494 | // Emit the debug info for weight variables and activations variables used by |
495 | // the Glow IR. Represent those variables as global variables. |
496 | for (auto &v : F_->findConstants()) { |
497 | auto *w = cast<WeightVar>(F_->getWeightForNode(v)); |
498 | emitDebugGlobalVariableForValue(w); |
499 | } |
500 | |
501 | for (const auto &I : F_->getInstrs()) { |
502 | if (!isa<AllocActivationInst>(&I) && !isa<TensorViewInst>(&I)) |
503 | continue; |
504 | emitDebugGlobalVariableForValue(&I); |
505 | } |
506 | |
507 | // Finalize the debug info. |
508 | DIBuilder_->finalize(); |
509 | |
510 | // Fix function attributes related issues. |
511 | for (auto &FF : getModule()) { |
512 | // Optnone requires NoInline. |
513 | if (FF.hasFnAttribute(llvm::Attribute::AttrKind::OptimizeNone)) { |
514 | FF.addFnAttr(llvm::Attribute::AttrKind::NoInline); |
515 | } |
516 | } |
517 | |
518 | // Verify the module to see if there are any errors due to the debug |
519 | // information. |
520 | bool brokenDebugInfo = false; |
521 | (void)brokenDebugInfo; |
522 | // Pass brokenDebugInfo as a reference to the verifyModule. |
523 | assert(!llvm::verifyModule(getModule(), &llvm::errs(), &brokenDebugInfo) && |
524 | "LLVM module verification error" ); |
525 | assert(!brokenDebugInfo && "Debug information is broken" ); |
526 | } |
527 | |