Add IR debug info support for Elemental, Pure, and Recursive Procedures.

Patch by Eric Schweitz!

Differential Revision: https://reviews.llvm.org/D54043

llvm-svn: 356163
This commit is contained in:
Adrian Prantl 2019-03-14 16:29:54 +00:00
parent 330ab33f7c
commit e69917f166
5 changed files with 57 additions and 3 deletions

View File

@ -670,6 +670,37 @@ a C/C++ front-end would generate the following descriptors:
... ...
} }
Fortran specific debug information
==================================
Fortran function information
----------------------------
There are a few DWARF attributes defined to support client debugging of Fortran programs. LLVM can generate (or omit) the appropriate DWARF attributes for the prefix-specs of ELEMENTAL, PURE, IMPURE, RECURSIVE, and NON_RECURSIVE. This is done by using the spFlags values: DISPFlagElemental, DISPFlagPure, and DISPFlagRecursive.
.. code-block:: fortran
elemental function elem_func(a)
a Fortran front-end would generate the following descriptors:
.. code-block:: text
!11 = distinct !DISubprogram(name: "subroutine2", scope: !1, file: !1,
line: 5, type: !8, scopeLine: 6,
spFlags: DISPFlagDefinition | DISPFlagElemental, unit: !0,
retainedNodes: !2)
and this will materialize an additional DWARF attribute as:
.. code-block:: text
DW_TAG_subprogram [3]
DW_AT_low_pc [DW_FORM_addr] (0x0000000000000010 ".text")
DW_AT_high_pc [DW_FORM_data4] (0x00000001)
...
DW_AT_elemental [DW_FORM_flag_present] (true)
Debugging information format Debugging information format
============================ ============================

View File

@ -85,11 +85,14 @@ HANDLE_DISP_FLAG(2u, PureVirtual)
HANDLE_DISP_FLAG((1u << 2), LocalToUnit) HANDLE_DISP_FLAG((1u << 2), LocalToUnit)
HANDLE_DISP_FLAG((1u << 3), Definition) HANDLE_DISP_FLAG((1u << 3), Definition)
HANDLE_DISP_FLAG((1u << 4), Optimized) HANDLE_DISP_FLAG((1u << 4), Optimized)
HANDLE_DISP_FLAG((1u << 5), Pure)
HANDLE_DISP_FLAG((1u << 6), Elemental)
HANDLE_DISP_FLAG((1u << 7), Recursive)
#ifdef DISP_FLAG_LARGEST_NEEDED #ifdef DISP_FLAG_LARGEST_NEEDED
// Intended to be used with ADT/BitmaskEnum.h. // Intended to be used with ADT/BitmaskEnum.h.
// NOTE: Always must be equal to largest flag, check this when adding new flags. // NOTE: Always must be equal to largest flag, check this when adding new flags.
HANDLE_DISP_FLAG((1 << 4), Largest) HANDLE_DISP_FLAG((1 << 7), Largest)
#undef DISP_FLAG_LARGEST_NEEDED #undef DISP_FLAG_LARGEST_NEEDED
#endif #endif

View File

@ -1801,6 +1801,9 @@ public:
return getFlags() & FlagAllCallsDescribed; return getFlags() & FlagAllCallsDescribed;
} }
bool isMainSubprogram() const { return getFlags() & FlagMainSubprogram; } bool isMainSubprogram() const { return getFlags() & FlagMainSubprogram; }
bool isPure() const { return getSPFlags() & SPFlagPure; }
bool isElemental() const { return getSPFlags() & SPFlagElemental; }
bool isRecursive() const { return getSPFlags() & SPFlagRecursive; }
/// Check if this is reference-qualified. /// Check if this is reference-qualified.
/// ///

View File

@ -1267,6 +1267,12 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
if (SP->isMainSubprogram()) if (SP->isMainSubprogram())
addFlag(SPDie, dwarf::DW_AT_main_subprogram); addFlag(SPDie, dwarf::DW_AT_main_subprogram);
if (SP->isPure())
addFlag(SPDie, dwarf::DW_AT_pure);
if (SP->isElemental())
addFlag(SPDie, dwarf::DW_AT_elemental);
if (SP->isRecursive())
addFlag(SPDie, dwarf::DW_AT_recursive);
} }
void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR, void DwarfUnit::constructSubrangeDIE(DIE &Buffer, const DISubrange *SR,

View File

@ -6,8 +6,8 @@ define void @_Z3foov() !dbg !9 {
ret void ret void
} }
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15} ; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19}
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15} !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !17, !19, !20, !21}
!0 = !{null} !0 = !{null}
!1 = distinct !DICompositeType(tag: DW_TAG_structure_type) !1 = distinct !DICompositeType(tag: DW_TAG_structure_type)
@ -81,3 +81,14 @@ define void @_Z3foov() !dbg !9 {
!16 = !{i32 1, !"Debug Info Version", i32 3} !16 = !{i32 1, !"Debug Info Version", i32 3}
!llvm.module.flags = !{!16} !llvm.module.flags = !{!16}
!llvm.dbg.cu = !{!8} !llvm.dbg.cu = !{!8}
; CHECK: !DISubprogram({{.*}}subroutine1{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure,
; CHECK: !DISubprogram({{.*}}subroutine2{{.*}}, spFlags: DISPFlagDefinition | DISPFlagElemental,
; CHECK: !DISubprogram({{.*}}subroutine3{{.*}}, spFlags: DISPFlagDefinition | DISPFlagRecursive,
; CHECK: !DISubprogram({{.*}}subroutine4{{.*}}, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive,
!17 = distinct !DISubprogram(name: "subroutine1", scope: !1, file: !2, line: 1, type: !18, scopeLine: 2, spFlags: DISPFlagDefinition | DISPFlagPure, unit: !8, retainedNodes: !6)
!18 = !DISubroutineType(types: !0)
!19 = distinct !DISubprogram(name: "subroutine2", scope: !1, file: !2, line: 5, type: !18, scopeLine: 6, spFlags: DISPFlagDefinition | DISPFlagElemental, unit: !8, retainedNodes: !6)
!20 = distinct !DISubprogram(name: "subroutine3", scope: !1, file: !2, line: 9, type: !18, scopeLine: 10, spFlags: DISPFlagDefinition | DISPFlagRecursive, unit: !8, retainedNodes: !6)
!21 = distinct !DISubprogram(name: "subroutine4", scope: !1, file: !2, line: 13, type: !18, scopeLine: 14, spFlags: DISPFlagDefinition | DISPFlagPure | DISPFlagElemental | DISPFlagRecursive, unit: !8, retainedNodes: !6)