Skip to content

Commit

Permalink
Add IR debug info support for Elemental, Pure, and Recursive Procedures.
Browse files Browse the repository at this point in the history
Patch by Eric Schweitz!

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

llvm-svn: 356163
  • Loading branch information
adrian-prantl committed Mar 14, 2019
1 parent 330ab33 commit e69917f
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 3 deletions.
31 changes: 31 additions & 0 deletions llvm/docs/SourceLevelDebugging.rst
Expand Up @@ -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
============================

Expand Down
5 changes: 4 additions & 1 deletion llvm/include/llvm/IR/DebugInfoFlags.def
Expand Up @@ -85,11 +85,14 @@ HANDLE_DISP_FLAG(2u, PureVirtual)
HANDLE_DISP_FLAG((1u << 2), LocalToUnit)
HANDLE_DISP_FLAG((1u << 3), Definition)
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
// Intended to be used with ADT/BitmaskEnum.h.
// 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
#endif

Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/IR/DebugInfoMetadata.h
Expand Up @@ -1801,6 +1801,9 @@ class DISubprogram : public DILocalScope {
return getFlags() & FlagAllCallsDescribed;
}
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.
///
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
Expand Up @@ -1267,6 +1267,12 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,

if (SP->isMainSubprogram())
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,
Expand Down
15 changes: 13 additions & 2 deletions llvm/test/Assembler/disubprogram.ll
Expand Up @@ -6,8 +6,8 @@ define void @_Z3foov() !dbg !9 {
ret void
}

; CHECK: !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}
; 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, !17, !19, !20, !21}

!0 = !{null}
!1 = distinct !DICompositeType(tag: DW_TAG_structure_type)
Expand Down Expand Up @@ -81,3 +81,14 @@ define void @_Z3foov() !dbg !9 {
!16 = !{i32 1, !"Debug Info Version", i32 3}
!llvm.module.flags = !{!16}
!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)

0 comments on commit e69917f

Please sign in to comment.