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
31using namespace glow;
32using llvm::cast;
33using llvm::DISubprogram;
34using llvm::dyn_cast;
35using llvm::isa;
36
37extern llvm::cl::opt<bool> emitDebugInfo;
38
39void 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
56llvm::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
86static 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
102void 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
177llvm::DISubprogram *
178LLVMIRGen::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.
226static 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
269void 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
323void 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
380void 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
446void 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