[flang-commits] [flang] Reapply "[flang] Improve debug info for functions." with regression fixed. (PR #90484)

Abid Qadeer via flang-commits flang-commits at lists.llvm.org
Mon Apr 29 08:30:11 PDT 2024


https://github.com/abidh created https://github.com/llvm/llvm-project/pull/90484

The original PR #90083 had to be reverted in PR #90444 as it caused one of the gfortran tests to fail. The issue was using `isIntOrIndex` for checking for integer type. It allowed index type which later caused assertion when calling `getIntOrFloatBitWidth`. I have now replaced it with `isInteger` which should fix this regression.

>From 5fc74208f5c17b915c770aaacf920c94d322da9a Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Wed, 24 Apr 2024 15:26:10 +0100
Subject: [PATCH 1/3] [flang] Improve debug info for functions.

This PR improves the debug information for functions in the following
way:

1. Remove hardcoded line numbers.
2. Use proper type for function signature. I have a added a type
convertor. It currently is very limited but will be enhanced with time.
3. Use de-constructed function name so that user see the same name as
was in the source.
---
 .../lib/Optimizer/Transforms/AddDebugInfo.cpp | 36 ++++++++---
 flang/lib/Optimizer/Transforms/CMakeLists.txt |  1 +
 .../Transforms/DebugTypeGenerator.cpp         | 63 +++++++++++++++++++
 .../Optimizer/Transforms/DebugTypeGenerator.h | 40 ++++++++++++
 flang/test/Transforms/debug-fn-info.f90       | 43 +++++++++++++
 .../Transforms/debug-line-table-inc-file.fir  |  2 +-
 6 files changed, 174 insertions(+), 11 deletions(-)
 create mode 100644 flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
 create mode 100644 flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
 create mode 100644 flang/test/Transforms/debug-fn-info.f90

diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 68584bef055b61..5a023db7dd59af 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -11,6 +11,7 @@
 /// This pass populates some debug information for the module and functions.
 //===----------------------------------------------------------------------===//
 
+#include "DebugTypeGenerator.h"
 #include "flang/Common/Version.h"
 #include "flang/Optimizer/Builder/FIRBuilder.h"
 #include "flang/Optimizer/Builder/Todo.h"
@@ -106,14 +107,27 @@ void AddDebugInfoPass::runOnOperation() {
       filePath = llvm::sys::path::parent_path(funcLoc.getFilename().getValue());
     }
 
-    mlir::StringAttr funcName =
+    mlir::StringAttr fullName =
         mlir::StringAttr::get(context, funcOp.getName());
-    mlir::LLVM::DIBasicTypeAttr bT = mlir::LLVM::DIBasicTypeAttr::get(
-        context, llvm::dwarf::DW_TAG_base_type, "void", /*sizeInBits=*/0,
-        /*encoding=*/1);
-    // FIXME: Provide proper type for subroutine
+    auto result = fir::NameUniquer::deconstruct(funcOp.getName());
+    mlir::StringAttr funcName =
+        mlir::StringAttr::get(context, result.second.name);
+
+    llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
+    fir::DebugTypeGenerator typeGen(module);
+    for (auto resTy : funcOp.getResultTypes()) {
+      auto tyAttr = typeGen.convertType(fir::unwrapRefType(resTy), fileAttr,
+                                        cuAttr, funcOp.getLoc());
+      types.push_back(tyAttr);
+    }
+    for (auto inTy : funcOp.getArgumentTypes()) {
+      auto tyAttr = typeGen.convertType(fir::unwrapRefType(inTy), fileAttr,
+                                        cuAttr, funcOp.getLoc());
+      types.push_back(tyAttr);
+    }
+
     mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
-        mlir::LLVM::DISubroutineTypeAttr::get(context, CC, {bT, bT});
+        mlir::LLVM::DISubroutineTypeAttr::get(context, CC, types);
     mlir::LLVM::DIFileAttr funcFileAttr =
         mlir::LLVM::DIFileAttr::get(context, fileName, filePath);
 
@@ -130,11 +144,13 @@ void AddDebugInfoPass::runOnOperation() {
       subprogramFlags =
           subprogramFlags | mlir::LLVM::DISubprogramFlags::Definition;
     }
-    // FIXME: Provide proper line and scopeline.
+    unsigned line = 1;
+    if (auto funcLoc = l.dyn_cast<mlir::FileLineColLoc>())
+      line = funcLoc.getLine();
+
     auto spAttr = mlir::LLVM::DISubprogramAttr::get(
-        context, id, compilationUnit, fileAttr, funcName, funcName,
-        funcFileAttr, /*line=*/1, /*scopeline=*/1, subprogramFlags,
-        subTypeAttr);
+        context, id, compilationUnit, fileAttr, funcName, fullName,
+        funcFileAttr, line, line, subprogramFlags, subTypeAttr);
     funcOp->setLoc(builder.getFusedLoc({funcOp->getLoc()}, spAttr));
   });
 }
diff --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index fc08d67540ceb0..5a542f237f8f98 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -22,6 +22,7 @@ add_flang_library(FIRTransforms
   OMPMarkDeclareTarget.cpp
   VScaleAttr.cpp
   FunctionAttr.cpp
+  DebugTypeGenerator.cpp
 
   DEPENDS
   FIRDialect
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
new file mode 100644
index 00000000000000..0057e08f8a763b
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -0,0 +1,63 @@
+//===-- DebugTypeGenerator.cpp -- type conversion ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "flang-debug-type-generator"
+
+#include "DebugTypeGenerator.h"
+#include "llvm/ADT/ScopeExit.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/Support/Debug.h"
+
+namespace fir {
+
+DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
+    : module(m), kindMapping(getKindMapping(m)) {
+  LLVM_DEBUG(llvm::dbgs() << "DITypeAttr generator\n");
+}
+
+static mlir::LLVM::DITypeAttr genPlaceholderType(mlir::MLIRContext *context) {
+  return mlir::LLVM::DIBasicTypeAttr::get(
+      context, llvm::dwarf::DW_TAG_base_type, "void", 32, 1);
+}
+
+static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
+                                           mlir::StringAttr name,
+                                           unsigned bitSize,
+                                           unsigned decoding) {
+  return mlir::LLVM::DIBasicTypeAttr::get(
+      context, llvm::dwarf::DW_TAG_base_type, name, bitSize, decoding);
+}
+
+mlir::LLVM::DITypeAttr
+DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
+                                mlir::LLVM::DIScopeAttr scope,
+                                mlir::Location loc) {
+  mlir::MLIRContext *context = module.getContext();
+  if (Ty.isIntOrIndex()) {
+    return genBasicType(context, mlir::StringAttr::get(context, "integer"),
+                        Ty.getIntOrFloatBitWidth(), llvm::dwarf::DW_ATE_signed);
+  } else if (Ty.isa<mlir::FloatType>() || Ty.isa<fir::RealType>()) {
+    return genBasicType(context, mlir::StringAttr::get(context, "real"),
+                        Ty.getIntOrFloatBitWidth(), llvm::dwarf::DW_ATE_float);
+  } else if (auto logTy = Ty.dyn_cast_or_null<fir::LogicalType>()) {
+    return genBasicType(context,
+                        mlir::StringAttr::get(context, logTy.getMnemonic()),
+                        kindMapping.getLogicalBitsize(logTy.getFKind()),
+                        llvm::dwarf::DW_ATE_boolean);
+  } else {
+    // FIXME: These types are currently unhandled. We are generating a
+    // placeholder type to allow us to test supported bits.
+    return genPlaceholderType(context);
+  }
+}
+
+} // namespace fir
diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
new file mode 100644
index 00000000000000..5a2bb201db47a3
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h
@@ -0,0 +1,40 @@
+//===-- DebugTypeGenerator.h -- type conversion ------------------- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
+#define FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
+
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/Support/FIRContext.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
+#include "llvm/Support/Debug.h"
+
+namespace fir {
+
+/// This converts FIR/mlir type to DITypeAttr.
+class DebugTypeGenerator {
+public:
+  DebugTypeGenerator(mlir::ModuleOp module);
+
+  mlir::LLVM::DITypeAttr convertType(mlir::Type Ty,
+                                     mlir::LLVM::DIFileAttr fileAttr,
+                                     mlir::LLVM::DIScopeAttr scope,
+                                     mlir::Location loc);
+
+private:
+  mlir::ModuleOp module;
+  KindMapping kindMapping;
+};
+
+} // namespace fir
+
+#endif // FORTRAN_OPTIMIZER_TRANSFORMS_DEBUGTYPEGENERATOR_H
diff --git a/flang/test/Transforms/debug-fn-info.f90 b/flang/test/Transforms/debug-fn-info.f90
new file mode 100644
index 00000000000000..c1a817312c959c
--- /dev/null
+++ b/flang/test/Transforms/debug-fn-info.f90
@@ -0,0 +1,43 @@
+! RUN: %flang_fc1 -emit-fir -debug-info-kind=standalone -mmlir --mlir-print-debuginfo %s -o - | fir-opt --add-debug-info --mlir-print-debuginfo  | FileCheck %s
+
+
+! CHECK-DAG: #[[INT8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 64, encoding = DW_ATE_signed>
+! CHECK-DAG: #[[INT4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer", sizeInBits = 32, encoding = DW_ATE_signed>
+! CHECK-DAG: #[[REAL8:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 64, encoding = DW_ATE_float>
+! CHECK-DAG: #[[LOG1:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 8, encoding = DW_ATE_boolean>
+! CHECK-DAG: #[[REAL4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real", sizeInBits = 32, encoding = DW_ATE_float>
+! CHECK-DAG: #[[LOG4:.*]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "logical", sizeInBits = 32, encoding = DW_ATE_boolean>
+! CHECK: #[[TY1:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[INT8]], #[[INT4]], #[[REAL8]], #[[LOG1]]>
+! CHECK: #[[TY2:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[INT4]], #[[INT8]], #[[REAL4]], #[[LOG4]]>
+
+program mn
+  integer(kind=4) :: i4
+  integer(kind=8) :: i8
+  real(kind=4) :: r4
+  real(kind=8) :: r8
+  logical(kind=1) :: l1
+  logical(kind=4) :: l4
+  i8 = fn1(i4, r8, l1)
+  i4 = fn2(i8, r4, l4)
+contains
+  ! CHECK: #di_subprogram1 = #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "fn1", linkageName = "_QFPfn1", file = {{.*}}, line = [[@LINE+1]], scopeLine = [[@LINE+1]], subprogramFlags = Definition, type = #[[TY1]]>
+  function fn1(a, b, c) result (res)
+    implicit none
+    integer(kind=4), intent(in) :: a
+    real(kind=8), intent(in) :: b
+    logical(kind=1), intent(in) :: c
+    integer(kind=8) :: res
+    res = a + b
+  end function
+
+! CHECK: #di_subprogram2 = #llvm.di_subprogram<id = {{.*}}, compileUnit = {{.*}}, scope = {{.*}}, name = "fn2", linkageName = "_QFPfn2", file = {{.*}}, line = [[@LINE+1]], scopeLine = [[@LINE+1]], subprogramFlags = Definition, type = #[[TY2]]>
+  function fn2(a, b, c) result (res)
+    implicit none
+    integer(kind=8), intent(in) :: a
+    real(kind=4), intent(in) :: b
+    logical(kind=4), intent(in) :: c
+    integer(kind=4) :: res
+    res = a + b
+  end function
+end program
+
diff --git a/flang/test/Transforms/debug-line-table-inc-file.fir b/flang/test/Transforms/debug-line-table-inc-file.fir
index dc75482d4f8a7f..d7f60a1a86dbf0 100644
--- a/flang/test/Transforms/debug-line-table-inc-file.fir
+++ b/flang/test/Transforms/debug-line-table-inc-file.fir
@@ -31,7 +31,7 @@ module attributes {} {
 // CHECK: #[[LOC_INC_FILE:.*]] = loc("{{.*}}inc.f90":1:1)
 // CHECK: #[[LOC_FILE:.*]] = loc("{{.*}}simple.f90":3:1)
 // CHECK: #[[DI_CU:.*]] = #llvm.di_compile_unit<id = distinct[{{.*}}]<>, sourceLanguage = DW_LANG_Fortran95, file = #[[DI_FILE]], producer = "flang{{.*}}", isOptimized = false, emissionKind = LineTablesOnly>
-// CHECK: #[[DI_SP_INC:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #[[DI_CU]], scope = #[[DI_FILE]], name = "_QPsinc", linkageName = "_QPsinc", file = #[[DI_INC_FILE]], {{.*}}>
+// CHECK: #[[DI_SP_INC:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #[[DI_CU]], scope = #[[DI_FILE]], name = "sinc", linkageName = "_QPsinc", file = #[[DI_INC_FILE]], {{.*}}>
 // CHECK: #[[DI_SP:.*]] = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #[[DI_CU]], scope = #[[DI_FILE]], name = "_QQmain", linkageName = "_QQmain", file = #[[DI_FILE]], {{.*}}>
 // CHECK: #[[FUSED_LOC_INC_FILE]] = loc(fused<#[[DI_SP_INC]]>[#[[LOC_INC_FILE]]])
 // CHECK: #[[FUSED_LOC_FILE]] = loc(fused<#[[DI_SP]]>[#[[LOC_FILE]]])

>From 04507583ae62e077f9ff86809cfa52a8fad59f2e Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Fri, 26 Apr 2024 17:34:43 +0100
Subject: [PATCH 2/3] Address review comments.

---
 flang/lib/Optimizer/Transforms/AddDebugInfo.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 5a023db7dd59af..c98f18f8b25196 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -116,8 +116,8 @@ void AddDebugInfoPass::runOnOperation() {
     llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
     fir::DebugTypeGenerator typeGen(module);
     for (auto resTy : funcOp.getResultTypes()) {
-      auto tyAttr = typeGen.convertType(fir::unwrapRefType(resTy), fileAttr,
-                                        cuAttr, funcOp.getLoc());
+      auto tyAttr =
+          typeGen.convertType(resTy, fileAttr, cuAttr, funcOp.getLoc());
       types.push_back(tyAttr);
     }
     for (auto inTy : funcOp.getArgumentTypes()) {

>From aeb94e5de5e703e79b2cb90041e99ab62dab8409 Mon Sep 17 00:00:00 2001
From: Abid Qadeer <haqadeer at amd.com>
Date: Mon, 29 Apr 2024 14:57:17 +0100
Subject: [PATCH 3/3] Fix a regression.

The initial PR https://github.com/llvm/llvm-project/pull/90083 was
reverted as it caused the regression in one of the gfortran tests. This
commit fixes this issue by replacing isIntOrIndex with isInteger which
is the right function to check for integer type.
---
 flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
index 0057e08f8a763b..0f4ebf9507b124 100644
--- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
+++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp
@@ -42,7 +42,7 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
                                 mlir::LLVM::DIScopeAttr scope,
                                 mlir::Location loc) {
   mlir::MLIRContext *context = module.getContext();
-  if (Ty.isIntOrIndex()) {
+  if (Ty.isInteger()) {
     return genBasicType(context, mlir::StringAttr::get(context, "integer"),
                         Ty.getIntOrFloatBitWidth(), llvm::dwarf::DW_ATE_signed);
   } else if (Ty.isa<mlir::FloatType>() || Ty.isa<fir::RealType>()) {



More information about the flang-commits mailing list