[flang-commits] [flang] [flang][debug] Don't build signature types for minimal debug levels. (PR #221967)

via flang-commits flang-commits at lists.llvm.org
Tue Sep 8 04:49:41 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-fir-hlfir

Author: Abid Qadeer (abidh)

<details>
<summary>Changes</summary>

AddDebugInfo converted the result and argument types of every function before it checked the requested debug level, so -gline-tables-only or a -gline-directives-only ended up with the full type graph of each signature: derived types, array types, string types and the basic types they are built from.

Leave the type list empty at those levels which is also what clang emits for -gline-tables-only or -gline-directives-only. The subprogram of an omp.target region gets the same treatment.

A single variable is now used to decide this so parameter for the `addTargetOpDISP` lambda was removed.

Fixes #<!-- -->217343

---
Full diff: https://github.com/llvm/llvm-project/pull/221967.diff


3 Files Affected:

- (modified) flang/lib/Optimizer/Transforms/AddDebugInfo.cpp (+32-24) 
- (added) flang/test/Transforms/debug-line-table-no-types.fir (+31) 
- (modified) flang/test/Transforms/debug-omp-target-op-1.fir (+12-4) 


``````````diff
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 8f1dc8dcfe3f6..c911827b72a7c 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -636,19 +636,26 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
         mlir::StringAttr::get(context, fir::getPresentableFunctionName(funcOp));
   }
 
+  bool lineTableOrDirectivesOnly =
+      debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly ||
+      debugLevel == mlir::LLVM::DIEmissionKind::DebugDirectivesOnly;
+
+  // Dont generate any type at LineTablesOnly and DebugDirectivesOnly level.
   llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
-  for (auto resTy : funcOp.getResultTypes()) {
-    auto tyAttr =
-        typeGen.convertType(resTy, fileAttr, cuAttr, /*declOp=*/nullptr);
-    types.push_back(tyAttr);
-  }
-  // If no return type then add a null type as a place holder for that.
-  if (types.empty())
-    types.push_back(mlir::LLVM::DINullTypeAttr::get(context));
-  for (auto inTy : funcOp.getArgumentTypes()) {
-    auto tyAttr = typeGen.convertType(fir::unwrapRefType(inTy), fileAttr,
-                                      cuAttr, /*declOp=*/nullptr);
-    types.push_back(tyAttr);
+  if (!lineTableOrDirectivesOnly) {
+    for (auto resTy : funcOp.getResultTypes()) {
+      auto tyAttr =
+          typeGen.convertType(resTy, fileAttr, cuAttr, /*declOp=*/nullptr);
+      types.push_back(tyAttr);
+    }
+    // If no return type then add a null type as a place holder for that.
+    if (types.empty())
+      types.push_back(mlir::LLVM::DINullTypeAttr::get(context));
+    for (auto inTy : funcOp.getArgumentTypes()) {
+      auto tyAttr = typeGen.convertType(fir::unwrapRefType(inTy), fileAttr,
+                                        cuAttr, /*declOp=*/nullptr);
+      types.push_back(tyAttr);
+    }
   }
 
   mlir::LLVM::DISubroutineTypeAttr subTypeAttr =
@@ -713,8 +720,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
     Scope = getOrCreateModuleAttr(result.second.modules[0], fileAttr, cuAttr);
   }
 
-  auto addTargetOpDISP = [&](bool lineTableOnly,
-                             llvm::ArrayRef<mlir::Attribute> entities) {
+  auto addTargetOpDISP = [&](llvm::ArrayRef<mlir::Attribute> entities) {
     // When we process the DeclareOp inside the OpenMP target region, all the
     // variables get the DISubprogram of the parent function of the target op as
     // the scope. In the codegen (to llvm ir), OpenMP target op results in the
@@ -741,16 +747,19 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
       mlir::DistinctAttr id =
           mlir::DistinctAttr::create(mlir::UnitAttr::get(context));
       llvm::SmallVector<mlir::LLVM::DITypeAttr> types;
-      types.push_back(mlir::LLVM::DINullTypeAttr::get(context));
-      for (auto arg : targetOp.getRegion().getArguments()) {
-        auto tyAttr = typeGen.convertType(fir::unwrapRefType(arg.getType()),
-                                          fileAttr, cuAttr, /*declOp=*/nullptr);
-        types.push_back(tyAttr);
+      if (!lineTableOrDirectivesOnly) {
+        types.push_back(mlir::LLVM::DINullTypeAttr::get(context));
+        for (auto arg : targetOp.getRegion().getArguments()) {
+          auto tyAttr =
+              typeGen.convertType(fir::unwrapRefType(arg.getType()), fileAttr,
+                                  cuAttr, /*declOp=*/nullptr);
+          types.push_back(tyAttr);
+        }
       }
       CC = llvm::dwarf::getCallingConvention("DW_CC_normal");
       mlir::LLVM::DISubroutineTypeAttr spTy =
           mlir::LLVM::DISubroutineTypeAttr::get(context, CC, types);
-      if (lineTableOnly || entities.empty()) {
+      if (lineTableOrDirectivesOnly || entities.empty()) {
         auto spAttr = mlir::LLVM::DISubprogramAttr::get(
             context, id, compilationUnit, Scope, name, name, funcFileAttr, line,
             line, flags, spTy, /*retainedNodes=*/{}, /*annotations=*/{});
@@ -788,14 +797,13 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
 
   // Don't process variables if user asked for line tables or debug directives
   // only.
-  if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly ||
-      debugLevel == mlir::LLVM::DIEmissionKind::DebugDirectivesOnly) {
+  if (lineTableOrDirectivesOnly) {
     auto spAttr = mlir::LLVM::DISubprogramAttr::get(
         context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
         line, line, subprogramFlags, subTypeAttr, /*retainedNodes=*/{},
         /*annotations=*/{});
     funcOp->setLoc(builder.getFusedLoc({l}, spAttr));
-    addTargetOpDISP(/*lineTableOnly=*/true, /*entities=*/{});
+    addTargetOpDISP(/*entities=*/{});
     return;
   }
 
@@ -849,7 +857,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
         /*annotations=*/{});
 
   funcOp->setLoc(builder.getFusedLoc({l}, spAttr));
-  addTargetOpDISP(/*lineTableOnly=*/false, retainedNodes);
+  addTargetOpDISP(retainedNodes);
 
   // Find the first dummy_scope definition. This is the one of the current
   // function. The other ones may come from inlined calls. The variables inside
diff --git a/flang/test/Transforms/debug-line-table-no-types.fir b/flang/test/Transforms/debug-line-table-no-types.fir
new file mode 100644
index 0000000000000..f5bfd8d56431a
--- /dev/null
+++ b/flang/test/Transforms/debug-line-table-no-types.fir
@@ -0,0 +1,31 @@
+// Test that a compile unit which emits no type information gets an empty
+// DISubroutineType.
+
+// RUN: fir-opt --add-debug-info="debug-level=Full" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=FULL
+// RUN: fir-opt --add-debug-info="debug-level=LineTablesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=MINIMAL
+// RUN: fir-opt --add-debug-info="debug-level=DebugDirectivesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=MINIMAL
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+  func.func @_QPfn(%arg0: !fir.ref<!fir.type<_QFTpoint{x:f32,y:f32}>>, %arg1: !fir.box<!fir.array<?xf32>>, %arg2: !fir.ref<i32>) -> i32 {
+    %0 = fir.undefined i32
+    return %0 : i32
+  } loc(#loc_fn)
+} loc(#loc_module)
+#loc_module = loc("test.f90":1:1)
+#loc_fn = loc("test.f90":5:1)
+
+// At Full the signature drags in a type for the result and for every argument.
+// FULL-DAG: #[[INT4:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "integer(kind=4)", sizeInBits = 32, encoding = DW_ATE_signed>
+// FULL-DAG: #[[REAL4:.+]] = #llvm.di_basic_type<tag = DW_TAG_base_type, name = "real(kind=4)", sizeInBits = 32, encoding = DW_ATE_float>
+// FULL-DAG: #[[POINT:.+]] = #llvm.di_composite_type<{{.*}}tag = DW_TAG_structure_type, name = "point"
+// FULL-DAG: #[[ARRAY:.+]] = #llvm.di_composite_type<tag = DW_TAG_array_type
+// FULL-DAG: #[[SUBTY:.+]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #[[INT4]], #[[POINT]], #[[ARRAY]], #[[INT4]]>
+// FULL-DAG: #llvm.di_subprogram<{{.*}}name = "fn"{{.*}}type = #[[SUBTY]]>
+
+// MINIMAL-NOT: #llvm.di_basic_type
+// MINIMAL-NOT: #llvm.di_composite_type
+// MINIMAL-NOT: #llvm.di_derived_type
+// MINIMAL-NOT: #llvm.di_string_type
+// MINIMAL-NOT: #llvm.di_null_type
+// MINIMAL: #[[SUBTY:.+]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
+// MINIMAL: #llvm.di_subprogram<{{.*}}name = "fn"{{.*}}type = #[[SUBTY]]>
diff --git a/flang/test/Transforms/debug-omp-target-op-1.fir b/flang/test/Transforms/debug-omp-target-op-1.fir
index 0a1222148f75d..6f339b1fa4409 100644
--- a/flang/test/Transforms/debug-omp-target-op-1.fir
+++ b/flang/test/Transforms/debug-omp-target-op-1.fir
@@ -1,5 +1,6 @@
 // RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
-// RUN: fir-opt --add-debug-info="debug-level=LineTablesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=LINETABLE
+// RUN: fir-opt --add-debug-info="debug-level=LineTablesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=MINIMAL
+// RUN: fir-opt --add-debug-info="debug-level=DebugDirectivesOnly" --mlir-print-debuginfo %s | FileCheck %s --check-prefix=MINIMAL
 
 module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
   func.func @_QQmain() attributes {fir.bindc_name = "test"} {
@@ -35,6 +36,13 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
 // CHECK: #llvm.di_local_variable<scope = #[[SP1]], name = "x"{{.*}}line = 7, type = #[[TY]]>
 // CHECK: #llvm.di_local_variable<scope = #[[SP1]], name = "y"{{.*}}line = 8, type = #[[TY]]>
 
-// LINETABLE: #[[SP:.*]] = #llvm.di_subprogram<{{.*}}name = "test"{{.*}}>
-// LINETABLE: #[[SP1:.*]] = #llvm.di_subprogram<{{.*}}name = "__omp_offloading_{{.*}}_QQmain_l6"{{.*}}line = 6{{.*}}subprogramFlags = "LocalToUnit|Definition"{{.*}}>
-// LINETABLE-NOT: #llvm.di_local_variable
+// MINIMAL-NOT: #llvm.di_basic_type
+// MINIMAL-NOT: #llvm.di_composite_type
+// MINIMAL-NOT: #llvm.di_derived_type
+// MINIMAL-NOT: #llvm.di_string_type
+// MINIMAL-NOT: #llvm.di_null_type
+// MINIMAL: #[[SPTY:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_program>
+// MINIMAL: #[[SPTY1:.*]] = #llvm.di_subroutine_type<callingConvention = DW_CC_normal>
+// MINIMAL: #[[SP:.*]] = #llvm.di_subprogram<{{.*}}name = "test"{{.*}}type = #[[SPTY]]>
+// MINIMAL: #[[SP1:.*]] = #llvm.di_subprogram<{{.*}}name = "__omp_offloading_{{.*}}_QQmain_l6"{{.*}}line = 6{{.*}}subprogramFlags = "LocalToUnit|Definition", type = #[[SPTY1]]>
+// MINIMAL-NOT: #llvm.di_local_variable

``````````

</details>


https://github.com/llvm/llvm-project/pull/221967


More information about the flang-commits mailing list