Skip to content
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

[flang][debug] Don't generate debug for compiler-generated variables #112423

Merged
merged 4 commits into from
Oct 21, 2024

Conversation

abidh
Copy link
Contributor

@abidh abidh commented Oct 15, 2024

Flang generates many globals to handle derived types. There was a check in debug info to filter them based on the information that their names start with a period. This changed since PR#104859 where 'X' is being used instead of '.'.

This PR fixes this issue by also adding 'X' in that list. As user variables gets lower cased by the NameUniquer, there is no risk that those will be filtered out. I added a test for that to be sure.

…bles.

Flang generates many globals to handle derived types. There was a check
in debug info to filter them based on the information that their names
start with '.'. This changed since PR#104859 where 'X' is being used
instead of '.'.

This PR fixes this issue by also adding 'X' in that list. As user
variables gets lower cased by the NameUniquer, there is no risk that
those will be filtered out. I added a test for that to be sure.
@abidh abidh requested review from jeanPerier and vzakhari October 15, 2024 19:41
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Oct 15, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 15, 2024

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

Author: Abid Qadeer (abidh)

Changes

Flang generates many globals to handle derived types. There was a check in debug info to filter them based on the information that their names start with a period. This changed since PR#104859 where 'X' is being used instead of '.'.

This PR fixes this issue by also adding 'X' in that list. As user variables gets lower cased by the NameUniquer, there is no risk that those will be filtered out. I added a test for that to be sure.


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

4 Files Affected:

  • (modified) flang/lib/Optimizer/Transforms/AddDebugInfo.cpp (+7-4)
  • (added) flang/test/Integration/debug-extra-global.f90 (+14)
  • (modified) flang/test/Transforms/debug-derived-type-1.fir (+5-5)
  • (added) flang/test/Transforms/debug-extra-global.fir (+18)
diff --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 400a8648dd7e07..f31c86cf678635 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -211,10 +211,13 @@ void AddDebugInfoPass::handleGlobalOp(fir::GlobalOp globalOp,
   if (result.first != fir::NameUniquer::NameKind::VARIABLE)
     return;
 
-  // Discard entries that describe a derived type. Usually start with '.c.',
-  // '.dt.' or '.n.'. It would be better if result of the deconstruct had a flag
-  // for such values so that we dont have to look at string values.
-  if (!result.second.name.empty() && result.second.name[0] == '.')
+  // Discard entries that describe a derived type. They start with either '.' or
+  // 'X'. We filter both of them out. Note that NameUniquer makes the name lower
+  // case so user variables should be safe. It would be better if result of the
+  // deconstruct had a flag for such values so that we dont have to look at
+  // string values.
+  if (!result.second.name.empty() &&
+      (result.second.name[0] == '.' || result.second.name[0] == 'X'))
     return;
 
   unsigned line = getLineFromLoc(globalOp.getLoc());
diff --git a/flang/test/Integration/debug-extra-global.f90 b/flang/test/Integration/debug-extra-global.f90
new file mode 100644
index 00000000000000..c0ad2e306386da
--- /dev/null
+++ b/flang/test/Integration/debug-extra-global.f90
@@ -0,0 +1,14 @@
+! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck  %s
+
+program test
+ type t1
+   integer :: XcX
+   integer :: xdtx
+ end type
+  type(t1) :: var
+  var%XcX = 2
+  var%xdtx = 3
+end
+
+! Test that there is no debug info for compiler generated globals.
+! CHECK-NOT: DIGlobalVariable
diff --git a/flang/test/Transforms/debug-derived-type-1.fir b/flang/test/Transforms/debug-derived-type-1.fir
index cfbd361a91e726..b1c6076c9c212a 100644
--- a/flang/test/Transforms/debug-derived-type-1.fir
+++ b/flang/test/Transforms/debug-derived-type-1.fir
@@ -8,15 +8,15 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr<272>, d
     %0 = fir.zero_bits !fir.type<_QMm_employeeTt_employee{t_person:!fir.type<_QMm_employeeTt_person{t_address:!fir.type<_QMm_employeeTt_address{house_number:i32}>,name:!fir.char<1,20>}>,hired_date:!fir.type<_QMm_employeeTt_date{year:i32,month:i32,day:i32}>,monthly_salary:f32}>
     fir.has_value %0 : !fir.type<_QMm_employeeTt_employee{t_person:!fir.type<_QMm_employeeTt_person{t_address:!fir.type<_QMm_employeeTt_address{house_number:i32}>,name:!fir.char<1,20>}>,hired_date:!fir.type<_QMm_employeeTt_date{year:i32,month:i32,day:i32}>,monthly_salary:f32}>
   } loc(#loc5)
-  fir.global @_QMt1Evar : !fir.type<_QMt1Tt_t1{age:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}> {
-    %0 = fir.zero_bits !fir.type<_QMt1Tt_t1{age:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}>
-    fir.has_value %0 : !fir.type<_QMt1Tt_t1{age:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}>
+  fir.global @_QMt1Evar : !fir.type<_QMt1Tt_t1{XcX:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}> {
+    %0 = fir.zero_bits !fir.type<_QMt1Tt_t1{XcX:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}>
+    fir.has_value %0 : !fir.type<_QMt1Tt_t1{XcX:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}>
   } loc(#loc6)
   fir.global @_QMtest_1Exyz : !fir.type<_QMtest_1Tsometype{m_array:!fir.array<3xi32>,m_vt1:!fir.box<!fir.heap<!fir.type<_QMtest_1Tt1{name:!fir.char<1,20>,height:f32}>>>,v2:i32,m_alloc:!fir.box<!fir.heap<!fir.array<?xi32>>>,v3:i32,m_first:!fir.box<!fir.heap<!fir.char<1,?>>>,v4:i32,m_p1:!fir.box<!fir.ptr<i32>>,v5:i32,m_p2:!fir.box<!fir.ptr<i32>>,v6:i32,m_p3:!fir.box<!fir.ptr<!fir.array<?xi32>>>,v7:i32}> {
     %0 = fir.zero_bits !fir.type<_QMtest_1Tsometype{m_array:!fir.array<3xi32>,m_vt1:!fir.box<!fir.heap<!fir.type<_QMtest_1Tt1{name:!fir.char<1,20>,height:f32}>>>,v2:i32,m_alloc:!fir.box<!fir.heap<!fir.array<?xi32>>>,v3:i32,m_first:!fir.box<!fir.heap<!fir.char<1,?>>>,v4:i32,m_p1:!fir.box<!fir.ptr<i32>>,v5:i32,m_p2:!fir.box<!fir.ptr<i32>>,v6:i32,m_p3:!fir.box<!fir.ptr<!fir.array<?xi32>>>,v7:i32}>
     fir.has_value %0 : !fir.type<_QMtest_1Tsometype{m_array:!fir.array<3xi32>,m_vt1:!fir.box<!fir.heap<!fir.type<_QMtest_1Tt1{name:!fir.char<1,20>,height:f32}>>>,v2:i32,m_alloc:!fir.box<!fir.heap<!fir.array<?xi32>>>,v3:i32,m_first:!fir.box<!fir.heap<!fir.char<1,?>>>,v4:i32,m_p1:!fir.box<!fir.ptr<i32>>,v5:i32,m_p2:!fir.box<!fir.ptr<i32>>,v6:i32,m_p3:!fir.box<!fir.ptr<!fir.array<?xi32>>>,v7:i32}>
   } loc(#loc12)
-  fir.type_info @_QMt1Tt_t1 noinit nodestroy nofinal : !fir.type<_QMt1Tt_t1{age:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}> loc(#loc7)
+  fir.type_info @_QMt1Tt_t1 noinit nodestroy nofinal : !fir.type<_QMt1Tt_t1{XcX:i32,points:!fir.array<3xcomplex<f32>>,cond:!fir.logical<1>,name:!fir.char<1,20>,ratio:f64}> loc(#loc7)
   fir.type_info @_QMm_employeeTt_address noinit nodestroy nofinal : !fir.type<_QMm_employeeTt_address{house_number:i32}> loc(#loc1)
   fir.type_info @_QMm_employeeTt_person noinit nodestroy nofinal extends !fir.type<_QMm_employeeTt_address{house_number:i32}> : !fir.type<_QMm_employeeTt_person{t_address:!fir.type<_QMm_employeeTt_address{house_number:i32}>,name:!fir.char<1,20>}> loc(#loc2)
   fir.type_info @_QMm_employeeTt_date noinit nodestroy nofinal : !fir.type<_QMm_employeeTt_date{year:i32,month:i32,day:i32}> loc(#loc3)
@@ -68,7 +68,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr<272>, d
 // CHECK-DAG: #[[ELME3:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "monthly_salary", baseType = #[[REAL4_TY]], sizeInBits = 32, alignInBits = 32, offsetInBits = 288>
 // CHECK-DAG: #[[EMP:.*]] = #llvm.di_composite_type<{{.*}}tag = DW_TAG_structure_type, name = "t_employee"{{.*}}line = 46, scope = #[[MOD]], sizeInBits = 320, elements = #[[ELME1]], #[[ELME2]], #[[ELME3]]>
 
-// CHECK-DAG: #[[ELM1:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "age", baseType = #[[INT_TY]], sizeInBits = 32, alignInBits = 32>
+// CHECK-DAG: #[[ELM1:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "XcX", baseType = #[[INT_TY]], sizeInBits = 32, alignInBits = 32>
 // CHECK-DAG: #[[ELM2:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "points", baseType = #[[CMX_ARR]], sizeInBits = 192, alignInBits = 32, offsetInBits = 32>
 // CHECK-DAG: #[[ELM3:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "cond", baseType = #[[LOG_TY]], sizeInBits = 8, alignInBits = 8, offsetInBits = 224>
 // CHECK-DAG: #[[ELM4:.*]] = #llvm.di_derived_type<tag = DW_TAG_member, name = "name", baseType = #[[STR_TY]], sizeInBits = 160, alignInBits = 8, offsetInBits = 232>
diff --git a/flang/test/Transforms/debug-extra-global.fir b/flang/test/Transforms/debug-extra-global.fir
new file mode 100644
index 00000000000000..d3bc22ad0c59b0
--- /dev/null
+++ b/flang/test/Transforms/debug-extra-global.fir
@@ -0,0 +1,18 @@
+// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
+
+module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
+  fir.global linkonce_odr @_QFEXnXxcx constant target : !fir.char<1,3> {
+    %0 = fir.string_lit "xcx"(3) : !fir.char<1,3>
+    fir.has_value %0 : !fir.char<1,3>
+  } loc(#loc1)
+  fir.global linkonce_odr @_QFEXnXxdtx constant target : !fir.char<1,4> {
+    %0 = fir.string_lit "xdtx"(4) : !fir.char<1,4>
+    fir.has_value %0 : !fir.char<1,4>
+  } loc(#loc1)
+}
+#loc1 = loc("derived.f90":24:1)
+
+// Test that no di_global_variable gets created for these compile generated
+// globals.
+
+// CHECK-NOT: #di_global_variable

abidh added 2 commits October 15, 2024 21:30
Test now check a global variable while previously I checked a derived class member.
Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit inlined, LGTM otherwise.

// deconstruct had a flag for such values so that we dont have to look at
// string values.
if (!result.second.name.empty() &&
(result.second.name[0] == '.' || result.second.name[0] == 'X'))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move the result.second.name[0] == '.' || result.second.name[0] == 'X' part into some static fir::NameUniquer::isSpecialSymbol(llvm::StringRef name) helper in Optimizer/Support/InternalNames so that the usages of these delimiters are better centralized and advertise.

Long term, it may be better to have some compiler generated flag attributes on the global/declare for such variables (and others) rather than relying on the names.
In semantics, these variables are tagged with the CompilerCreated symbol attribute, but it is currently not represented in FIR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. I have moved the code into a separate function.

end

! Test that global starting with 'X' don't get filtered.
CHECK: !DIGlobalVariable(name: "xcx", linkageName: "_QMmExcx"{{.*}})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CHECK: !DIGlobalVariable(name: "xcx", linkageName: "_QMmExcx"{{.*}})
! CHECK: !DIGlobalVariable(name: "xcx", linkageName: "_QMmExcx"{{.*}})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching this. Fixed.

Added isSpecialSymbol to check for symbols which don't require debug info.
Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update

@abidh abidh merged commit 95b4128 into llvm:main Oct 21, 2024
8 checks passed
EricWF pushed a commit to efcs/llvm-project that referenced this pull request Oct 22, 2024
…lvm#112423)

Flang generates many globals to handle derived types. There was a check
in debug info to filter them based on the information that their names
start with a period. This changed since PR#104859 where 'X' is being
used instead of '.'.

This PR fixes this issue by also adding 'X' in that list. As user
variables gets lower cased by the NameUniquer, there is no risk that
those will be filtered out. I added a test for that to be sure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:fir-hlfir flang Flang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants