Skip to content

Commit ecdb38e

Browse files
Merge pull request #1256 from Thirumalai-Shaktivel/debug
2 parents e2bd8ee + b21d996 commit ecdb38e

11 files changed

+103
-66
lines changed

run_tests.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ def is_included(backend):
9696
run_test(
9797
filename,
9898
"llvm_dbg",
99-
"lpython --no-color --show-llvm -g {infile} -o {outfile}",
99+
"lpython --no-color --show-llvm -g --debug-with-line-column "
100+
"{infile} -o {outfile}",
100101
filename,
101102
update_reference,
102103
extra_args)

src/bin/lpython.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ int emit_llvm(const std::string &infile,
558558
// ASR -> LLVM
559559
LFortran::PythonCompiler fe(compiler_options);
560560
LFortran::Result<std::unique_ptr<LFortran::LLVMModule>>
561-
res = fe.get_llvm3(*asr, pass_manager, diagnostics);
561+
res = fe.get_llvm3(*asr, pass_manager, diagnostics, infile);
562562
std::cerr << diagnostics.render(input, lm, compiler_options);
563563
if (!res.ok) {
564564
LFORTRAN_ASSERT(diagnostics.has_error())
@@ -629,7 +629,7 @@ int compile_python_to_object_file(
629629
std::unique_ptr<LFortran::LLVMModule> m;
630630
auto asr_to_llvm_start = std::chrono::high_resolution_clock::now();
631631
LFortran::Result<std::unique_ptr<LFortran::LLVMModule>>
632-
res = fe.get_llvm3(*asr, pass_manager, diagnostics);
632+
res = fe.get_llvm3(*asr, pass_manager, diagnostics, infile);
633633
auto asr_to_llvm_end = std::chrono::high_resolution_clock::now();
634634
times.push_back(std::make_pair("ASR to LLVM", std::chrono::duration<double, std::milli>(asr_to_llvm_end - asr_to_llvm_start).count()));
635635
std::cerr << diagnostics.render(input, lm, compiler_options);
@@ -1279,7 +1279,9 @@ int main(int argc, char *argv[])
12791279
app.add_option("-I", compiler_options.import_path, "Specify the path"
12801280
"to look for the module")->allow_extra_args(false);
12811281
// app.add_option("-J", arg_J, "Where to save mod files");
1282-
app.add_flag("-g", compiler_options.arg_g, "Compile with debugging information");
1282+
app.add_flag("-g", compiler_options.emit_debug_info, "Compile with debugging information");
1283+
app.add_flag("--debug-with-line-column", compiler_options.emit_debug_line_column,
1284+
"Convert the linear location info into line + column in the debugging information");
12831285
// app.add_option("-D", compiler_options.c_preprocessor_defines, "Define <macro>=<value> (or 1 if <value> omitted)")->allow_extra_args(false);
12841286
app.add_flag("--version", arg_version, "Display compiler version information");
12851287

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
161161
std::unique_ptr<llvm::Module> module;
162162
std::unique_ptr<llvm::IRBuilder<>> builder;
163163
Platform platform;
164-
bool enable_debug_info;
164+
bool emit_debug_info;
165+
std::string infile;
166+
bool emit_debug_line_column;
165167
Allocator &al;
166168

167169
llvm::Value *tmp;
@@ -239,11 +241,15 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
239241
llvm::DIFile *debug_Unit;
240242

241243
ASRToLLVMVisitor(Allocator &al, llvm::LLVMContext &context, Platform platform,
242-
bool enable_debug_info, diag::Diagnostics &diagnostics) :
244+
bool emit_debug_info, std::string infile, bool emit_debug_line_column,
245+
diag::Diagnostics &diagnostics) :
243246
diag{diagnostics},
244247
context(context),
245248
builder(std::make_unique<llvm::IRBuilder<>>(context)),
246-
platform{platform}, enable_debug_info{enable_debug_info},
249+
platform{platform},
250+
emit_debug_info{emit_debug_info},
251+
infile{infile},
252+
emit_debug_line_column{emit_debug_line_column},
247253
al{al},
248254
prototype_only(false),
249255
llvm_utils(std::make_unique<LLVMUtils>(context, builder.get())),
@@ -369,11 +375,24 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
369375
}
370376
}
371377

378+
void debug_get_line_column(const uint32_t &loc_first,
379+
uint32_t &line, uint32_t &column) {
380+
LocationManager lm;
381+
lm.in_filename = infile;
382+
lm.init_simple(LFortran::read_file(infile));
383+
lm.pos_to_linecol(lm.output_to_input_pos(loc_first, false), line, column);
384+
}
385+
372386
template <typename T>
373387
void debug_emit_loc(const T &x) {
374388
Location loc = x.base.base.loc;
375-
uint64_t line = loc.first;
376-
uint64_t column = 0;
389+
uint32_t line, column;
390+
if (emit_debug_line_column) {
391+
debug_get_line_column(loc.first, line, column);
392+
} else {
393+
line = loc.first;
394+
column = 0;
395+
}
377396
builder->SetCurrentDebugLocation(
378397
llvm::DILocation::get(debug_current_scope->getContext(),
379398
line, column, debug_current_scope));
@@ -385,8 +404,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
385404
debug_CU->getFilename(),
386405
debug_CU->getDirectory());
387406
llvm::DIScope *FContext = debug_Unit;
388-
uint64_t LineNo, ScopeLine;
389-
LineNo = ScopeLine = 0;
407+
uint32_t line, column;
408+
if (emit_debug_line_column) {
409+
debug_get_line_column(x.base.base.loc.first, line, column);
410+
} else {
411+
line = 0;
412+
}
390413
std::string fn_debug_name = x.m_name;
391414
llvm::DIBasicType *return_type_info = nullptr;
392415
if constexpr (std::is_same_v<T, ASR::Function_t>){
@@ -405,7 +428,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
405428
DBuilder->getOrCreateTypeArray(return_type_info));
406429
SP = DBuilder->createFunction(
407430
FContext, fn_debug_name, llvm::StringRef(), debug_Unit,
408-
LineNo, return_type, ScopeLine,
431+
line, return_type, 0, // TODO: ScopeLine
409432
llvm::DINode::FlagPrototyped,
410433
llvm::DISubprogram::SPFlagDefinition);
411434
debug_current_scope = SP;
@@ -1147,10 +1170,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
11471170
module = std::make_unique<llvm::Module>("LFortran", context);
11481171
module->setDataLayout("");
11491172

1150-
if (enable_debug_info) {
1173+
if (emit_debug_info) {
11511174
DBuilder = std::make_unique<llvm::DIBuilder>(*module);
11521175
debug_CU = DBuilder->createCompileUnit(
1153-
llvm::dwarf::DW_LANG_C, DBuilder->createFile("xxexpr.py", "/yy/"),
1176+
llvm::dwarf::DW_LANG_C, DBuilder->createFile(infile, "."),
11541177
"LPython Compiler", false, "", 0);
11551178
}
11561179

@@ -2249,7 +2272,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
22492272
llvm::Function::ExternalLinkage, "main", module.get());
22502273
llvm::BasicBlock *BB = llvm::BasicBlock::Create(context,
22512274
".entry", F);
2252-
if (enable_debug_info) {
2275+
if (emit_debug_info) {
22532276
llvm::DISubprogram *SP;
22542277
debug_emit_function(x, SP);
22552278
F->setSubprogram(SP);
@@ -2266,7 +2289,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
22662289
dict_api_sc->set_is_dict_present(is_dict_present_copy_sc);
22672290

22682291
// Finalize the debug info.
2269-
if (enable_debug_info) DBuilder->finalize();
2292+
if (emit_debug_info) DBuilder->finalize();
22702293
}
22712294

22722295
/*
@@ -2599,20 +2622,26 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
25992622
}
26002623
}
26012624
llvm::AllocaInst *ptr = builder->CreateAlloca(type, nullptr, v->m_name);
2602-
if (enable_debug_info) {
2625+
if (emit_debug_info) {
26032626
// Reset the debug location
26042627
builder->SetCurrentDebugLocation(nullptr);
2605-
uint64_t LineNo = v->base.base.loc.first;
2628+
uint32_t line, column;
2629+
if (emit_debug_line_column) {
2630+
debug_get_line_column(v->base.base.loc.first, line, column);
2631+
} else {
2632+
line = v->base.base.loc.first;
2633+
column = 0;
2634+
}
26062635
std::string type_name;
26072636
uint32_t type_size, type_encoding;
26082637
get_type_debug_info(v->m_type, type_name, type_size,
26092638
type_encoding);
26102639
llvm::DILocalVariable *debug_var = DBuilder->createParameterVariable(
2611-
debug_current_scope, v->m_name, ++debug_arg_count, debug_Unit, LineNo,
2640+
debug_current_scope, v->m_name, ++debug_arg_count, debug_Unit, line,
26122641
DBuilder->createBasicType(type_name, type_size, type_encoding), true);
26132642
DBuilder->insertDeclare(ptr, debug_var, DBuilder->createExpression(),
26142643
llvm::DILocation::get(debug_current_scope->getContext(),
2615-
LineNo, 0, debug_current_scope), builder->GetInsertBlock());
2644+
line, 0, debug_current_scope), builder->GetInsertBlock());
26162645
}
26172646

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

31853214
// Finalize the debug info.
3186-
if (enable_debug_info) DBuilder->finalize();
3215+
if (emit_debug_info) DBuilder->finalize();
31873216
}
31883217

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

32203249
// Add Debugging information to the LLVM function F
3221-
if (enable_debug_info) {
3250+
if (emit_debug_info) {
32223251
debug_emit_function(x, SP);
32233252
F->setSubprogram(SP);
32243253
}
32253254
} else {
32263255
uint32_t old_h = llvm_symtab_fn_names[fn_name];
32273256
F = llvm_symtab_fn[old_h];
3228-
if (enable_debug_info) {
3257+
if (emit_debug_info) {
32293258
SP = (llvm::DISubprogram*) llvm_symtab_fn_discope[old_h];
32303259
}
32313260
}
32323261
llvm_symtab_fn[h] = F;
3233-
if (enable_debug_info) llvm_symtab_fn_discope[h] = SP;
3262+
if (emit_debug_info) llvm_symtab_fn_discope[h] = SP;
32343263

32353264
// Instantiate (pre-declare) all nested interfaces
32363265
for (auto &item : x.m_symtab->get_scope()) {
@@ -3427,12 +3456,12 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
34273456
parent_function = &x;
34283457
parent_function_hash = h;
34293458
llvm::Function* F = llvm_symtab_fn[h];
3430-
if (enable_debug_info) debug_current_scope = llvm_symtab_fn_discope[h];
3459+
if (emit_debug_info) debug_current_scope = llvm_symtab_fn_discope[h];
34313460
proc_return = llvm::BasicBlock::Create(context, "return");
34323461
llvm::BasicBlock *BB = llvm::BasicBlock::Create(context,
34333462
".entry", F);
34343463
builder->SetInsertPoint(BB);
3435-
if (enable_debug_info) debug_emit_loc(x);
3464+
if (emit_debug_info) debug_emit_loc(x);
34363465
declare_args(x, *F);
34373466
declare_local_vars(x);
34383467
}
@@ -3715,7 +3744,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
37153744
}
37163745

37173746
void visit_Assignment(const ASR::Assignment_t &x) {
3718-
if (enable_debug_info) debug_emit_loc(x);
3747+
if (emit_debug_info) debug_emit_loc(x);
37193748
if( x.m_overloaded ) {
37203749
this->visit_stmt(*x.m_overloaded);
37213750
return ;
@@ -6014,7 +6043,7 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
60146043
}
60156044

60166045
void visit_SubroutineCall(const ASR::SubroutineCall_t &x) {
6017-
if (enable_debug_info) debug_emit_loc(x);
6046+
if (emit_debug_info) debug_emit_loc(x);
60186047
if( ASRUtils::is_intrinsic_optimization(x.m_name) ) {
60196048
ASR::Function_t* routine = ASR::down_cast<ASR::Function_t>(
60206049
ASRUtils::symbol_get_past_external(x.m_name));
@@ -6356,12 +6385,14 @@ Result<std::unique_ptr<LLVMModule>> asr_to_llvm(ASR::TranslationUnit_t &asr,
63566385
diag::Diagnostics &diagnostics,
63576386
llvm::LLVMContext &context, Allocator &al,
63586387
LCompilers::PassManager& pass_manager,
6359-
CompilerOptions &co, const std::string &run_fn)
6388+
CompilerOptions &co, const std::string &run_fn,
6389+
const std::string &infile)
63606390
{
63616391
#if LLVM_VERSION_MAJOR >= 15
63626392
context.setOpaquePointers(false);
63636393
#endif
6364-
ASRToLLVMVisitor v(al, context, co.platform, co.arg_g, diagnostics);
6394+
ASRToLLVMVisitor v(al, context, co.platform, co.emit_debug_info, infile,
6395+
co.emit_debug_line_column, diagnostics);
63656396
LCompilers::PassOptions pass_options;
63666397
pass_options.run_fun = run_fn;
63676398
pass_options.always_run = false;

src/libasr/codegen/asr_to_llvm.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ namespace LFortran {
1212
llvm::LLVMContext &context, Allocator &al,
1313
LCompilers::PassManager& pass_manager,
1414
CompilerOptions &co,
15-
const std::string &run_fn);
15+
const std::string &run_fn,
16+
const std::string &infile);
1617

1718
} // namespace LFortran
1819

src/libasr/pass/global_stmts.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void pass_wrap_global_stmts_into_function(Allocator &al,
2929
SymbolTable *fn_scope = al.make_new<SymbolTable>(unit.m_global_scope);
3030

3131
ASR::ttype_t *type;
32-
Location loc;
32+
Location loc = unit.base.base.loc;
3333
ASR::asr_t *return_var=nullptr;
3434
ASR::expr_t *return_var_ref=nullptr;
3535
char *var_name;

src/libasr/utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ struct CompilerOptions {
3838
bool implicit_interface = false;
3939
std::string target = "";
4040
std::string arg_o = "";
41-
bool arg_g = false;
41+
bool emit_debug_info = false;
42+
bool emit_debug_line_column = false;
4243
std::string import_path = "";
4344
Platform platform;
4445

src/lpython/python_evaluator.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ PythonCompiler::~PythonCompiler() = default;
3939
Result<std::unique_ptr<LLVMModule>> PythonCompiler::get_llvm3(
4040
#ifdef HAVE_LFORTRAN_LLVM
4141
ASR::TranslationUnit_t &asr, LCompilers::PassManager& lpm,
42-
diag::Diagnostics &diagnostics
42+
diag::Diagnostics &diagnostics, const std::string &infile
4343
#else
4444
ASR::TranslationUnit_t &/*asr*/, LCompilers::PassManager&/*lpm*/,
45-
diag::Diagnostics &/*diagnostics*/
45+
diag::Diagnostics &/*diagnostics*/,const std::string &/*infile*/
4646
#endif
4747
)
4848
{
@@ -55,7 +55,7 @@ Result<std::unique_ptr<LLVMModule>> PythonCompiler::get_llvm3(
5555
Result<std::unique_ptr<LFortran::LLVMModule>> res
5656
= asr_to_llvm(asr, diagnostics,
5757
e->get_context(), al, lpm, compiler_options,
58-
run_fn);
58+
run_fn, infile);
5959
if (res.ok) {
6060
m = std::move(res.result);
6161
} else {

src/lpython/python_evaluator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ class PythonCompiler
5252
};
5353

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

5758
private:
5859
Allocator al;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "llvm_dbg-expr_01-9fc5f30",
3+
"cmd": "lpython --no-color --show-llvm -g --debug-with-line-column {infile} -o {outfile}",
4+
"infile": "tests/expr_01.py",
5+
"infile_hash": "4284fe3a1b4dd3e5d1de1357a79e9a25b426ca245b4cc91cf99e8547",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": "llvm_dbg-expr_01-9fc5f30.stdout",
9+
"stdout_hash": "d9ddd67926153e27017b59e3d5786b20797f0819c7943ccb3c334188",
10+
"stderr": null,
11+
"stderr_hash": null,
12+
"returncode": 0
13+
}

tests/reference/llvm_dbg-expr_01-bc258d6.stdout renamed to tests/reference/llvm_dbg-expr_01-9fc5f30.stdout

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,28 +49,28 @@ attributes #0 = { nounwind readnone speculatable willreturn }
4949
!llvm.dbg.cu = !{!0}
5050

5151
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "LPython Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
52-
!1 = !DIFile(filename: "xxexpr.py", directory: "/yy/")
52+
!1 = !DIFile(filename: "tests/expr_01.py", directory: ".")
5353
!2 = !{}
54-
!3 = distinct !DISubprogram(name: "_lpython_main_program", scope: !1, file: !1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
54+
!3 = distinct !DISubprogram(name: "_lpython_main_program", scope: !1, file: !1, line: 1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
5555
!4 = !DISubroutineType(types: !5)
5656
!5 = !{null}
57-
!6 = !DILocation(line: 89, scope: !3)
58-
!7 = distinct !DISubprogram(name: "main0", scope: !1, file: !1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
59-
!8 = !DILocation(line: 0, scope: !7)
60-
!9 = !DILocalVariable(name: "x", arg: 1, scope: !7, file: !1, line: 17, type: !10)
57+
!6 = !DILocation(line: 9, column: 1, scope: !3)
58+
!7 = distinct !DISubprogram(name: "main0", scope: !1, file: !1, line: 1, type: !4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
59+
!8 = !DILocation(line: 1, column: 1, scope: !7)
60+
!9 = !DILocalVariable(name: "x", arg: 1, scope: !7, file: !1, line: 2, type: !10)
6161
!10 = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed)
62-
!11 = !DILocation(line: 17, scope: !7)
63-
!12 = !DILocalVariable(name: "x2", arg: 2, scope: !7, file: !1, line: 28, type: !13)
62+
!11 = !DILocation(line: 2, scope: !7)
63+
!12 = !DILocalVariable(name: "x2", arg: 2, scope: !7, file: !1, line: 3, type: !13)
6464
!13 = !DIBasicType(name: "integer", size: 64, encoding: DW_ATE_signed)
65-
!14 = !DILocation(line: 28, scope: !7)
66-
!15 = !DILocalVariable(name: "y", arg: 3, scope: !7, file: !1, line: 40, type: !16)
65+
!14 = !DILocation(line: 3, scope: !7)
66+
!15 = !DILocalVariable(name: "y", arg: 3, scope: !7, file: !1, line: 4, type: !16)
6767
!16 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
68-
!17 = !DILocation(line: 40, scope: !7)
69-
!18 = !DILocalVariable(name: "y2", arg: 4, scope: !7, file: !1, line: 51, type: !19)
68+
!17 = !DILocation(line: 4, scope: !7)
69+
!18 = !DILocalVariable(name: "y2", arg: 4, scope: !7, file: !1, line: 5, type: !19)
7070
!19 = !DIBasicType(name: "double", size: 64, encoding: DW_ATE_float)
71-
!20 = !DILocation(line: 51, scope: !7)
72-
!21 = !DILocation(line: 63, scope: !7)
73-
!22 = distinct !DISubprogram(name: "main_program", scope: !1, file: !1, type: !23, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
71+
!20 = !DILocation(line: 5, scope: !7)
72+
!21 = !DILocation(line: 6, column: 5, scope: !7)
73+
!22 = distinct !DISubprogram(name: "main_program", scope: !1, file: !1, line: 1, type: !23, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
7474
!23 = !DISubroutineType(types: !24)
7575
!24 = !{!10}
76-
!25 = !DILocation(line: 0, scope: !22)
76+
!25 = !DILocation(line: 1, column: 1, scope: !22)

tests/reference/llvm_dbg-expr_01-bc258d6.json

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)