Skip to content

Commit

Permalink
Merge pull request lcompilers#1256 from Thirumalai-Shaktivel/debug
Browse files Browse the repository at this point in the history
  • Loading branch information
Thirumalai-Shaktivel committed Nov 3, 2022
2 parents e2bd8ee + b21d996 commit ecdb38e
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 66 deletions.
3 changes: 2 additions & 1 deletion run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ def is_included(backend):
run_test(
filename,
"llvm_dbg",
"lpython --no-color --show-llvm -g {infile} -o {outfile}",
"lpython --no-color --show-llvm -g --debug-with-line-column "
"{infile} -o {outfile}",
filename,
update_reference,
extra_args)
Expand Down
8 changes: 5 additions & 3 deletions src/bin/lpython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ int emit_llvm(const std::string &infile,
// ASR -> LLVM
LFortran::PythonCompiler fe(compiler_options);
LFortran::Result<std::unique_ptr<LFortran::LLVMModule>>
res = fe.get_llvm3(*asr, pass_manager, diagnostics);
res = fe.get_llvm3(*asr, pass_manager, diagnostics, infile);
std::cerr << diagnostics.render(input, lm, compiler_options);
if (!res.ok) {
LFORTRAN_ASSERT(diagnostics.has_error())
Expand Down Expand Up @@ -629,7 +629,7 @@ int compile_python_to_object_file(
std::unique_ptr<LFortran::LLVMModule> m;
auto asr_to_llvm_start = std::chrono::high_resolution_clock::now();
LFortran::Result<std::unique_ptr<LFortran::LLVMModule>>
res = fe.get_llvm3(*asr, pass_manager, diagnostics);
res = fe.get_llvm3(*asr, pass_manager, diagnostics, infile);
auto asr_to_llvm_end = std::chrono::high_resolution_clock::now();
times.push_back(std::make_pair("ASR to LLVM", std::chrono::duration<double, std::milli>(asr_to_llvm_end - asr_to_llvm_start).count()));
std::cerr << diagnostics.render(input, lm, compiler_options);
Expand Down Expand Up @@ -1279,7 +1279,9 @@ int main(int argc, char *argv[])
app.add_option("-I", compiler_options.import_path, "Specify the path"
"to look for the module")->allow_extra_args(false);
// app.add_option("-J", arg_J, "Where to save mod files");
app.add_flag("-g", compiler_options.arg_g, "Compile with debugging information");
app.add_flag("-g", compiler_options.emit_debug_info, "Compile with debugging information");
app.add_flag("--debug-with-line-column", compiler_options.emit_debug_line_column,
"Convert the linear location info into line + column in the debugging information");
// app.add_option("-D", compiler_options.c_preprocessor_defines, "Define <macro>=<value> (or 1 if <value> omitted)")->allow_extra_args(false);
app.add_flag("--version", arg_version, "Display compiler version information");

Expand Down
83 changes: 57 additions & 26 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
std::unique_ptr<llvm::Module> module;
std::unique_ptr<llvm::IRBuilder<>> builder;
Platform platform;
bool enable_debug_info;
bool emit_debug_info;
std::string infile;
bool emit_debug_line_column;
Allocator &al;

llvm::Value *tmp;
Expand Down Expand Up @@ -239,11 +241,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
llvm::DIFile *debug_Unit;

ASRToLLVMVisitor(Allocator &al, llvm::LLVMContext &context, Platform platform,
bool enable_debug_info, diag::Diagnostics &diagnostics) :
bool emit_debug_info, std::string infile, bool emit_debug_line_column,
diag::Diagnostics &diagnostics) :
diag{diagnostics},
context(context),
builder(std::make_unique<llvm::IRBuilder<>>(context)),
platform{platform}, enable_debug_info{enable_debug_info},
platform{platform},
emit_debug_info{emit_debug_info},
infile{infile},
emit_debug_line_column{emit_debug_line_column},
al{al},
prototype_only(false),
llvm_utils(std::make_unique<LLVMUtils>(context, builder.get())),
Expand Down Expand Up @@ -369,11 +375,24 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
}
}

void debug_get_line_column(const uint32_t &loc_first,
uint32_t &line, uint32_t &column) {
LocationManager lm;
lm.in_filename = infile;
lm.init_simple(LFortran::read_file(infile));
lm.pos_to_linecol(lm.output_to_input_pos(loc_first, false), line, column);
}

template <typename T>
void debug_emit_loc(const T &x) {
Location loc = x.base.base.loc;
uint64_t line = loc.first;
uint64_t column = 0;
uint32_t line, column;
if (emit_debug_line_column) {
debug_get_line_column(loc.first, line, column);
} else {
line = loc.first;
column = 0;
}
builder->SetCurrentDebugLocation(
llvm::DILocation::get(debug_current_scope->getContext(),
line, column, debug_current_scope));
Expand All @@ -385,8 +404,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
debug_CU->getFilename(),
debug_CU->getDirectory());
llvm::DIScope *FContext = debug_Unit;
uint64_t LineNo, ScopeLine;
LineNo = ScopeLine = 0;
uint32_t line, column;
if (emit_debug_line_column) {
debug_get_line_column(x.base.base.loc.first, line, column);
} else {
line = 0;
}
std::string fn_debug_name = x.m_name;
llvm::DIBasicType *return_type_info = nullptr;
if constexpr (std::is_same_v<T, ASR::Function_t>){
Expand All @@ -405,7 +428,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
DBuilder->getOrCreateTypeArray(return_type_info));
SP = DBuilder->createFunction(
FContext, fn_debug_name, llvm::StringRef(), debug_Unit,
LineNo, return_type, ScopeLine,
line, return_type, 0, // TODO: ScopeLine
llvm::DINode::FlagPrototyped,
llvm::DISubprogram::SPFlagDefinition);
debug_current_scope = SP;
Expand Down Expand Up @@ -1147,10 +1170,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
module = std::make_unique<llvm::Module>("LFortran", context);
module->setDataLayout("");

if (enable_debug_info) {
if (emit_debug_info) {
DBuilder = std::make_unique<llvm::DIBuilder>(*module);
debug_CU = DBuilder->createCompileUnit(
llvm::dwarf::DW_LANG_C, DBuilder->createFile("xxexpr.py", "/yy/"),
llvm::dwarf::DW_LANG_C, DBuilder->createFile(infile, "."),
"LPython Compiler", false, "", 0);
}

Expand Down Expand Up @@ -2249,7 +2272,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
llvm::Function::ExternalLinkage, "main", module.get());
llvm::BasicBlock *BB = llvm::BasicBlock::Create(context,
".entry", F);
if (enable_debug_info) {
if (emit_debug_info) {
llvm::DISubprogram *SP;
debug_emit_function(x, SP);
F->setSubprogram(SP);
Expand All @@ -2266,7 +2289,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
dict_api_sc->set_is_dict_present(is_dict_present_copy_sc);

// Finalize the debug info.
if (enable_debug_info) DBuilder->finalize();
if (emit_debug_info) DBuilder->finalize();
}

/*
Expand Down Expand Up @@ -2599,20 +2622,26 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
}
}
llvm::AllocaInst *ptr = builder->CreateAlloca(type, nullptr, v->m_name);
if (enable_debug_info) {
if (emit_debug_info) {
// Reset the debug location
builder->SetCurrentDebugLocation(nullptr);
uint64_t LineNo = v->base.base.loc.first;
uint32_t line, column;
if (emit_debug_line_column) {
debug_get_line_column(v->base.base.loc.first, line, column);
} else {
line = v->base.base.loc.first;
column = 0;
}
std::string type_name;
uint32_t type_size, type_encoding;
get_type_debug_info(v->m_type, type_name, type_size,
type_encoding);
llvm::DILocalVariable *debug_var = DBuilder->createParameterVariable(
debug_current_scope, v->m_name, ++debug_arg_count, debug_Unit, LineNo,
debug_current_scope, v->m_name, ++debug_arg_count, debug_Unit, line,
DBuilder->createBasicType(type_name, type_size, type_encoding), true);
DBuilder->insertDeclare(ptr, debug_var, DBuilder->createExpression(),
llvm::DILocation::get(debug_current_scope->getContext(),
LineNo, 0, debug_current_scope), builder->GetInsertBlock());
line, 0, debug_current_scope), builder->GetInsertBlock());
}

if( ASR::is_a<ASR::Struct_t>(*v->m_type) ) {
Expand Down Expand Up @@ -3183,7 +3212,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
dict_api_sc->set_is_dict_present(is_dict_present_copy_sc);

// Finalize the debug info.
if (enable_debug_info) DBuilder->finalize();
if (emit_debug_info) DBuilder->finalize();
}

void instantiate_function(const ASR::Function_t &x){
Expand Down Expand Up @@ -3218,19 +3247,19 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
llvm::Function::ExternalLinkage, fn_name, module.get());

// Add Debugging information to the LLVM function F
if (enable_debug_info) {
if (emit_debug_info) {
debug_emit_function(x, SP);
F->setSubprogram(SP);
}
} else {
uint32_t old_h = llvm_symtab_fn_names[fn_name];
F = llvm_symtab_fn[old_h];
if (enable_debug_info) {
if (emit_debug_info) {
SP = (llvm::DISubprogram*) llvm_symtab_fn_discope[old_h];
}
}
llvm_symtab_fn[h] = F;
if (enable_debug_info) llvm_symtab_fn_discope[h] = SP;
if (emit_debug_info) llvm_symtab_fn_discope[h] = SP;

// Instantiate (pre-declare) all nested interfaces
for (auto &item : x.m_symtab->get_scope()) {
Expand Down Expand Up @@ -3427,12 +3456,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
parent_function = &x;
parent_function_hash = h;
llvm::Function* F = llvm_symtab_fn[h];
if (enable_debug_info) debug_current_scope = llvm_symtab_fn_discope[h];
if (emit_debug_info) debug_current_scope = llvm_symtab_fn_discope[h];
proc_return = llvm::BasicBlock::Create(context, "return");
llvm::BasicBlock *BB = llvm::BasicBlock::Create(context,
".entry", F);
builder->SetInsertPoint(BB);
if (enable_debug_info) debug_emit_loc(x);
if (emit_debug_info) debug_emit_loc(x);
declare_args(x, *F);
declare_local_vars(x);
}
Expand Down Expand Up @@ -3715,7 +3744,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
}

void visit_Assignment(const ASR::Assignment_t &x) {
if (enable_debug_info) debug_emit_loc(x);
if (emit_debug_info) debug_emit_loc(x);
if( x.m_overloaded ) {
this->visit_stmt(*x.m_overloaded);
return ;
Expand Down Expand Up @@ -6014,7 +6043,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
}

void visit_SubroutineCall(const ASR::SubroutineCall_t &x) {
if (enable_debug_info) debug_emit_loc(x);
if (emit_debug_info) debug_emit_loc(x);
if( ASRUtils::is_intrinsic_optimization(x.m_name) ) {
ASR::Function_t* routine = ASR::down_cast<ASR::Function_t>(
ASRUtils::symbol_get_past_external(x.m_name));
Expand Down Expand Up @@ -6356,12 +6385,14 @@ Result<std::unique_ptr<LLVMModule>> asr_to_llvm(ASR::TranslationUnit_t &asr,
diag::Diagnostics &diagnostics,
llvm::LLVMContext &context, Allocator &al,
LCompilers::PassManager& pass_manager,
CompilerOptions &co, const std::string &run_fn)
CompilerOptions &co, const std::string &run_fn,
const std::string &infile)
{
#if LLVM_VERSION_MAJOR >= 15
context.setOpaquePointers(false);
#endif
ASRToLLVMVisitor v(al, context, co.platform, co.arg_g, diagnostics);
ASRToLLVMVisitor v(al, context, co.platform, co.emit_debug_info, infile,
co.emit_debug_line_column, diagnostics);
LCompilers::PassOptions pass_options;
pass_options.run_fun = run_fn;
pass_options.always_run = false;
Expand Down
3 changes: 2 additions & 1 deletion src/libasr/codegen/asr_to_llvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ namespace LFortran {
llvm::LLVMContext &context, Allocator &al,
LCompilers::PassManager& pass_manager,
CompilerOptions &co,
const std::string &run_fn);
const std::string &run_fn,
const std::string &infile);

} // namespace LFortran

Expand Down
2 changes: 1 addition & 1 deletion src/libasr/pass/global_stmts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void pass_wrap_global_stmts_into_function(Allocator &al,
SymbolTable *fn_scope = al.make_new<SymbolTable>(unit.m_global_scope);

ASR::ttype_t *type;
Location loc;
Location loc = unit.base.base.loc;
ASR::asr_t *return_var=nullptr;
ASR::expr_t *return_var_ref=nullptr;
char *var_name;
Expand Down
3 changes: 2 additions & 1 deletion src/libasr/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ struct CompilerOptions {
bool implicit_interface = false;
std::string target = "";
std::string arg_o = "";
bool arg_g = false;
bool emit_debug_info = false;
bool emit_debug_line_column = false;
std::string import_path = "";
Platform platform;

Expand Down
6 changes: 3 additions & 3 deletions src/lpython/python_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ PythonCompiler::~PythonCompiler() = default;
Result<std::unique_ptr<LLVMModule>> PythonCompiler::get_llvm3(
#ifdef HAVE_LFORTRAN_LLVM
ASR::TranslationUnit_t &asr, LCompilers::PassManager& lpm,
diag::Diagnostics &diagnostics
diag::Diagnostics &diagnostics, const std::string &infile
#else
ASR::TranslationUnit_t &/*asr*/, LCompilers::PassManager&/*lpm*/,
diag::Diagnostics &/*diagnostics*/
diag::Diagnostics &/*diagnostics*/,const std::string &/*infile*/
#endif
)
{
Expand All @@ -55,7 +55,7 @@ Result<std::unique_ptr<LLVMModule>> PythonCompiler::get_llvm3(
Result<std::unique_ptr<LFortran::LLVMModule>> res
= asr_to_llvm(asr, diagnostics,
e->get_context(), al, lpm, compiler_options,
run_fn);
run_fn, infile);
if (res.ok) {
m = std::move(res.result);
} else {
Expand Down
3 changes: 2 additions & 1 deletion src/lpython/python_evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class PythonCompiler
};

Result<std::unique_ptr<LLVMModule>> get_llvm3(ASR::TranslationUnit_t &asr,
LCompilers::PassManager& lpm, diag::Diagnostics &diagnostics);
LCompilers::PassManager& lpm, diag::Diagnostics &diagnostics,
const std::string &infile);

private:
Allocator al;
Expand Down
13 changes: 13 additions & 0 deletions tests/reference/llvm_dbg-expr_01-9fc5f30.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"basename": "llvm_dbg-expr_01-9fc5f30",
"cmd": "lpython --no-color --show-llvm -g --debug-with-line-column {infile} -o {outfile}",
"infile": "tests/expr_01.py",
"infile_hash": "4284fe3a1b4dd3e5d1de1357a79e9a25b426ca245b4cc91cf99e8547",
"outfile": null,
"outfile_hash": null,
"stdout": "llvm_dbg-expr_01-9fc5f30.stdout",
"stdout_hash": "d9ddd67926153e27017b59e3d5786b20797f0819c7943ccb3c334188",
"stderr": null,
"stderr_hash": null,
"returncode": 0
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,28 +49,28 @@ attributes #0 = { nounwind readnone speculatable willreturn }
!llvm.dbg.cu = !{!0}

!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "LPython Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "xxexpr.py", directory: "/yy/")
!1 = !DIFile(filename: "tests/expr_01.py", directory: ".")
!2 = !{}
!3 = distinct !DISubprogram(name: "_lpython_main_program", scope: !1, file: !1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!3 = distinct !DISubprogram(name: "_lpython_main_program", scope: !1, file: !1, line: 1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!4 = !DISubroutineType(types: !5)
!5 = !{null}
!6 = !DILocation(line: 89, scope: !3)
!7 = distinct !DISubprogram(name: "main0", scope: !1, file: !1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DILocation(line: 0, scope: !7)
!9 = !DILocalVariable(name: "x", arg: 1, scope: !7, file: !1, line: 17, type: !10)
!6 = !DILocation(line: 9, column: 1, scope: !3)
!7 = distinct !DISubprogram(name: "main0", scope: !1, file: !1, line: 1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!8 = !DILocation(line: 1, column: 1, scope: !7)
!9 = !DILocalVariable(name: "x", arg: 1, scope: !7, file: !1, line: 2, type: !10)
!10 = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed)
!11 = !DILocation(line: 17, scope: !7)
!12 = !DILocalVariable(name: "x2", arg: 2, scope: !7, file: !1, line: 28, type: !13)
!11 = !DILocation(line: 2, scope: !7)
!12 = !DILocalVariable(name: "x2", arg: 2, scope: !7, file: !1, line: 3, type: !13)
!13 = !DIBasicType(name: "integer", size: 64, encoding: DW_ATE_signed)
!14 = !DILocation(line: 28, scope: !7)
!15 = !DILocalVariable(name: "y", arg: 3, scope: !7, file: !1, line: 40, type: !16)
!14 = !DILocation(line: 3, scope: !7)
!15 = !DILocalVariable(name: "y", arg: 3, scope: !7, file: !1, line: 4, type: !16)
!16 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
!17 = !DILocation(line: 40, scope: !7)
!18 = !DILocalVariable(name: "y2", arg: 4, scope: !7, file: !1, line: 51, type: !19)
!17 = !DILocation(line: 4, scope: !7)
!18 = !DILocalVariable(name: "y2", arg: 4, scope: !7, file: !1, line: 5, type: !19)
!19 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
!20 = !DILocation(line: 51, scope: !7)
!21 = !DILocation(line: 63, scope: !7)
!22 = distinct !DISubprogram(name: "main_program", scope: !1, file: !1, type: !23, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!20 = !DILocation(line: 5, scope: !7)
!21 = !DILocation(line: 6, column: 5, scope: !7)
!22 = distinct !DISubprogram(name: "main_program", scope: !1, file: !1, line: 1, type: !23, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
!23 = !DISubroutineType(types: !24)
!24 = !{!10}
!25 = !DILocation(line: 0, scope: !22)
!25 = !DILocation(line: 1, column: 1, scope: !22)
13 changes: 0 additions & 13 deletions tests/reference/llvm_dbg-expr_01-bc258d6.json

This file was deleted.

0 comments on commit ecdb38e

Please sign in to comment.