[flang-commits] [flang] [flang] Add debug information for module variables. (PR #91582)
Abid Qadeer via flang-commits
flang-commits at lists.llvm.org
Tue May 21 04:43:58 PDT 2024
https://github.com/abidh updated https://github.com/llvm/llvm-project/pull/91582
>From eecff7b856d257ba2d758500de2121332f06eb0e Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Fri, 26 Apr 2024 16:21:36 +0100
Subject: [PATCH 1/9] [flang] Add initial implementation of module variables.
This PR add supports for module variables and function. The module
variables are added as global variables but their scope is set to
module instead of compile unit. The scope of function declared inside
a module is also set accordingly.
After this patch, a module variable could be evaluated in the GDB as
`p helper::gli` where helper is name of the module and gli is the name
of the variable. A future patch will add the import module functionality
which will remove the need to prefix the name with helper::.
The line number where is module is declared is a best guess at the
moment as this information is not part of the GlobalOp.
---
flang/lib/Optimizer/CodeGen/CodeGen.cpp | 17 +++-
.../lib/Optimizer/Transforms/AddDebugInfo.cpp | 84 ++++++++++++++++++-
flang/test/Transforms/debug-module-1.f90 | 39 +++++++++
flang/test/Transforms/debug-module-2.f90 | 37 ++++++++
4 files changed, 174 insertions(+), 3 deletions(-)
create mode 100644 flang/test/Transforms/debug-module-1.f90
create mode 100644 flang/test/Transforms/debug-module-2.f90
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 72172f63888e1..fb7afcf07713c 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -2716,6 +2716,18 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
mlir::LogicalResult
matchAndRewrite(fir::GlobalOp global, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
+
+ mlir::LLVM::DIGlobalVariableExpressionAttr dbgExpr;
+
+ if (auto fusedLoc = mlir::dyn_cast<mlir::FusedLoc>(global.getLoc())) {
+ if (auto gvAttr =
+ mlir::dyn_cast_or_null<mlir::LLVM::DIGlobalVariableAttr>(
+ fusedLoc.getMetadata())) {
+ dbgExpr = mlir::LLVM::DIGlobalVariableExpressionAttr::get(
+ global.getContext(), gvAttr, mlir::LLVM::DIExpressionAttr());
+ }
+ }
+
auto tyAttr = convertType(global.getType());
if (auto boxType = mlir::dyn_cast<fir::BaseBoxType>(global.getType()))
tyAttr = this->lowerTy().convertBoxTypeAsStruct(boxType);
@@ -2724,8 +2736,11 @@ struct GlobalOpConversion : public fir::FIROpConversion<fir::GlobalOp> {
assert(attributeTypeIsCompatible(global.getContext(), initAttr, tyAttr));
auto linkage = convertLinkage(global.getLinkName());
auto isConst = global.getConstant().has_value();
+ mlir::SymbolRefAttr comdat;
+ llvm::ArrayRef<mlir::NamedAttribute> attrs;
auto g = rewriter.create<mlir::LLVM::GlobalOp>(
- loc, tyAttr, isConst, linkage, global.getSymName(), initAttr);
+ loc, tyAttr, isConst, linkage, global.getSymName(), initAttr, 0, 0,
+ false, false, comdat, attrs, dbgExpr);
auto module = global->getParentOfType<mlir::ModuleOp>();
// Add comdat if necessary
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 07e8aed4cd07b..87cabfbd6324a 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -35,6 +35,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
+#include <map>
namespace fir {
#define GEN_PASS_DEF_ADDDEBUGINFO
@@ -54,6 +55,16 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
public:
AddDebugInfoPass(fir::AddDebugInfoOptions options) : Base(options) {}
void runOnOperation() override;
+
+private:
+ std::map<std::string, mlir::LLVM::DIModuleAttr> moduleMap;
+
+ mlir::LLVM::DIModuleAttr getOrCreateModuleAttr(
+ const std::string &name, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, unsigned line, bool decl);
+
+ void handleGlobalOp(fir::GlobalOp glocalOp, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope);
};
static uint32_t getLineFromLoc(mlir::Location loc) {
@@ -99,6 +110,66 @@ void AddDebugInfoPass::handleDeclareOp(fir::cg::XDeclareOp declOp,
declOp->setLoc(builder.getFusedLoc({declOp->getLoc()}, localVarAttr));
}
+// The `module` does not have a first class representation in the `FIR`. We
+// extract information about it from the name of the identifiers and keep a
+// map to avoid duplication.
+mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
+ const std::string &name, mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope, unsigned line, bool decl) {
+ mlir::MLIRContext *context = &getContext();
+ mlir::LLVM::DIModuleAttr modAttr;
+ if (auto iter{moduleMap.find(name)}; iter != moduleMap.end())
+ modAttr = iter->second;
+ else {
+ modAttr = mlir::LLVM::DIModuleAttr::get(
+ context, fileAttr, scope, mlir::StringAttr::get(context, name),
+ mlir::StringAttr(), mlir::StringAttr(), mlir::StringAttr(), line, decl);
+ moduleMap[name] = modAttr;
+ }
+ return modAttr;
+}
+
+void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
+ mlir::LLVM::DIFileAttr fileAttr,
+ mlir::LLVM::DIScopeAttr scope) {
+ mlir::ModuleOp module = getOperation();
+ mlir::MLIRContext *context = &getContext();
+ fir::DebugTypeGenerator typeGen(module);
+ mlir::OpBuilder builder(context);
+
+ auto result = fir::NameUniquer::deconstruct(globalOp.getSymName());
+ if (result.first != fir::NameUniquer::NameKind::VARIABLE)
+ return;
+
+ unsigned line = getLineFromLoc(globalOp.getLoc());
+
+ // DWARF5 says following about the fortran modules:
+ // A Fortran 90 module may also be represented by a module entry
+ // (but no declaration attribute is warranted because Fortran has no concept
+ // of a corresponding module body).
+ // But in practice, compilers use declaration attribute with a module in cases
+ // where module was defined in another source file (only being used in this
+ // one). The hasInitializationBody() seems to provide the right information
+ // but inverted. It is true where module is actually defined but false where
+ // it is used.
+ // FIXME: Currently we don't have the line number on which a module was
+ // declared. We are using a best guess of line - 1 where line is the source
+ // line of the first member of the module that we encounter.
+
+ if (!result.second.modules.empty())
+ scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
+ line - 1, !globalOp.hasInitializationBody());
+
+ auto diType = typeGen.convertType(globalOp.getType(), fileAttr, scope,
+ globalOp.getLoc());
+ auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
+ context, scope, mlir::StringAttr::get(context, result.second.name),
+ mlir::StringAttr::get(context, globalOp.getName()), fileAttr, line,
+ diType, /*isLocalToUnit*/ false,
+ /*isDefinition*/ globalOp.hasInitializationBody(), /* alignInBits*/ 0);
+ globalOp->setLoc(builder.getFusedLoc({globalOp->getLoc()}, gvAttr));
+}
+
void AddDebugInfoPass::runOnOperation() {
mlir::ModuleOp module = getOperation();
mlir::MLIRContext *context = &getContext();
@@ -138,6 +209,10 @@ void AddDebugInfoPass::runOnOperation() {
llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer,
isOptimized, debugLevel);
+ module.walk([&](fir::GlobalOp globalOp) {
+ handleGlobalOp(globalOp, fileAttr, cuAttr);
+ });
+
module.walk([&](mlir::func::FuncOp funcOp) {
mlir::Location l = funcOp->getLoc();
// If fused location has already been created then nothing to do
@@ -180,6 +255,7 @@ void AddDebugInfoPass::runOnOperation() {
// Only definitions need a distinct identifier and a compilation unit.
mlir::DistinctAttr id;
+ mlir::LLVM::DIScopeAttr Scope = fileAttr;
mlir::LLVM::DICompileUnitAttr compilationUnit;
mlir::LLVM::DISubprogramFlags subprogramFlags =
mlir::LLVM::DISubprogramFlags{};
@@ -192,9 +268,13 @@ void AddDebugInfoPass::runOnOperation() {
subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
}
unsigned line = getLineFromLoc(l);
+ if (!result.second.modules.empty())
+ Scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, cuAttr,
+ line - 1, false);
+
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
- context, id, compilationUnit, fileAttr, funcName, fullName,
- funcFileAttr, line, line, subprogramFlags, subTypeAttr);
+ context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
+ line, line, subprogramFlags, subTypeAttr);
funcOp->setLoc(builder.getFusedLoc({funcOp->getLoc()}, spAttr));
// Don't process variables if user asked for line tables only.
diff --git a/flang/test/Transforms/debug-module-1.f90 b/flang/test/Transforms/debug-module-1.f90
new file mode 100644
index 0000000000000..2321c7093f422
--- /dev/null
+++ b/flang/test/Transforms/debug-module-1.f90
@@ -0,0 +1,39 @@
+! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \
+! RUN: fir-opt --cg-rewrite --mlir-print-debuginfo | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
+
+! CHECK-DAG: #[[I4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
+! CHECK-DAG: #[[R4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
+! CHECK-DAG: #[[FILE:.*]] = #llvm.di_file<"debug-module-1.f90" {{.*}}>
+! CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<{{.*}}, file = #[[FILE]], {{.*}}>
+! CHECK-DAG: #[[MOD:.*]] = #llvm.di_module<file = #[[FILE]], scope = #[[CU]], name = "helper", {{.*}}>
+module helper
+! CHECK-DAG: #[[LOC1:.*]] = loc("{{.*}}debug-module-1.f90":[[@LINE+2]]{{.*}})
+! CHECK-DAG: #[[GLR:.*]] = #llvm.di_global_variable<scope = #[[MOD]], name = "glr", linkageName = "_QMhelperEglr", file = #[[FILE]], line = [[@LINE+1]], type = #[[R4]], isDefined = true>
+ real glr
+! CHECK-DAG: #[[LOC2:.*]] = loc("{{.*}}debug-module-1.f90":[[@LINE+2]]{{.*}})
+! CHECK-DAG: #[[GLI:.*]] = #llvm.di_global_variable<scope = #[[MOD]], name = "gli", linkageName = "_QMhelperEgli", file = #[[FILE]], line = [[@LINE+1]], type = #[[I4]], isDefined = true>
+ integer gli
+
+ contains
+! CHECK-DAG: #[[LOC3:.*]] = loc("{{.*}}debug-module-1.f90":[[@LINE+2]]{{.*}})
+! CHECK-DAG: #[[TEST:.*]] = #llvm.di_subprogram<{{.*}}compileUnit = #[[CU]], scope = #[[MOD]], name = "test", linkageName = "_QMhelperPtest", file = #[[FILE]], line = [[@LINE+1]], scopeLine = [[@LINE+1]]{{.*}}>
+ subroutine test()
+ glr = 12.34
+ gli = 67
+
+ end subroutine
+end module helper
+
+program test
+use helper
+implicit none
+
+ glr = 3.14
+ gli = 2
+ call test()
+
+end program test
+
+! CHECK-DAG: loc(fused<#[[GLR]]>[#[[LOC1]]])
+! CHECK-DAG: loc(fused<#[[GLI]]>[#[[LOC2]]])
+! CHECK-DAG: loc(fused<#[[TEST]]>[#[[LOC3]]])
\ No newline at end of file
diff --git a/flang/test/Transforms/debug-module-2.f90 b/flang/test/Transforms/debug-module-2.f90
new file mode 100644
index 0000000000000..9f6bba3ef0470
--- /dev/null
+++ b/flang/test/Transforms/debug-module-2.f90
@@ -0,0 +1,37 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+
+! CHECK-DAG: ![[FILE:.*]] = !DIFile(filename: {{.*}}debug-module-2.f90{{.*}})
+! CHECK-DAG: ![[FILE2:.*]] = !DIFile(filename: {{.*}}debug-module-2.f90{{.*}})
+! CHECK-DAG: ![[CU:.*]] = distinct !DICompileUnit({{.*}}file: ![[FILE]]{{.*}} globals: ![[GLOBALS:.*]])
+! CHECK-DAG: ![[MOD:.*]] = !DIModule(scope: ![[CU]], name: "helper", file: ![[FILE]]{{.*}})
+! CHECK-DAG: ![[R4:.*]] = !DIBasicType(name: "real", size: 32, encoding: DW_ATE_float)
+! CHECK-DAG: ![[I4:.*]] = !DIBasicType(name: "integer", size: 32, encoding: DW_ATE_signed)
+module helper
+! CHECK-DAG: ![[GLR:.*]] = distinct !DIGlobalVariable(name: "glr", linkageName: "_QMhelperEglr", scope: ![[MOD]], file: ![[FILE]], line: [[@LINE+2]], type: ![[R4]], isLocal: false, isDefinition: true)
+! CHECK-DAG: ![[GLRX:.*]] = !DIGlobalVariableExpression(var: ![[GLR]], expr: !DIExpression())
+ real glr
+
+! CHECK-DAG: ![[GLI:.*]] = distinct !DIGlobalVariable(name: "gli", linkageName: "_QMhelperEgli", scope: ![[MOD]], file: ![[FILE]], line: [[@LINE+2]], type: ![[I4]], isLocal: false, isDefinition: true)
+! CHECK-DAG: ![[GLIX:.*]] = !DIGlobalVariableExpression(var: ![[GLI]], expr: !DIExpression())
+ integer gli
+
+ contains
+!CHECK-DAG: !DISubprogram(name: "test", linkageName: "_QMhelperPtest", scope: ![[MOD]], file: ![[FILE2]], line: [[@LINE+1]]{{.*}}unit: ![[CU]])
+ subroutine test()
+ glr = 12.34
+ gli = 67
+
+ end subroutine
+end module helper
+
+program test
+use helper
+implicit none
+
+ glr = 3.14
+ gli = 2
+ call test()
+
+end program test
+
+! CHECK-DAG: ![[GLOBALS]] = !{![[GLIX]], ![[GLRX]]}
>From e87df98ea5c71fd221209d8f440e0bea456835fc Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 15 May 2024 11:39:46 +0100
Subject: [PATCH 2/9] Handled review comments.
Following changes were done.
1. Remove MLIR changes as they have been moved to separate PR.
2. Replace std::map with llvm::StringMap
3. Use a direct for loop instead of module.walk.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 87cabfbd6324a..d807d74b2ed86 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -57,7 +57,7 @@ class AddDebugInfoPass : public fir::impl::AddDebugInfoBase<AddDebugInfoPass> {
void runOnOperation() override;
private:
- std::map<std::string, mlir::LLVM::DIModuleAttr> moduleMap;
+ llvm::StringMap<mlir::LLVM::DIModuleAttr> moduleMap;
mlir::LLVM::DIModuleAttr getOrCreateModuleAttr(
const std::string &name, mlir::LLVM::DIFileAttr fileAttr,
@@ -119,7 +119,7 @@ mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
mlir::MLIRContext *context = &getContext();
mlir::LLVM::DIModuleAttr modAttr;
if (auto iter{moduleMap.find(name)}; iter != moduleMap.end())
- modAttr = iter->second;
+ modAttr = iter->getValue();
else {
modAttr = mlir::LLVM::DIModuleAttr::get(
context, fileAttr, scope, mlir::StringAttr::get(context, name),
@@ -209,9 +209,8 @@ void AddDebugInfoPass::runOnOperation() {
llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer,
isOptimized, debugLevel);
- module.walk([&](fir::GlobalOp globalOp) {
+ for (auto globalOp : module.getOps<fir::GlobalOp>())
handleGlobalOp(globalOp, fileAttr, cuAttr);
- });
module.walk([&](mlir::func::FuncOp funcOp) {
mlir::Location l = funcOp->getLoc();
>From be8a2ba065f753ade70bfabc8dd9d260f5d18495 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 15 May 2024 13:02:24 +0100
Subject: [PATCH 3/9] Remove a redundant include file.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index d807d74b2ed86..d89302abb14d1 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -35,7 +35,6 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
-#include <map>
namespace fir {
#define GEN_PASS_DEF_ADDDEBUGINFO
>From e90d49a0424dbc2b6f1577bfc1bca2af12ec3acb Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 15 May 2024 17:56:30 +0100
Subject: [PATCH 4/9] Addressed review comments.
1. Skip variables if module list is empty.
2. Add a missing line at the end of a file.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 8 +++++---
flang/test/Transforms/debug-module-1.f90 | 2 +-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index d89302abb14d1..8a9a772023c53 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -155,9 +155,11 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
// declared. We are using a best guess of line - 1 where line is the source
// line of the first member of the module that we encounter.
- if (!result.second.modules.empty())
- scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
- line - 1, !globalOp.hasInitializationBody());
+ if (result.second.modules.empty())
+ return;
+
+ scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
+ line - 1, !globalOp.hasInitializationBody());
auto diType = typeGen.convertType(globalOp.getType(), fileAttr, scope,
globalOp.getLoc());
diff --git a/flang/test/Transforms/debug-module-1.f90 b/flang/test/Transforms/debug-module-1.f90
index 2321c7093f422..b53d5b1e5b5bc 100644
--- a/flang/test/Transforms/debug-module-1.f90
+++ b/flang/test/Transforms/debug-module-1.f90
@@ -36,4 +36,4 @@ end program test
! CHECK-DAG: loc(fused<#[[GLR]]>[#[[LOC1]]])
! CHECK-DAG: loc(fused<#[[GLI]]>[#[[LOC2]]])
-! CHECK-DAG: loc(fused<#[[TEST]]>[#[[LOC3]]])
\ No newline at end of file
+! CHECK-DAG: loc(fused<#[[TEST]]>[#[[LOC3]]])
>From e837cabf841dfb15b1e8bcdf8a5e3944e1c37e1f Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Thu, 16 May 2024 10:10:57 +0100
Subject: [PATCH 5/9] Process variable only if full debug info is requested.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 7 +++++--
flang/test/Transforms/debug-module-2.f90 | 2 ++
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 8a9a772023c53..4be8b2717c69b 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -210,8 +210,11 @@ void AddDebugInfoPass::runOnOperation() {
llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer,
isOptimized, debugLevel);
- for (auto globalOp : module.getOps<fir::GlobalOp>())
- handleGlobalOp(globalOp, fileAttr, cuAttr);
+ if (debugLevel == mlir::LLVM::DIEmissionKind::Full) {
+ // Process 'GlobalOp' only if full debug info is requested.
+ for (auto globalOp : module.getOps<fir::GlobalOp>())
+ handleGlobalOp(globalOp, fileAttr, cuAttr);
+ }
module.walk([&](mlir::func::FuncOp funcOp) {
mlir::Location l = funcOp->getLoc();
diff --git a/flang/test/Transforms/debug-module-2.f90 b/flang/test/Transforms/debug-module-2.f90
index 9f6bba3ef0470..60fccaa2a6c1f 100644
--- a/flang/test/Transforms/debug-module-2.f90
+++ b/flang/test/Transforms/debug-module-2.f90
@@ -1,4 +1,5 @@
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=line-tables-only %s -o - | FileCheck --check-prefix=LINEONLY %s
! CHECK-DAG: ![[FILE:.*]] = !DIFile(filename: {{.*}}debug-module-2.f90{{.*}})
! CHECK-DAG: ![[FILE2:.*]] = !DIFile(filename: {{.*}}debug-module-2.f90{{.*}})
@@ -35,3 +36,4 @@ program test
end program test
! CHECK-DAG: ![[GLOBALS]] = !{![[GLIX]], ![[GLRX]]}
+! LINEONLY-NOT: DIGlobalVariable
>From 94aecb0d592cbb00789dcbb5bd7905494cefe1d6 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Thu, 16 May 2024 10:48:33 +0100
Subject: [PATCH 6/9] Replace 'hasInitializationBody' with 'isInitialized'.
This address one of the review comments.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 4be8b2717c69b..fec7ae553e2cf 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -148,7 +148,7 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
// of a corresponding module body).
// But in practice, compilers use declaration attribute with a module in cases
// where module was defined in another source file (only being used in this
- // one). The hasInitializationBody() seems to provide the right information
+ // one). The isInitialized() seems to provide the right information
// but inverted. It is true where module is actually defined but false where
// it is used.
// FIXME: Currently we don't have the line number on which a module was
@@ -159,7 +159,7 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
return;
scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
- line - 1, !globalOp.hasInitializationBody());
+ line - 1, !globalOp.isInitialized());
auto diType = typeGen.convertType(globalOp.getType(), fileAttr, scope,
globalOp.getLoc());
@@ -167,7 +167,7 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
context, scope, mlir::StringAttr::get(context, result.second.name),
mlir::StringAttr::get(context, globalOp.getName()), fileAttr, line,
diType, /*isLocalToUnit*/ false,
- /*isDefinition*/ globalOp.hasInitializationBody(), /* alignInBits*/ 0);
+ /*isDefinition*/ globalOp.isInitialized(), /* alignInBits*/ 0);
globalOp->setLoc(builder.getFusedLoc({globalOp->getLoc()}, gvAttr));
}
>From 3487f18d4f7526bf1630ce968b4a9e1fe524cd9e Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Mon, 20 May 2024 10:41:41 +0100
Subject: [PATCH 7/9] Handle review comments.
Fixed nits and move IR tests to Integration folder.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 11 ++++++-----
.../{Transforms => Integration}/debug-module-2.f90 | 0
2 files changed, 6 insertions(+), 5 deletions(-)
rename flang/test/{Transforms => Integration}/debug-module-2.f90 (100%)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index fec7ae553e2cf..cf1bbda40cf9e 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -117,12 +117,13 @@ mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
mlir::LLVM::DIScopeAttr scope, unsigned line, bool decl) {
mlir::MLIRContext *context = &getContext();
mlir::LLVM::DIModuleAttr modAttr;
- if (auto iter{moduleMap.find(name)}; iter != moduleMap.end())
+ if (auto iter{moduleMap.find(name)}; iter != moduleMap.end()) {
modAttr = iter->getValue();
- else {
+ } else {
modAttr = mlir::LLVM::DIModuleAttr::get(
context, fileAttr, scope, mlir::StringAttr::get(context, name),
- mlir::StringAttr(), mlir::StringAttr(), mlir::StringAttr(), line, decl);
+ /* configMacros */ mlir::StringAttr(), /* includePath */mlir::StringAttr(),
+ /* apinotes */ mlir::StringAttr(), line, decl);
moduleMap[name] = modAttr;
}
return modAttr;
@@ -136,7 +137,7 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
fir::DebugTypeGenerator typeGen(module);
mlir::OpBuilder builder(context);
- auto result = fir::NameUniquer::deconstruct(globalOp.getSymName());
+ std::pair result = fir::NameUniquer::deconstruct(globalOp.getSymName());
if (result.first != fir::NameUniquer::NameKind::VARIABLE)
return;
@@ -161,7 +162,7 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
line - 1, !globalOp.isInitialized());
- auto diType = typeGen.convertType(globalOp.getType(), fileAttr, scope,
+ mlir::LLVM::DITypeAttr diType = typeGen.convertType(globalOp.getType(), fileAttr, scope,
globalOp.getLoc());
auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
context, scope, mlir::StringAttr::get(context, result.second.name),
diff --git a/flang/test/Transforms/debug-module-2.f90 b/flang/test/Integration/debug-module-2.f90
similarity index 100%
rename from flang/test/Transforms/debug-module-2.f90
rename to flang/test/Integration/debug-module-2.f90
>From 5d5c73cad421bdca6e43e1cc10704ff160f1a33e Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Mon, 20 May 2024 11:01:58 +0100
Subject: [PATCH 8/9] Fix clang-format issues.
---
flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index cf1bbda40cf9e..fb7c0bf0d1f97 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -122,7 +122,8 @@ mlir::LLVM::DIModuleAttr AddDebugInfoPass::getOrCreateModuleAttr(
} else {
modAttr = mlir::LLVM::DIModuleAttr::get(
context, fileAttr, scope, mlir::StringAttr::get(context, name),
- /* configMacros */ mlir::StringAttr(), /* includePath */mlir::StringAttr(),
+ /* configMacros */ mlir::StringAttr(),
+ /* includePath */ mlir::StringAttr(),
/* apinotes */ mlir::StringAttr(), line, decl);
moduleMap[name] = modAttr;
}
@@ -162,8 +163,8 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, scope,
line - 1, !globalOp.isInitialized());
- mlir::LLVM::DITypeAttr diType = typeGen.convertType(globalOp.getType(), fileAttr, scope,
- globalOp.getLoc());
+ mlir::LLVM::DITypeAttr diType = typeGen.convertType(
+ globalOp.getType(), fileAttr, scope, globalOp.getLoc());
auto gvAttr = mlir::LLVM::DIGlobalVariableAttr::get(
context, scope, mlir::StringAttr::get(context, result.second.name),
mlir::StringAttr::get(context, globalOp.getName()), fileAttr, line,
>From c5091267bde53d6351f05524cc598d1a146c88fd Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Tue, 21 May 2024 12:25:07 +0100
Subject: [PATCH 9/9] Handle review comments.
Add test files that work on fir and test individual passes. Remove the
fortran testcase.
---
flang/test/Transforms/debug-module-1.f90 | 39 -----------------------
flang/test/Transforms/debug-module-1.fir | 40 ++++++++++++++++++++++++
flang/test/Transforms/debug-module-2.fir | 35 +++++++++++++++++++++
3 files changed, 75 insertions(+), 39 deletions(-)
delete mode 100644 flang/test/Transforms/debug-module-1.f90
create mode 100644 flang/test/Transforms/debug-module-1.fir
create mode 100644 flang/test/Transforms/debug-module-2.fir
diff --git a/flang/test/Transforms/debug-module-1.f90 b/flang/test/Transforms/debug-module-1.f90
deleted file mode 100644
index b53d5b1e5b5bc..0000000000000
--- a/flang/test/Transforms/debug-module-1.f90
+++ /dev/null
@@ -1,39 +0,0 @@
-! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | \
-! RUN: fir-opt --cg-rewrite --mlir-print-debuginfo | fir-opt --add-debug-info --mlir-print-debuginfo | FileCheck %s
-
-! CHECK-DAG: #[[I4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
-! CHECK-DAG: #[[R4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
-! CHECK-DAG: #[[FILE:.*]] = #llvm.di_file<"debug-module-1.f90" {{.*}}>
-! CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<{{.*}}, file = #[[FILE]], {{.*}}>
-! CHECK-DAG: #[[MOD:.*]] = #llvm.di_module<file = #[[FILE]], scope = #[[CU]], name = "helper", {{.*}}>
-module helper
-! CHECK-DAG: #[[LOC1:.*]] = loc("{{.*}}debug-module-1.f90":[[@LINE+2]]{{.*}})
-! CHECK-DAG: #[[GLR:.*]] = #llvm.di_global_variable<scope = #[[MOD]], name = "glr", linkageName = "_QMhelperEglr", file = #[[FILE]], line = [[@LINE+1]], type = #[[R4]], isDefined = true>
- real glr
-! CHECK-DAG: #[[LOC2:.*]] = loc("{{.*}}debug-module-1.f90":[[@LINE+2]]{{.*}})
-! CHECK-DAG: #[[GLI:.*]] = #llvm.di_global_variable<scope = #[[MOD]], name = "gli", linkageName = "_QMhelperEgli", file = #[[FILE]], line = [[@LINE+1]], type = #[[I4]], isDefined = true>
- integer gli
-
- contains
-! CHECK-DAG: #[[LOC3:.*]] = loc("{{.*}}debug-module-1.f90":[[@LINE+2]]{{.*}})
-! CHECK-DAG: #[[TEST:.*]] = #llvm.di_subprogram<{{.*}}compileUnit = #[[CU]], scope = #[[MOD]], name = "test", linkageName = "_QMhelperPtest", file = #[[FILE]], line = [[@LINE+1]], scopeLine = [[@LINE+1]]{{.*}}>
- subroutine test()
- glr = 12.34
- gli = 67
-
- end subroutine
-end module helper
-
-program test
-use helper
-implicit none
-
- glr = 3.14
- gli = 2
- call test()
-
-end program test
-
-! CHECK-DAG: loc(fused<#[[GLR]]>[#[[LOC1]]])
-! CHECK-DAG: loc(fused<#[[GLI]]>[#[[LOC2]]])
-! CHECK-DAG: loc(fused<#[[TEST]]>[#[[LOC3]]])
diff --git a/flang/test/Transforms/debug-module-1.fir b/flang/test/Transforms/debug-module-1.fir
new file mode 100644
index 0000000000000..822ae01b99aa7
--- /dev/null
+++ b/flang/test/Transforms/debug-module-1.fir
@@ -0,0 +1,40 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+
+module attributes {} {
+ fir.global @_QMhelperEgli : i32 {
+ %0 = fir.zero_bits i32
+ fir.has_value %0 : i32
+ } loc(#loc1)
+ fir.global @_QMhelperEglr : f32 {
+ %0 = fir.zero_bits f32
+ fir.has_value %0 : f32
+ } loc(#loc2)
+ func.func @_QMhelperPtest() {
+ %c67_i32 = arith.constant 67 : i32
+ %cst = arith.constant 1.234000e+01 : f32
+ %0 = fir.address_of(@_QMhelperEgli) : !fir.ref<i32>
+ %1 = fir.address_of(@_QMhelperEglr) : !fir.ref<f32>
+ fir.store %cst to %1 : !fir.ref<f32>
+ fir.store %c67_i32 to %0 : !fir.ref<i32>
+ return
+ } loc(#loc3)
+}
+#loc1 = loc("test.f90":12:11)
+#loc2 = loc("test.f90":15:8)
+#loc3 = loc("test.f90":20:5)
+
+// CHECK-DAG: #[[I4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
+// CHECK-DAG: #[[R4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
+// CHECK-DAG: #[[CU:.*]] = #llvm.di_compile_unit<{{.*}}>
+// CHECK-DAG: #[[MOD:.*]] = #llvm.di_module<{{.*}}scope = #[[CU]], name = "helper"{{.*}}>
+// CHECK-DAG: #[[LOC1:.*]] = loc("{{.*}}test.f90":12{{.*}})
+// CHECK-DAG: #[[GLI:.*]] = #llvm.di_global_variable<scope = #[[MOD]], name = "gli", linkageName = "_QMhelperEgli"{{.*}}line = 12, type = #[[I4]], isDefined = true>
+// CHECK-DAG: #[[LOC2:.*]] = loc("{{.*}}test.f90":15{{.*}})
+// CHECK-DAG: #[[GLR:.*]] = #llvm.di_global_variable<scope = #[[MOD]], name = "glr", linkageName = "_QMhelperEglr"{{.*}}line = 15, type = #[[R4]], isDefined = true>
+// CHECK-DAG: #[[LOC3:.*]] = loc("{{.*}}test.f90":20{{.*}})
+// CHECK-DAG: #[[TEST:.*]] = #llvm.di_subprogram<{{.*}}compileUnit = #[[CU]], scope = #[[MOD]], name = "test", linkageName = "_QMhelperPtest"{{.*}}line = 20, scopeLine = 20{{.*}}>
+// CHECK-DAG: loc(fused<#[[GLI]]>[#[[LOC1]]])
+// CHECK-DAG: loc(fused<#[[GLR]]>[#[[LOC2]]])
+// CHECK-DAG: loc(fused<#[[TEST]]>[#[[LOC3]]])
+
diff --git a/flang/test/Transforms/debug-module-2.fir b/flang/test/Transforms/debug-module-2.fir
new file mode 100644
index 0000000000000..6acdc1df23d27
--- /dev/null
+++ b/flang/test/Transforms/debug-module-2.fir
@@ -0,0 +1,35 @@
+// RUN: fir-opt --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" --mlir-print-debuginfo %s | FileCheck %s
+
+module {
+ fir.global @_QMhelperEgli : i32 {
+ %0 = fir.zero_bits i32
+ fir.has_value %0 : i32
+ } loc(#loc3)
+ fir.global @_QMhelperEglr : f32 {
+ %0 = fir.zero_bits f32
+ fir.has_value %0 : f32
+ } loc(#loc4)
+}
+#di_basic_type = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
+#di_basic_type1 = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
+
+#di_file = #llvm.di_file<"test.f90" in "">
+#di_subroutine_type = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
+
+#di_compile_unit = #llvm.di_compile_unit<id = distinct[0]<>, sourceLanguage = DW_LANG_Fortran95, file = #di_file, producer = "flang version 19.0.0 (/home/haqadeer/work/llvm-project/flang 5d5c73cad421bdca6e43e1cc10704ff160f1a33e)", isOptimized = false, emissionKind = Full>
+#di_module = #llvm.di_module<file = #di_file, scope = #di_compile_unit, name = "helper", line = 11>
+#di_global_variable = #llvm.di_global_variable<scope = #di_module, name = "gli", linkageName = "_QMhelperEgli", file = #di_file, line = 12, type = #di_basic_type, isDefined = true>
+#di_global_variable1 = #llvm.di_global_variable<scope = #di_module, name = "glr", linkageName = "_QMhelperEglr", file = #di_file, line = 15, type = #di_basic_type1, isDefined = true>
+
+#loc1 = loc("test.f90":12:11)
+#loc2 = loc("test.f90":15:8)
+#loc3 = loc(fused<#di_global_variable>[#loc1])
+#loc4 = loc(fused<#di_global_variable1>[#loc2])
+
+
+// CHECK-DAG: #[[GLI:.*]] = #llvm.di_global_variable<{{.*}}name = "gli", linkageName = "_QMhelperEgli"{{.*}}>
+// CHECK-DAG: #[[GLR:.*]] = #llvm.di_global_variable<{{.*}}name = "glr", linkageName = "_QMhelperEglr"{{.*}}>
+// CHECK-DAG: #[[GLIE:.*]] = #llvm.di_global_variable_expression<var = #[[GLI]]>
+// CHECK-DAG: #[[GLRE:.*]] = #llvm.di_global_variable_expression<var = #[[GLR]]>
+// CHECK-DAG: llvm.mlir.global{{.*}}@_QMhelperEgli() {{{.*}}dbg_expr = #[[GLIE]]}
+// CHECK-DAG: llvm.mlir.global{{.*}}@_QMhelperEglr() {{{.*}}dbg_expr = #[[GLRE]]}
More information about the flang-commits
mailing list