From 23bff3332ae671cd29806a7420258b1481977358 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Wed, 9 Sep 2026 06:59:08 +0200 Subject: [PATCH 01/14] TODO --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 154 +++++++++++++++++++- 1 file changed, 151 insertions(+), 3 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index c69d1abd4..cf526bfc9 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -31,9 +31,11 @@ #include #include +#include #include #include +#include #include namespace jlm::llvm @@ -45,9 +47,16 @@ class IpGraphToLlvmConverter::Context final std::unordered_map::const_iterator; public: - Context(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) + Context( + InterProceduralGraphModule & ipGraphModule, + ::llvm::Module & llvmModule, + std::unique_ptr<::llvm::DIBuilder> diBuilder) : LlvmModule_(llvmModule), - IpGraphModule_(ipGraphModule) + IpGraphModule_(ipGraphModule), + diBuilder_(std::move(diBuilder)), + diCompileUnit_(nullptr), + diFile_(nullptr), + diSubprogram_(nullptr) {} Context(const Context &) = delete; @@ -74,6 +83,49 @@ class IpGraphToLlvmConverter::Context final return LlvmModule_; } + void + setDIBuilder(std::unique_ptr<::llvm::DIBuilder> diBuilder) noexcept + { + diBuilder_ = std::move(diBuilder); + } + + [[nodiscard]] bool + hasDIBuilder() const noexcept + { + return diBuilder_ != nullptr; + } + + [[nodiscard]] ::llvm::DIBuilder & + di_builder() const noexcept + { + JLM_ASSERT(diBuilder_ != nullptr); + return *diBuilder_; + } + + void + setDICompileUnit(::llvm::DICompileUnit * cu) noexcept + { + diCompileUnit_ = cu; + } + + [[nodiscard]] ::llvm::DICompileUnit * + di_compile_unit() const noexcept + { + return diCompileUnit_; + } + + void + setDIFile(::llvm::DIFile * file) noexcept + { + diFile_ = file; + } + + [[nodiscard]] ::llvm::DIFile * + di_file() const noexcept + { + return diFile_; + } + const_iterator begin() const { @@ -114,6 +166,25 @@ class IpGraphToLlvmConverter::Context final return it->second; } + void + setDISubprogram(::llvm::DISubprogram * diSubprogram) noexcept + { + diSubprogram_ = diSubprogram; + } + + [[nodiscard]] bool + hasDISubprogram() const noexcept + { + return diSubprogram_ != nullptr; + } + + [[nodiscard]] ::llvm::DISubprogram * + getDISubprogram() const noexcept + { + JLM_ASSERT(diSubprogram_ != nullptr); + return diSubprogram_; + } + TypeConverter & GetTypeConverter() { @@ -121,7 +192,10 @@ class IpGraphToLlvmConverter::Context final } static std::unique_ptr - Create(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) + Create( + InterProceduralGraphModule & ipGraphModule, + ::llvm::Module & llvmModule, + std::unique_ptr<::llvm::DIBuilder> diBuilder) { return std::make_unique(ipGraphModule, llvmModule); } @@ -129,6 +203,10 @@ class IpGraphToLlvmConverter::Context final private: ::llvm::Module & LlvmModule_; InterProceduralGraphModule & IpGraphModule_; + std::unique_ptr<::llvm::DIBuilder> diBuilder_; + ::llvm::DICompileUnit * diCompileUnit_; + ::llvm::DIFile * diFile_; + ::llvm::DISubprogram * diSubprogram_; std::unordered_map variables_; std::unordered_map nodes_; TypeConverter TypeConverter_; @@ -1748,6 +1826,15 @@ IpGraphToLlvmConverter::convert_instruction( operands.push_back(tac.operand(n)); ::llvm::IRBuilder<> builder(Context_->basic_block(node)); + if (Context_->hasDISubprogram()) + { + auto debugLoc = ::llvm::DILocation::get( + Context_->llvm_module().getContext(), + 1, + 1, + Context_->getDISubprogram()); + builder.SetCurrentDebugLocation(debugLoc); + } const auto & op = tac.operation(); auto r = convert_operation(op, op, operands, builder); if (r != nullptr) @@ -1830,6 +1917,15 @@ IpGraphToLlvmConverter::create_conditional_branch(const ControlFlowGraphNode * n JLM_ASSERT(node->OutEdge(0)->sink() != node->cfg().exit()); JLM_ASSERT(node->OutEdge(1)->sink() != node->cfg().exit()); ::llvm::IRBuilder<> builder(Context_->basic_block(node)); + if (Context_->hasDISubprogram()) + { + auto debugLoc = ::llvm::DILocation::get( + Context_->llvm_module().getContext(), + 2, + 3, + Context_->getDISubprogram()); + builder.SetCurrentDebugLocation(debugLoc); + } auto branch = static_cast(node)->tacs().last(); JLM_ASSERT(branch && is(branch)); @@ -2223,10 +2319,13 @@ IpGraphToLlvmConverter::convert_function(const FunctionNode & node) auto & im = Context_->module(); auto f = ::llvm::cast<::llvm::Function>(Context_->value(im.variable(&node))); + Context_->setDISubprogram(f->getSubprogram()); + // Type, name, attributes and calling convention have already been set on the LLVM Function. // The only conversion that remains is the function body. convert_cfg(*node.cfg(), *f); + Context_->setDISubprogram(nullptr); } void @@ -2304,6 +2403,31 @@ IpGraphToLlvmConverter::convert_ipgraph() auto attributes = convert_attributes(*n); f->setAttributes(attributes); + // Create and attach debug info only for function *definitions*. + // For declarations (e.g. libc functions like printf), attaching multiple distinct + // DISubprograms across translation units/passes can easily create invalid IR. + if (n->cfg() && Context_->hasDIBuilder()) + { + auto * file = Context_->di_file(); + if (file != nullptr) + { + auto & dib = Context_->di_builder(); + auto diTypeArray = dib.getOrCreateTypeArray({}); + auto * subroutineType = dib.createSubroutineType(diTypeArray); + auto * sp = dib.createFunction( + file, + n->name(), + n->name(), + file, + 1, + subroutineType, + 1, + ::llvm::DINode::FlagZero, + ::llvm::DISubprogram::SPFlagDefinition); + f->setSubprogram(sp); + } + } + Context_->insert(v, f); } else @@ -2337,8 +2461,32 @@ IpGraphToLlvmConverter::ConvertModule( llvmModule->setDataLayout(ipGraphModule.data_layout()); Context_ = Context::Create(ipGraphModule, *llvmModule); + + // Initialize module-level debug info so that functions can get DISubprograms attached. + // This creates a minimal compile unit + file; callers without a source filename still work. + { + llvmModule->addModuleFlag( + ::llvm::Module::Warning, + "Debug Info Version", + ::llvm::DEBUG_METADATA_VERSION); + + auto dib = std::make_unique<::llvm::DIBuilder>(*llvmModule); + auto sourceFile = llvmModule->getSourceFileName(); + if (sourceFile.empty()) + sourceFile = "unknown"; + + auto * file = dib->createFile(sourceFile, "."); + Context_->setDIFile(file); + auto * cu = dib->createCompileUnit(::llvm::dwarf::DW_LANG_C, file, "jlm", false, "", 0); + Context_->setDICompileUnit(cu); + Context_->setDIBuilder(std::move(dib)); + } + convert_ipgraph(); + if (Context_->hasDIBuilder()) + Context_->di_builder().finalize(); + return llvmModule; } From e4dac2f8f9cda9d58981d8345737f2c9e0b6bf62 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Wed, 9 Sep 2026 07:14:36 +0200 Subject: [PATCH 02/14] TODO --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 126 ++++++-------------- 1 file changed, 38 insertions(+), 88 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index cf526bfc9..90324627b 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -47,17 +47,25 @@ class IpGraphToLlvmConverter::Context final std::unordered_map::const_iterator; public: - Context( - InterProceduralGraphModule & ipGraphModule, - ::llvm::Module & llvmModule, - std::unique_ptr<::llvm::DIBuilder> diBuilder) + ~Context() + { + diBuilder_.finalize(); + } + + Context(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) : LlvmModule_(llvmModule), IpGraphModule_(ipGraphModule), - diBuilder_(std::move(diBuilder)), - diCompileUnit_(nullptr), + diBuilder_(llvmModule), diFile_(nullptr), diSubprogram_(nullptr) - {} + { + auto sourceFile = llvmModule.getSourceFileName(); + if (sourceFile.empty()) + sourceFile = "unknown"; + + diFile_ = diBuilder_.createFile(sourceFile, "."); + diBuilder_.createCompileUnit(::llvm::dwarf::DW_LANG_C, diFile_, "jlm", false, "", 0); + } Context(const Context &) = delete; @@ -83,41 +91,10 @@ class IpGraphToLlvmConverter::Context final return LlvmModule_; } - void - setDIBuilder(std::unique_ptr<::llvm::DIBuilder> diBuilder) noexcept - { - diBuilder_ = std::move(diBuilder); - } - - [[nodiscard]] bool - hasDIBuilder() const noexcept - { - return diBuilder_ != nullptr; - } - [[nodiscard]] ::llvm::DIBuilder & - di_builder() const noexcept + getDIBuilder() noexcept { - JLM_ASSERT(diBuilder_ != nullptr); - return *diBuilder_; - } - - void - setDICompileUnit(::llvm::DICompileUnit * cu) noexcept - { - diCompileUnit_ = cu; - } - - [[nodiscard]] ::llvm::DICompileUnit * - di_compile_unit() const noexcept - { - return diCompileUnit_; - } - - void - setDIFile(::llvm::DIFile * file) noexcept - { - diFile_ = file; + return diBuilder_; } [[nodiscard]] ::llvm::DIFile * @@ -192,10 +169,7 @@ class IpGraphToLlvmConverter::Context final } static std::unique_ptr - Create( - InterProceduralGraphModule & ipGraphModule, - ::llvm::Module & llvmModule, - std::unique_ptr<::llvm::DIBuilder> diBuilder) + Create(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) { return std::make_unique(ipGraphModule, llvmModule); } @@ -203,8 +177,7 @@ class IpGraphToLlvmConverter::Context final private: ::llvm::Module & LlvmModule_; InterProceduralGraphModule & IpGraphModule_; - std::unique_ptr<::llvm::DIBuilder> diBuilder_; - ::llvm::DICompileUnit * diCompileUnit_; + ::llvm::DIBuilder diBuilder_; ::llvm::DIFile * diFile_; ::llvm::DISubprogram * diSubprogram_; std::unordered_map variables_; @@ -2406,26 +2379,22 @@ IpGraphToLlvmConverter::convert_ipgraph() // Create and attach debug info only for function *definitions*. // For declarations (e.g. libc functions like printf), attaching multiple distinct // DISubprograms across translation units/passes can easily create invalid IR. - if (n->cfg() && Context_->hasDIBuilder()) + if (n->cfg()) { - auto * file = Context_->di_file(); - if (file != nullptr) - { - auto & dib = Context_->di_builder(); - auto diTypeArray = dib.getOrCreateTypeArray({}); - auto * subroutineType = dib.createSubroutineType(diTypeArray); - auto * sp = dib.createFunction( - file, - n->name(), - n->name(), - file, - 1, - subroutineType, - 1, - ::llvm::DINode::FlagZero, - ::llvm::DISubprogram::SPFlagDefinition); - f->setSubprogram(sp); - } + auto & diBuilder = Context_->getDIBuilder(); + auto diTypeArray = diBuilder.getOrCreateTypeArray({}); + auto * subroutineType = diBuilder.createSubroutineType(diTypeArray); + auto * sp = diBuilder.createFunction( + Context_->di_file(), + n->name(), + n->name(), + Context_->di_file(), + 1, + subroutineType, + 1, + ::llvm::DINode::FlagZero, + ::llvm::DISubprogram::SPFlagDefinition); + f->setSubprogram(sp); } Context_->insert(v, f); @@ -2459,34 +2428,15 @@ IpGraphToLlvmConverter::ConvertModule( llvmModule->setSourceFileName(ipGraphModule.source_filename().to_str()); llvmModule->setTargetTriple(ipGraphModule.target_triple()); llvmModule->setDataLayout(ipGraphModule.data_layout()); + llvmModule->addModuleFlag( + ::llvm::Module::Warning, + "Debug Info Version", + ::llvm::DEBUG_METADATA_VERSION); Context_ = Context::Create(ipGraphModule, *llvmModule); - // Initialize module-level debug info so that functions can get DISubprograms attached. - // This creates a minimal compile unit + file; callers without a source filename still work. - { - llvmModule->addModuleFlag( - ::llvm::Module::Warning, - "Debug Info Version", - ::llvm::DEBUG_METADATA_VERSION); - - auto dib = std::make_unique<::llvm::DIBuilder>(*llvmModule); - auto sourceFile = llvmModule->getSourceFileName(); - if (sourceFile.empty()) - sourceFile = "unknown"; - - auto * file = dib->createFile(sourceFile, "."); - Context_->setDIFile(file); - auto * cu = dib->createCompileUnit(::llvm::dwarf::DW_LANG_C, file, "jlm", false, "", 0); - Context_->setDICompileUnit(cu); - Context_->setDIBuilder(std::move(dib)); - } - convert_ipgraph(); - if (Context_->hasDIBuilder()) - Context_->di_builder().finalize(); - return llvmModule; } From 375b34022cb7828fda2d9e8078e1f9cea69ba2b5 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Wed, 9 Sep 2026 07:15:38 +0200 Subject: [PATCH 03/14] TODO --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 90324627b..3d9f9de9c 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -2434,7 +2434,6 @@ IpGraphToLlvmConverter::ConvertModule( ::llvm::DEBUG_METADATA_VERSION); Context_ = Context::Create(ipGraphModule, *llvmModule); - convert_ipgraph(); return llvmModule; From 7e514a97b1e2a4db68ccfbb6a1acb1fa7ffdb696 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Wed, 9 Sep 2026 12:43:07 +0200 Subject: [PATCH 04/14] more --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 22 +++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 3d9f9de9c..8d694f230 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -1799,12 +1799,13 @@ IpGraphToLlvmConverter::convert_instruction( operands.push_back(tac.operand(n)); ::llvm::IRBuilder<> builder(Context_->basic_block(node)); - if (Context_->hasDISubprogram()) + auto rvsdgNodeLocation = tac.getRvsdgNodeLocation(); + if (Context_->hasDISubprogram() && rvsdgNodeLocation.has_value()) { auto debugLoc = ::llvm::DILocation::get( Context_->llvm_module().getContext(), - 1, - 1, + rvsdgNodeLocation.value().regionId, + rvsdgNodeLocation.value().nodeId, Context_->getDISubprogram()); builder.SetCurrentDebugLocation(debugLoc); } @@ -1890,20 +1891,21 @@ IpGraphToLlvmConverter::create_conditional_branch(const ControlFlowGraphNode * n JLM_ASSERT(node->OutEdge(0)->sink() != node->cfg().exit()); JLM_ASSERT(node->OutEdge(1)->sink() != node->cfg().exit()); ::llvm::IRBuilder<> builder(Context_->basic_block(node)); - if (Context_->hasDISubprogram()) + + auto branch = static_cast(node)->tacs().last(); + JLM_ASSERT(branch && is(branch)); + JLM_ASSERT(Context_->value(branch->operand(0))->getType()->isIntegerTy(1)); + auto rvsdgNodeLocation = branch->getRvsdgNodeLocation(); + if (Context_->hasDISubprogram() && rvsdgNodeLocation.has_value()) { auto debugLoc = ::llvm::DILocation::get( Context_->llvm_module().getContext(), - 2, - 3, + rvsdgNodeLocation.value().regionId, + rvsdgNodeLocation.value().nodeId, Context_->getDISubprogram()); builder.SetCurrentDebugLocation(debugLoc); } - auto branch = static_cast(node)->tacs().last(); - JLM_ASSERT(branch && is(branch)); - JLM_ASSERT(Context_->value(branch->operand(0))->getType()->isIntegerTy(1)); - auto condition = Context_->value(branch->operand(0)); auto bbfalse = Context_->basic_block(node->OutEdge(0)->sink()); auto bbtrue = Context_->basic_block(node->OutEdge(1)->sink()); From e42cc1e9e79630efdf1d71874acf6a2924645827 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Thu, 17 Sep 2026 05:29:13 +0200 Subject: [PATCH 05/14] more --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 46 +++++++++++---------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 8d694f230..4c0121c6b 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -31,11 +31,11 @@ #include #include +#include #include #include #include -#include #include namespace jlm::llvm @@ -47,25 +47,16 @@ class IpGraphToLlvmConverter::Context final std::unordered_map::const_iterator; public: - ~Context() - { - diBuilder_.finalize(); - } - - Context(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) + Context( + InterProceduralGraphModule & ipGraphModule, + ::llvm::Module & llvmModule, + ::llvm::DIBuilder & diBuilder) : LlvmModule_(llvmModule), IpGraphModule_(ipGraphModule), - diBuilder_(llvmModule), + diBuilder_(&diBuilder), diFile_(nullptr), diSubprogram_(nullptr) - { - auto sourceFile = llvmModule.getSourceFileName(); - if (sourceFile.empty()) - sourceFile = "unknown"; - - diFile_ = diBuilder_.createFile(sourceFile, "."); - diBuilder_.createCompileUnit(::llvm::dwarf::DW_LANG_C, diFile_, "jlm", false, "", 0); - } + {} Context(const Context &) = delete; @@ -94,7 +85,7 @@ class IpGraphToLlvmConverter::Context final [[nodiscard]] ::llvm::DIBuilder & getDIBuilder() noexcept { - return diBuilder_; + return *diBuilder_; } [[nodiscard]] ::llvm::DIFile * @@ -169,15 +160,18 @@ class IpGraphToLlvmConverter::Context final } static std::unique_ptr - Create(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) + Create( + InterProceduralGraphModule & ipGraphModule, + ::llvm::Module & llvmModule, + ::llvm::DIBuilder & diBuilder) { - return std::make_unique(ipGraphModule, llvmModule); + return std::make_unique(ipGraphModule, llvmModule, diBuilder); } private: ::llvm::Module & LlvmModule_; InterProceduralGraphModule & IpGraphModule_; - ::llvm::DIBuilder diBuilder_; + ::llvm::DIBuilder * diBuilder_; ::llvm::DIFile * diFile_; ::llvm::DISubprogram * diSubprogram_; std::unordered_map variables_; @@ -2435,9 +2429,19 @@ IpGraphToLlvmConverter::ConvertModule( "Debug Info Version", ::llvm::DEBUG_METADATA_VERSION); - Context_ = Context::Create(ipGraphModule, *llvmModule); + ::llvm::DIBuilder diBuilder(*llvmModule); + auto sourceFile = llvmModule->getSourceFileName(); + if (sourceFile.empty()) + sourceFile = "unknown"; + + const auto diFile = diBuilder.createFile(sourceFile, "."); + diBuilder.createCompileUnit(::llvm::dwarf::DW_LANG_C, diFile, "jlm", false, "", 0); + + Context_ = Context::Create(ipGraphModule, *llvmModule, diBuilder); convert_ipgraph(); + diBuilder.finalize(); + return llvmModule; } From 85f69b2d3ca28ade6e4deadf12a73fe6c87a31aa Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Thu, 17 Sep 2026 05:32:56 +0200 Subject: [PATCH 06/14] more --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 4c0121c6b..1bb9e56e4 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -88,10 +88,10 @@ class IpGraphToLlvmConverter::Context final return *diBuilder_; } - [[nodiscard]] ::llvm::DIFile * - di_file() const noexcept + [[nodiscard]] ::llvm::DIFile & + getDIFile() const noexcept { - return diFile_; + return *diFile_; } const_iterator @@ -2381,10 +2381,10 @@ IpGraphToLlvmConverter::convert_ipgraph() auto diTypeArray = diBuilder.getOrCreateTypeArray({}); auto * subroutineType = diBuilder.createSubroutineType(diTypeArray); auto * sp = diBuilder.createFunction( - Context_->di_file(), + &Context_->getDIFile(), n->name(), n->name(), - Context_->di_file(), + &Context_->getDIFile(), 1, subroutineType, 1, From f07b032975b6e4828463d8abf3e77fd36c5f18ff Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Thu, 17 Sep 2026 05:44:45 +0200 Subject: [PATCH 07/14] more --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 29 ++++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 1bb9e56e4..7b9a36a71 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -50,11 +50,12 @@ class IpGraphToLlvmConverter::Context final Context( InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule, - ::llvm::DIBuilder & diBuilder) + ::llvm::DIBuilder & diBuilder, + ::llvm::DICompileUnit & diCompileUnit) : LlvmModule_(llvmModule), IpGraphModule_(ipGraphModule), diBuilder_(&diBuilder), - diFile_(nullptr), + diCompileUnit_(&diCompileUnit), diSubprogram_(nullptr) {} @@ -88,10 +89,10 @@ class IpGraphToLlvmConverter::Context final return *diBuilder_; } - [[nodiscard]] ::llvm::DIFile & - getDIFile() const noexcept + [[nodiscard]] ::llvm::DICompileUnit & + getDICompileUnit() const noexcept { - return *diFile_; + return *diCompileUnit_; } const_iterator @@ -163,16 +164,17 @@ class IpGraphToLlvmConverter::Context final Create( InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule, - ::llvm::DIBuilder & diBuilder) + ::llvm::DIBuilder & diBuilder, + ::llvm::DICompileUnit & diCompileUnit) { - return std::make_unique(ipGraphModule, llvmModule, diBuilder); + return std::make_unique(ipGraphModule, llvmModule, diBuilder, diCompileUnit); } private: ::llvm::Module & LlvmModule_; InterProceduralGraphModule & IpGraphModule_; ::llvm::DIBuilder * diBuilder_; - ::llvm::DIFile * diFile_; + ::llvm::DICompileUnit * diCompileUnit_; ::llvm::DISubprogram * diSubprogram_; std::unordered_map variables_; std::unordered_map nodes_; @@ -2381,10 +2383,10 @@ IpGraphToLlvmConverter::convert_ipgraph() auto diTypeArray = diBuilder.getOrCreateTypeArray({}); auto * subroutineType = diBuilder.createSubroutineType(diTypeArray); auto * sp = diBuilder.createFunction( - &Context_->getDIFile(), + Context_->getDICompileUnit().getFile(), n->name(), n->name(), - &Context_->getDIFile(), + Context_->getDICompileUnit().getFile(), 1, subroutineType, 1, @@ -2434,10 +2436,11 @@ IpGraphToLlvmConverter::ConvertModule( if (sourceFile.empty()) sourceFile = "unknown"; - const auto diFile = diBuilder.createFile(sourceFile, "."); - diBuilder.createCompileUnit(::llvm::dwarf::DW_LANG_C, diFile, "jlm", false, "", 0); + auto diFile = diBuilder.createFile(sourceFile, "."); + auto diCompileUnit = + diBuilder.createCompileUnit(::llvm::dwarf::DW_LANG_C, diFile, "jlm", false, "", 0); - Context_ = Context::Create(ipGraphModule, *llvmModule, diBuilder); + Context_ = Context::Create(ipGraphModule, *llvmModule, diBuilder, *diCompileUnit); convert_ipgraph(); diBuilder.finalize(); From 3d120a2a247ea6fa348f462015530d53263ee63e Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Thu, 17 Sep 2026 05:58:41 +0200 Subject: [PATCH 08/14] more --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 35 ++++++++++++--------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 7b9a36a71..7309ac49b 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -50,12 +50,10 @@ class IpGraphToLlvmConverter::Context final Context( InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule, - ::llvm::DIBuilder & diBuilder, - ::llvm::DICompileUnit & diCompileUnit) - : LlvmModule_(llvmModule), + ::llvm::DIBuilder & diBuilder) + : llvmModule_(llvmModule), IpGraphModule_(ipGraphModule), diBuilder_(&diBuilder), - diCompileUnit_(&diCompileUnit), diSubprogram_(nullptr) {} @@ -80,7 +78,7 @@ class IpGraphToLlvmConverter::Context final ::llvm::Module & llvm_module() const noexcept { - return LlvmModule_; + return llvmModule_; } [[nodiscard]] ::llvm::DIBuilder & @@ -92,7 +90,12 @@ class IpGraphToLlvmConverter::Context final [[nodiscard]] ::llvm::DICompileUnit & getDICompileUnit() const noexcept { - return *diCompileUnit_; + JLM_ASSERT( + std::distance( + llvmModule_.debug_compile_units().begin(), + llvmModule_.debug_compile_units().end()) + == 1); + return **llvmModule_.debug_compile_units().begin(); } const_iterator @@ -164,17 +167,15 @@ class IpGraphToLlvmConverter::Context final Create( InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule, - ::llvm::DIBuilder & diBuilder, - ::llvm::DICompileUnit & diCompileUnit) + ::llvm::DIBuilder & diBuilder) { - return std::make_unique(ipGraphModule, llvmModule, diBuilder, diCompileUnit); + return std::make_unique(ipGraphModule, llvmModule, diBuilder); } private: - ::llvm::Module & LlvmModule_; + ::llvm::Module & llvmModule_; InterProceduralGraphModule & IpGraphModule_; ::llvm::DIBuilder * diBuilder_; - ::llvm::DICompileUnit * diCompileUnit_; ::llvm::DISubprogram * diSubprogram_; std::unordered_map variables_; std::unordered_map nodes_; @@ -2436,11 +2437,15 @@ IpGraphToLlvmConverter::ConvertModule( if (sourceFile.empty()) sourceFile = "unknown"; - auto diFile = diBuilder.createFile(sourceFile, "."); - auto diCompileUnit = - diBuilder.createCompileUnit(::llvm::dwarf::DW_LANG_C, diFile, "jlm", false, "", 0); + diBuilder.createCompileUnit( + ::llvm::dwarf::DW_LANG_C, + diBuilder.createFile(sourceFile, "."), + "jlm", + false, + "", + 0); - Context_ = Context::Create(ipGraphModule, *llvmModule, diBuilder, *diCompileUnit); + Context_ = Context::Create(ipGraphModule, *llvmModule, diBuilder); convert_ipgraph(); diBuilder.finalize(); From 60099efe97e5e43b62ea22ad7447327130a15315 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Thu, 17 Sep 2026 06:15:43 +0200 Subject: [PATCH 09/14] more --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 54 ++++++--------------- jlm/llvm/backend/IpGraphToLlvmConverter.hpp | 11 +++-- 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 7309ac49b..3fd28cc7a 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -53,8 +53,7 @@ class IpGraphToLlvmConverter::Context final ::llvm::DIBuilder & diBuilder) : llvmModule_(llvmModule), IpGraphModule_(ipGraphModule), - diBuilder_(&diBuilder), - diSubprogram_(nullptr) + diBuilder_(&diBuilder) {} Context(const Context &) = delete; @@ -138,25 +137,6 @@ class IpGraphToLlvmConverter::Context final return it->second; } - void - setDISubprogram(::llvm::DISubprogram * diSubprogram) noexcept - { - diSubprogram_ = diSubprogram; - } - - [[nodiscard]] bool - hasDISubprogram() const noexcept - { - return diSubprogram_ != nullptr; - } - - [[nodiscard]] ::llvm::DISubprogram * - getDISubprogram() const noexcept - { - JLM_ASSERT(diSubprogram_ != nullptr); - return diSubprogram_; - } - TypeConverter & GetTypeConverter() { @@ -176,7 +156,6 @@ class IpGraphToLlvmConverter::Context final ::llvm::Module & llvmModule_; InterProceduralGraphModule & IpGraphModule_; ::llvm::DIBuilder * diBuilder_; - ::llvm::DISubprogram * diSubprogram_; std::unordered_map variables_; std::unordered_map nodes_; TypeConverter TypeConverter_; @@ -1789,21 +1768,21 @@ IpGraphToLlvmConverter::convert_operation( void IpGraphToLlvmConverter::convert_instruction( const llvm::ThreeAddressCode & tac, - const llvm::ControlFlowGraphNode * node) + const llvm::ControlFlowGraphNode * node, + ::llvm::DISubprogram & diSubprogram) { std::vector operands; for (size_t n = 0; n < tac.noperands(); n++) operands.push_back(tac.operand(n)); ::llvm::IRBuilder<> builder(Context_->basic_block(node)); - auto rvsdgNodeLocation = tac.getRvsdgNodeLocation(); - if (Context_->hasDISubprogram() && rvsdgNodeLocation.has_value()) + if (const auto rvsdgNodeLocation = tac.getRvsdgNodeLocation(); rvsdgNodeLocation.has_value()) { auto debugLoc = ::llvm::DILocation::get( Context_->llvm_module().getContext(), rvsdgNodeLocation.value().regionId, rvsdgNodeLocation.value().nodeId, - Context_->getDISubprogram()); + &diSubprogram); builder.SetCurrentDebugLocation(debugLoc); } const auto & op = tac.operation(); @@ -1882,7 +1861,9 @@ IpGraphToLlvmConverter::create_unconditional_branch(const ControlFlowGraphNode * } void -IpGraphToLlvmConverter::create_conditional_branch(const ControlFlowGraphNode * node) +IpGraphToLlvmConverter::create_conditional_branch( + const ControlFlowGraphNode * node, + ::llvm::DISubprogram & diSubprogram) { JLM_ASSERT(node->NumOutEdges() == 2); JLM_ASSERT(node->OutEdge(0)->sink() != node->cfg().exit()); @@ -1892,14 +1873,13 @@ IpGraphToLlvmConverter::create_conditional_branch(const ControlFlowGraphNode * n auto branch = static_cast(node)->tacs().last(); JLM_ASSERT(branch && is(branch)); JLM_ASSERT(Context_->value(branch->operand(0))->getType()->isIntegerTy(1)); - auto rvsdgNodeLocation = branch->getRvsdgNodeLocation(); - if (Context_->hasDISubprogram() && rvsdgNodeLocation.has_value()) + if (const auto rvsdgNodeLocation = branch->getRvsdgNodeLocation(); rvsdgNodeLocation.has_value()) { auto debugLoc = ::llvm::DILocation::get( Context_->llvm_module().getContext(), rvsdgNodeLocation.value().regionId, rvsdgNodeLocation.value().nodeId, - Context_->getDISubprogram()); + &diSubprogram); builder.SetCurrentDebugLocation(debugLoc); } @@ -1951,7 +1931,9 @@ IpGraphToLlvmConverter::create_switch(const ControlFlowGraphNode * node) } void -IpGraphToLlvmConverter::create_terminator_instruction(const llvm::ControlFlowGraphNode * node) +IpGraphToLlvmConverter::create_terminator_instruction( + const llvm::ControlFlowGraphNode * node, + ::llvm::DISubprogram & diSubprogram) { JLM_ASSERT(is(node)); auto & tacs = static_cast(node)->tacs(); @@ -1972,7 +1954,7 @@ IpGraphToLlvmConverter::create_terminator_instruction(const llvm::ControlFlowGra // conditional branch if (Context_->value(branch->operand(0))->getType()->isIntegerTy(1)) - return create_conditional_branch(node); + return create_conditional_branch(node, diSubprogram); // switch create_switch(node); @@ -2241,7 +2223,7 @@ IpGraphToLlvmConverter::convert_cfg(ControlFlowGraph & cfg, ::llvm::Function & f JLM_ASSERT(is(node)); auto & tacs = static_cast(node)->tacs(); for (const auto & tac : tacs) - convert_instruction(*tac, node); + convert_instruction(*tac, node, *f.getSubprogram()); } // create cfg structure @@ -2250,7 +2232,7 @@ IpGraphToLlvmConverter::convert_cfg(ControlFlowGraph & cfg, ::llvm::Function & f if (node == cfg.entry() || node == cfg.exit()) continue; - create_terminator_instruction(node); + create_terminator_instruction(node, *f.getSubprogram()); } // patch phi instructions @@ -2291,13 +2273,9 @@ IpGraphToLlvmConverter::convert_function(const FunctionNode & node) auto & im = Context_->module(); auto f = ::llvm::cast<::llvm::Function>(Context_->value(im.variable(&node))); - Context_->setDISubprogram(f->getSubprogram()); - // Type, name, attributes and calling convention have already been set on the LLVM Function. // The only conversion that remains is the function body. - convert_cfg(*node.cfg(), *f); - Context_->setDISubprogram(nullptr); } void diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.hpp b/jlm/llvm/backend/IpGraphToLlvmConverter.hpp index ee9673156..e7fdeece0 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.hpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.hpp @@ -139,13 +139,15 @@ class IpGraphToLlvmConverter final ConvertEnumAttribute(const llvm::EnumAttribute & attribute); void - create_terminator_instruction(const llvm::ControlFlowGraphNode * node); + create_terminator_instruction( + const llvm::ControlFlowGraphNode * node, + ::llvm::DISubprogram & diSubprogram); void create_switch(const ControlFlowGraphNode * node); void - create_conditional_branch(const ControlFlowGraphNode * node); + create_conditional_branch(const ControlFlowGraphNode * node, ::llvm::DISubprogram & diSubprogram); void create_unconditional_branch(const ControlFlowGraphNode * node); @@ -157,7 +159,10 @@ class IpGraphToLlvmConverter final convert_tacs(const tacsvector_t & tacs); void - convert_instruction(const llvm::ThreeAddressCode & tac, const llvm::ControlFlowGraphNode * node); + convert_instruction( + const llvm::ThreeAddressCode & tac, + const llvm::ControlFlowGraphNode * node, + ::llvm::DISubprogram & diSubprogram); /** * Converts the given operation, with the given arguments, to an LLVM instruction. From cb5e4f9804c66e977f789db9eb9d4529cc60e7f8 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Thu, 17 Sep 2026 06:24:54 +0200 Subject: [PATCH 10/14] more --- jlm/llvm/backend/IpGraphToLlvmConverter.cpp | 54 ++++++++++----------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp index 3fd28cc7a..42ef30ddd 100644 --- a/jlm/llvm/backend/IpGraphToLlvmConverter.cpp +++ b/jlm/llvm/backend/IpGraphToLlvmConverter.cpp @@ -47,14 +47,28 @@ class IpGraphToLlvmConverter::Context final std::unordered_map::const_iterator; public: - Context( - InterProceduralGraphModule & ipGraphModule, - ::llvm::Module & llvmModule, - ::llvm::DIBuilder & diBuilder) + ~Context() + { + diBuilder_.finalize(); + } + + Context(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) : llvmModule_(llvmModule), IpGraphModule_(ipGraphModule), - diBuilder_(&diBuilder) - {} + diBuilder_(llvmModule) + { + auto sourceFile = llvmModule.getSourceFileName(); + if (sourceFile.empty()) + sourceFile = "unknown"; + + diBuilder_.createCompileUnit( + ::llvm::dwarf::DW_LANG_C, + diBuilder_.createFile(sourceFile, "."), + "jlm", + false, + "", + 0); + } Context(const Context &) = delete; @@ -83,7 +97,7 @@ class IpGraphToLlvmConverter::Context final [[nodiscard]] ::llvm::DIBuilder & getDIBuilder() noexcept { - return *diBuilder_; + return diBuilder_; } [[nodiscard]] ::llvm::DICompileUnit & @@ -144,18 +158,15 @@ class IpGraphToLlvmConverter::Context final } static std::unique_ptr - Create( - InterProceduralGraphModule & ipGraphModule, - ::llvm::Module & llvmModule, - ::llvm::DIBuilder & diBuilder) + Create(InterProceduralGraphModule & ipGraphModule, ::llvm::Module & llvmModule) { - return std::make_unique(ipGraphModule, llvmModule, diBuilder); + return std::make_unique(ipGraphModule, llvmModule); } private: ::llvm::Module & llvmModule_; InterProceduralGraphModule & IpGraphModule_; - ::llvm::DIBuilder * diBuilder_; + ::llvm::DIBuilder diBuilder_; std::unordered_map variables_; std::unordered_map nodes_; TypeConverter TypeConverter_; @@ -2410,24 +2421,9 @@ IpGraphToLlvmConverter::ConvertModule( "Debug Info Version", ::llvm::DEBUG_METADATA_VERSION); - ::llvm::DIBuilder diBuilder(*llvmModule); - auto sourceFile = llvmModule->getSourceFileName(); - if (sourceFile.empty()) - sourceFile = "unknown"; - - diBuilder.createCompileUnit( - ::llvm::dwarf::DW_LANG_C, - diBuilder.createFile(sourceFile, "."), - "jlm", - false, - "", - 0); - - Context_ = Context::Create(ipGraphModule, *llvmModule, diBuilder); + Context_ = Context::Create(ipGraphModule, *llvmModule); convert_ipgraph(); - diBuilder.finalize(); - return llvmModule; } From 9cf8fa0cecd26075264f57eb19245abd570a4389 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Thu, 17 Sep 2026 06:57:28 +0200 Subject: [PATCH 11/14] golden --- .../golden/hls-test-suite/decoupled/mergesort_decouple.cycles | 2 +- .../golden/hls-test-suite/decoupled/mergesort_decouple3.cycles | 2 +- .../golden/hls-test-suite/decoupled/mergesort_decouple4.cycles | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple.cycles index 8cf24d613..2606a9111 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple.cycles @@ -1 +1 @@ -193558 \ No newline at end of file +193602 \ No newline at end of file diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles index 9e538f3c6..8a5316ba7 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles @@ -1 +1 @@ -13766 \ No newline at end of file +13813 \ No newline at end of file diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles index 9e538f3c6..8a5316ba7 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles @@ -1 +1 @@ -13766 \ No newline at end of file +13813 \ No newline at end of file From 69904d0ac55cc0c83d2bf88c87396408d1d29e29 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Fri, 18 Sep 2026 05:54:02 +0200 Subject: [PATCH 12/14] golden --- .../golden/hls-test-suite/decoupled/mergesort_decouple2.cycles | 2 +- .../golden/hls-test-suite/decoupled/mergesort_decouple3.cycles | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles index 7dc24cd1f..f9bdd5cbd 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles @@ -1 +1 @@ -13805 \ No newline at end of file +13758 \ No newline at end of file diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles index 8a5316ba7..9e538f3c6 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple3.cycles @@ -1 +1 @@ -13813 \ No newline at end of file +13766 \ No newline at end of file From 83290f591e7016c0654b3abb874036def3e3cc7a Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Fri, 18 Sep 2026 06:14:06 +0200 Subject: [PATCH 13/14] golden --- .../golden/hls-test-suite/decoupled/mergesort_decouple2.cycles | 2 +- .../golden/hls-test-suite/decoupled/mergesort_decouple4.cycles | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles index f9bdd5cbd..7dc24cd1f 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple2.cycles @@ -1 +1 @@ -13758 \ No newline at end of file +13805 \ No newline at end of file diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles index 8a5316ba7..9e538f3c6 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles @@ -1 +1 @@ -13813 \ No newline at end of file +13766 \ No newline at end of file From 80f9327cb100e5d26ac6f66c81eed67500f8c731 Mon Sep 17 00:00:00 2001 From: Nico Reissmann Date: Fri, 18 Sep 2026 06:35:47 +0200 Subject: [PATCH 14/14] golden --- .../golden/hls-test-suite/decoupled/mergesort_decouple4.cycles | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles b/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles index 9e538f3c6..8a5316ba7 100644 --- a/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles +++ b/.github/golden/hls-test-suite/decoupled/mergesort_decouple4.cycles @@ -1 +1 @@ -13766 \ No newline at end of file +13813 \ No newline at end of file