-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Reapply "[flang] Improve debug info for functions." with regression fixed. #90484
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
The initial PR llvm#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.
@llvm/pr-subscribers-flang-fir-hlfir Author: Abid Qadeer (abidh) ChangesThe original PR #90083 had to be reverted in PR #90444 as it caused one of the gfortran tests to fail. The issue was using Full diff: https://github.com/llvm/llvm-project/pull/90484.diff 6 Files Affected:
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 68584bef055b61..c98f18f8b25196 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(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..0f4ebf9507b124
--- /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.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>()) {
+ 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]]])
|
I don't have the expertise to review this seriously. If no one else has any strong opinions landing it and seeing what the bots think is also fine with me. You will get emails this time, I've fixed the other issues that prevented that the first time around. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG
@abidh My local build started to see some failures like
Is it something related to this PR? |
No that is #90413, but I see you already figured that out :) |
With this small test program:
this patch is causing
Please repair or revert this change post haste, it is blocking development for me and others at Nvidia. |
I will upload a quick fix for review shortly. @abidh you may consider using FIR TypeConverter at least for some FIR types to "reduce" the types space to some limited number of LLVM types, for which you can get the bitwidth. |
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 callinggetIntOrFloatBitWidth
. I have now replaced it withisInteger
which should fix this regression.