-
Notifications
You must be signed in to change notification settings - Fork 14.3k
Two fixes for DISubrangeType #130345
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
Two fixes for DISubrangeType #130345
Conversation
My previous patch to add DISubrangeType (llvm#126772) had a couple of minor errors. This patch corrects them. 1. When using a DISubrangeType as an array index type, the wrong tag was written into the DIE. 2. I'd intended for subranges to use bit strides, not byte strides -- but neglected to actually implement this. Ada needs bit strides. This patch adds a new test that checks both these things. Finally, this patch adds some documentation for DISubrangeType.
@llvm/pr-subscribers-debuginfo Author: Tom Tromey (tromey) ChangesMy previous patch to add DISubrangeType (#126772) had a couple of minor errors. This patch corrects them.
This patch adds a new test that checks both these things. Finally, this patch adds some documentation for DISubrangeType. Full diff: https://github.com/llvm/llvm-project/pull/130345.diff 3 Files Affected:
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 8f80344b854ee..b0de05da2fd1f 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -6319,21 +6319,24 @@ The following ``tag:`` values are valid:
DW_TAG_union_type = 23
For ``DW_TAG_array_type``, the ``elements:`` should be :ref:`subrange
-descriptors <DISubrange>`, each representing the range of subscripts at that
-level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates that an
-array type is a native packed vector. The optional ``dataLocation`` is a
-DIExpression that describes how to get from an object's address to the actual
-raw data, if they aren't equivalent. This is only supported for array types,
-particularly to describe Fortran arrays, which have an array descriptor in
-addition to the array data. Alternatively it can also be DIVariable which
-has the address of the actual raw data. The Fortran language supports pointer
-arrays which can be attached to actual arrays, this attachment between pointer
-and pointee is called association. The optional ``associated`` is a
-DIExpression that describes whether the pointer array is currently associated.
-The optional ``allocated`` is a DIExpression that describes whether the
-allocatable array is currently allocated. The optional ``rank`` is a
-DIExpression that describes the rank (number of dimensions) of fortran assumed
-rank array (rank is known at runtime).
+descriptors <DISubrange>` or :ref:`subrange descriptors
+<DISubrangeType>`, each representing the range of subscripts at that
+level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates
+that an array type is a native packed vector. The optional
+``dataLocation`` is a DIExpression that describes how to get from an
+object's address to the actual raw data, if they aren't
+equivalent. This is only supported for array types, particularly to
+describe Fortran arrays, which have an array descriptor in addition to
+the array data. Alternatively it can also be DIVariable which has the
+address of the actual raw data. The Fortran language supports pointer
+arrays which can be attached to actual arrays, this attachment between
+pointer and pointee is called association. The optional
+``associated`` is a DIExpression that describes whether the pointer
+array is currently associated. The optional ``allocated`` is a
+DIExpression that describes whether the allocatable array is currently
+allocated. The optional ``rank`` is a DIExpression that describes the
+rank (number of dimensions) of fortran assumed rank array (rank is
+known at runtime).
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
descriptors <DIEnumerator>`, each representing the definition of an enumeration
@@ -6378,6 +6381,50 @@ DISubrange
!12 = !DIGlobalVariable(name: "count", scope: !8, file: !6, line: 22, type: !9)
!13 = !DISubrange(count: !12, lowerBound: 0)
+.. _DISubrangeType:
+
+DISubrangeType
+""""""""""""""
+
+``DISubrangeType`` is similar to ``DISubrange``, but it is also a
+``DIType``. It may be used as the type of an object, but could also
+be used as an array index.
+
+Like ``DISubrange``, it can hold a lower bound and count, or a lower
+bound and upper bound. A ``DISubrangeType`` refers to the underlying
+type of which it is a subrange; this type can be an integer type or an
+enumeration type.
+
+A ``DISubrangeType`` may also have a stride -- unlike ``DISubrange``,
+this stride is a bit stride. The stride is only useful when a
+``DISubrangeType`` is used as an array index type.
+
+Finally, ``DISubrangeType`` may have a bias. In Ada, a program can
+request that a subrange value be stored in the minimum number of bits
+required. In this situation, the stored value is biased by the lower
+bound -- e.g., a range ``-7 .. 0`` may take 3 bits in memory, and the
+value -5 would be stored as 2 (a bias of -7).
+
+.. code-block:: text
+
+ ; Scopes used in rest of example
+ !0 = !DIFile(filename: "vla.c", directory: "/path/to/file")
+ !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !0)
+ !2 = distinct !DISubprogram(name: "foo", scope: !1, file: !0, line: 5)
+
+ ; Base type used in example.
+ !3 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+
+ ; A simple subrange with a name.
+ !4 = !DISubrange(name: "subrange", file: !0, line: 17, size: 32,
+ align: 32, baseType: !3, lowerBound: 18, count: 12)
+ ; A subrange with a bias.
+ !5 = !DISubrange(name: "biased", lowerBound: -7, upperBound: 0,
+ bias: -7, size: 3)
+ ; A subrange with a bit stride.
+ !6 = !DISubrange(name: "biased", lowerBound: 0, upperBound: 7,
+ stride: 3)
+
.. _DIEnumerator:
DIEnumerator
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index b77ecf1372405..383fbfb3fbd2b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1478,7 +1478,7 @@ void DwarfUnit::constructSubrangeDIE(DIE &DW_Subrange, const DISubrangeType *SR,
AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());
- AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());
+ AddBoundTypeEntry(dwarf::DW_AT_bit_stride, SR->getStride());
AddBoundTypeEntry(dwarf::DW_AT_GNU_bias, SR->getBias());
}
@@ -1670,7 +1670,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
DINodeArray Elements = CTy->getElements();
for (DINode *E : Elements) {
if (auto *Element = dyn_cast_or_null<DISubrangeType>(E)) {
- DIE &TyDIE = createAndAddDIE(CTy->getTag(), Buffer, CTy);
+ DIE &TyDIE = createAndAddDIE(Element->getTag(), Buffer, CTy);
constructSubrangeDIE(TyDIE, Element, true);
} else if (auto *Element = dyn_cast_or_null<DISubrange>(E))
constructSubrangeDIE(Buffer, Element);
diff --git a/llvm/test/DebugInfo/Generic/subrange_type.ll b/llvm/test/DebugInfo/Generic/subrange_type.ll
new file mode 100644
index 0000000000000..28fd70eab5d72
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/subrange_type.ll
@@ -0,0 +1,39 @@
+;; Check output of DISubrangeType.
+
+; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info - | FileCheck %s
+
+; CHECK: DW_TAG_array_type
+; CHECK-TYPE: DW_AT_type{{.*}}"unsigned int"
+; CHECK-NOT: NULL
+; CHECK: DW_TAG_subrange_type
+; CHECK-NOT: NULL
+; CHECK: DW_AT_lower_bound (-7)
+; CHECK-NEXT: DW_AT_upper_bound (0)
+; CHECK-NEXT: DW_AT_bit_stride (6)
+
+; ModuleID = 'subrange_type.ll'
+source_filename = "/dir/subrange_type.adb"
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{i32 2, !"Dwarf Version", i32 4}
+!2 = distinct !DICompileUnit(language: DW_LANG_Ada95, file: !3, producer: "GNAT/LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4)
+!3 = !DIFile(filename: "subrange_type.adb", directory: "/dir")
+!4 = !{}
+!5 = !{!29}
+!6 = distinct !DISubprogram(name: "sr", scope: !3, file: !3, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9)
+!7 = !DISubroutineType(types: !8)
+!8 = !{null}
+!9 = !{!10}
+!10 = !DILocalVariable(name: "x", scope: !6, file: !3, line: 3, type: !31, align: 32)
+!11 = !DISubrangeType(name: "sr__int_range", file: !3, line: 2, size: 32, align: 32, baseType: !12, lowerBound: i64 -7, upperBound: i64 0, stride: 6)
+!12 = !DIBasicType(name: "sr__Tint_rangeB", size: 32, encoding: DW_ATE_signed)
+!13 = !DILocation(line: 3, column: 4, scope: !6)
+!14 = !DILocation(line: 6, column: 5, scope: !6)
+
+
+!29 = !DICompositeType(tag: DW_TAG_array_type, size: 64, align: 32, file: !3, scope: !6, baseType: !31, elements: !32)
+!31 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned)
+!32 = !{!11}
|
@llvm/pr-subscribers-llvm-ir Author: Tom Tromey (tromey) ChangesMy previous patch to add DISubrangeType (#126772) had a couple of minor errors. This patch corrects them.
This patch adds a new test that checks both these things. Finally, this patch adds some documentation for DISubrangeType. Full diff: https://github.com/llvm/llvm-project/pull/130345.diff 3 Files Affected:
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 8f80344b854ee..b0de05da2fd1f 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -6319,21 +6319,24 @@ The following ``tag:`` values are valid:
DW_TAG_union_type = 23
For ``DW_TAG_array_type``, the ``elements:`` should be :ref:`subrange
-descriptors <DISubrange>`, each representing the range of subscripts at that
-level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates that an
-array type is a native packed vector. The optional ``dataLocation`` is a
-DIExpression that describes how to get from an object's address to the actual
-raw data, if they aren't equivalent. This is only supported for array types,
-particularly to describe Fortran arrays, which have an array descriptor in
-addition to the array data. Alternatively it can also be DIVariable which
-has the address of the actual raw data. The Fortran language supports pointer
-arrays which can be attached to actual arrays, this attachment between pointer
-and pointee is called association. The optional ``associated`` is a
-DIExpression that describes whether the pointer array is currently associated.
-The optional ``allocated`` is a DIExpression that describes whether the
-allocatable array is currently allocated. The optional ``rank`` is a
-DIExpression that describes the rank (number of dimensions) of fortran assumed
-rank array (rank is known at runtime).
+descriptors <DISubrange>` or :ref:`subrange descriptors
+<DISubrangeType>`, each representing the range of subscripts at that
+level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates
+that an array type is a native packed vector. The optional
+``dataLocation`` is a DIExpression that describes how to get from an
+object's address to the actual raw data, if they aren't
+equivalent. This is only supported for array types, particularly to
+describe Fortran arrays, which have an array descriptor in addition to
+the array data. Alternatively it can also be DIVariable which has the
+address of the actual raw data. The Fortran language supports pointer
+arrays which can be attached to actual arrays, this attachment between
+pointer and pointee is called association. The optional
+``associated`` is a DIExpression that describes whether the pointer
+array is currently associated. The optional ``allocated`` is a
+DIExpression that describes whether the allocatable array is currently
+allocated. The optional ``rank`` is a DIExpression that describes the
+rank (number of dimensions) of fortran assumed rank array (rank is
+known at runtime).
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
descriptors <DIEnumerator>`, each representing the definition of an enumeration
@@ -6378,6 +6381,50 @@ DISubrange
!12 = !DIGlobalVariable(name: "count", scope: !8, file: !6, line: 22, type: !9)
!13 = !DISubrange(count: !12, lowerBound: 0)
+.. _DISubrangeType:
+
+DISubrangeType
+""""""""""""""
+
+``DISubrangeType`` is similar to ``DISubrange``, but it is also a
+``DIType``. It may be used as the type of an object, but could also
+be used as an array index.
+
+Like ``DISubrange``, it can hold a lower bound and count, or a lower
+bound and upper bound. A ``DISubrangeType`` refers to the underlying
+type of which it is a subrange; this type can be an integer type or an
+enumeration type.
+
+A ``DISubrangeType`` may also have a stride -- unlike ``DISubrange``,
+this stride is a bit stride. The stride is only useful when a
+``DISubrangeType`` is used as an array index type.
+
+Finally, ``DISubrangeType`` may have a bias. In Ada, a program can
+request that a subrange value be stored in the minimum number of bits
+required. In this situation, the stored value is biased by the lower
+bound -- e.g., a range ``-7 .. 0`` may take 3 bits in memory, and the
+value -5 would be stored as 2 (a bias of -7).
+
+.. code-block:: text
+
+ ; Scopes used in rest of example
+ !0 = !DIFile(filename: "vla.c", directory: "/path/to/file")
+ !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !0)
+ !2 = distinct !DISubprogram(name: "foo", scope: !1, file: !0, line: 5)
+
+ ; Base type used in example.
+ !3 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+
+ ; A simple subrange with a name.
+ !4 = !DISubrange(name: "subrange", file: !0, line: 17, size: 32,
+ align: 32, baseType: !3, lowerBound: 18, count: 12)
+ ; A subrange with a bias.
+ !5 = !DISubrange(name: "biased", lowerBound: -7, upperBound: 0,
+ bias: -7, size: 3)
+ ; A subrange with a bit stride.
+ !6 = !DISubrange(name: "biased", lowerBound: 0, upperBound: 7,
+ stride: 3)
+
.. _DIEnumerator:
DIEnumerator
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index b77ecf1372405..383fbfb3fbd2b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1478,7 +1478,7 @@ void DwarfUnit::constructSubrangeDIE(DIE &DW_Subrange, const DISubrangeType *SR,
AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());
- AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());
+ AddBoundTypeEntry(dwarf::DW_AT_bit_stride, SR->getStride());
AddBoundTypeEntry(dwarf::DW_AT_GNU_bias, SR->getBias());
}
@@ -1670,7 +1670,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
DINodeArray Elements = CTy->getElements();
for (DINode *E : Elements) {
if (auto *Element = dyn_cast_or_null<DISubrangeType>(E)) {
- DIE &TyDIE = createAndAddDIE(CTy->getTag(), Buffer, CTy);
+ DIE &TyDIE = createAndAddDIE(Element->getTag(), Buffer, CTy);
constructSubrangeDIE(TyDIE, Element, true);
} else if (auto *Element = dyn_cast_or_null<DISubrange>(E))
constructSubrangeDIE(Buffer, Element);
diff --git a/llvm/test/DebugInfo/Generic/subrange_type.ll b/llvm/test/DebugInfo/Generic/subrange_type.ll
new file mode 100644
index 0000000000000..28fd70eab5d72
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/subrange_type.ll
@@ -0,0 +1,39 @@
+;; Check output of DISubrangeType.
+
+; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info - | FileCheck %s
+
+; CHECK: DW_TAG_array_type
+; CHECK-TYPE: DW_AT_type{{.*}}"unsigned int"
+; CHECK-NOT: NULL
+; CHECK: DW_TAG_subrange_type
+; CHECK-NOT: NULL
+; CHECK: DW_AT_lower_bound (-7)
+; CHECK-NEXT: DW_AT_upper_bound (0)
+; CHECK-NEXT: DW_AT_bit_stride (6)
+
+; ModuleID = 'subrange_type.ll'
+source_filename = "/dir/subrange_type.adb"
+
+!llvm.module.flags = !{!0, !1}
+!llvm.dbg.cu = !{!2}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !{i32 2, !"Dwarf Version", i32 4}
+!2 = distinct !DICompileUnit(language: DW_LANG_Ada95, file: !3, producer: "GNAT/LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4)
+!3 = !DIFile(filename: "subrange_type.adb", directory: "/dir")
+!4 = !{}
+!5 = !{!29}
+!6 = distinct !DISubprogram(name: "sr", scope: !3, file: !3, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9)
+!7 = !DISubroutineType(types: !8)
+!8 = !{null}
+!9 = !{!10}
+!10 = !DILocalVariable(name: "x", scope: !6, file: !3, line: 3, type: !31, align: 32)
+!11 = !DISubrangeType(name: "sr__int_range", file: !3, line: 2, size: 32, align: 32, baseType: !12, lowerBound: i64 -7, upperBound: i64 0, stride: 6)
+!12 = !DIBasicType(name: "sr__Tint_rangeB", size: 32, encoding: DW_ATE_signed)
+!13 = !DILocation(line: 3, column: 4, scope: !6)
+!14 = !DILocation(line: 6, column: 5, scope: !6)
+
+
+!29 = !DICompositeType(tag: DW_TAG_array_type, size: 64, align: 32, file: !3, scope: !6, baseType: !31, elements: !32)
+!31 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned)
+!32 = !{!11}
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/54/builds/7107 Here is the relevant piece of the build log for the reference
|
My previous patch to add DISubrangeType (#126772) had a couple of minor errors. This patch corrects them.
When using a DISubrangeType as an array index type, the wrong tag was written into the DIE.
I'd intended for subranges to use bit strides, not byte strides -- but neglected to actually implement this. Ada needs bit strides.
This patch adds a new test that checks both these things.
Finally, this patch adds some documentation for DISubrangeType.