• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "debug_data_builder.h"
17 
18 #include <llvm/IR/Module.h>
19 #include <llvm/IR/Function.h>
20 #include <llvm/IR/DIBuilder.h>
21 
22 namespace ark::llvmbackend {
23 
24 using llvm::DIBuilder;
25 using llvm::DICompileUnit;
26 using llvm::DILocation;
27 using llvm::DISubprogram;
28 using llvm::Function;
29 using llvm::Instruction;
30 
DebugDataBuilder(llvm::Module * module,const std::string & filename)31 DebugDataBuilder::DebugDataBuilder(llvm::Module *module, const std::string &filename) : builder_(new DIBuilder(*module))
32 {
33     auto file = builder_->createFile(filename, "/");
34     builder_->createCompileUnit(llvm::dwarf::DW_LANG_C_plus_plus_14, file, "ark-llvm-backend", true, "", 0, "",
35                                 DICompileUnit::DebugEmissionKind::NoDebug, 0, true, false,
36                                 DICompileUnit::DebugNameTableKind::None);
37 }
38 
BeginSubprogram(Function * function,const std::string & filename,uint32_t line)39 void DebugDataBuilder::BeginSubprogram(Function *function, const std::string &filename, uint32_t line)
40 {
41     ASSERT(builder_ != nullptr);
42     auto file = builder_->createFile(filename, "/");
43     auto flags = DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized;
44     auto type = builder_->createSubroutineType(builder_->getOrCreateTypeArray(llvm::None));
45     auto sp = builder_->createFunction(file, function->getName(), function->getName(), file, line, type, line,
46                                        llvm::DINode::FlagZero, flags);
47     function->setSubprogram(sp);
48 }
49 
EndSubprogram(Function * function)50 void DebugDataBuilder::EndSubprogram(Function *function)
51 {
52     ASSERT(builder_ != nullptr);
53     builder_->finalizeSubprogram(function->getSubprogram());
54 }
55 
SetLocation(Instruction * inst,uint32_t line,uint32_t column)56 void DebugDataBuilder::SetLocation(Instruction *inst, uint32_t line, uint32_t column)
57 {
58     auto func = inst->getFunction();
59     inst->setDebugLoc(DILocation::get(func->getContext(), line, column, func->getSubprogram()));
60 }
61 
AppendInlinedAt(llvm::Instruction * inst,llvm::Function * function,uint32_t line,uint32_t column)62 void DebugDataBuilder::AppendInlinedAt(llvm::Instruction *inst, llvm::Function *function, uint32_t line,
63                                        uint32_t column)
64 {
65     auto original = inst->getDebugLoc();
66 
67     auto inlinedAtNode = DILocation::getDistinct(function->getContext(), line, column, original.getScope());
68     llvm::DenseMap<const llvm::MDNode *, llvm::MDNode *> cache;
69     auto inlinedAt = llvm::DebugLoc::appendInlinedAt(original, inlinedAtNode, function->getContext(), cache);
70     auto newDebugInfo = DILocation::getDistinct(function->getContext(), original.getLine(), original->getColumn(),
71                                                 original.getScope(), inlinedAt);
72     inst->setDebugLoc(newDebugInfo);
73 }
74 
Finalize()75 void DebugDataBuilder::Finalize()
76 {
77     builder_->finalize();
78     delete builder_;
79     builder_ = nullptr;
80 }
81 
~DebugDataBuilder()82 DebugDataBuilder::~DebugDataBuilder()
83 {
84     delete builder_;
85 }
86 
87 }  // namespace ark::llvmbackend
88