<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
h2
{mso-style-priority:9;
mso-style-link:"Heading 2 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:18.0pt;
font-family:"Calibri",sans-serif;}
h3
{mso-style-priority:9;
mso-style-link:"Heading 3 Char";
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:13.5pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.Heading2Char
{mso-style-name:"Heading 2 Char";
mso-style-priority:9;
mso-style-link:"Heading 2";
font-family:"Cambria",serif;
color:#365F91;}
span.Heading3Char
{mso-style-name:"Heading 3 Char";
mso-style-priority:9;
mso-style-link:"Heading 3";
font-family:"Cambria",serif;
color:#243F60;}
p.msonormal0, li.msonormal0, div.msonormal0
{mso-style-name:msonormal;
mso-margin-top-alt:auto;
margin-right:0in;
mso-margin-bottom-alt:auto;
margin-left:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}
span.EmailStyle20
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Hi Adrian,<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thank you for the quick reply.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">(1) I agree. We’re running out of bits there. Furthermore, I have encoded these flags in a recycle-minded way to skirt the issue.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">(2) I will take a look. Note that Fortran debuggers expect DW_TAG_string_type for CHARACTER; and, they are distinct from arrays of INTEGER*1. (Yes, the conflation of string and CHARACTER terms is unfortunate.)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">(3) The Fortran DI name choice was to deliberately keep things separated. That may not be necessary as we move forward, but it was good at the time for sanity’s sake.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">(4) My understanding is the @llvm.dbg.declare !DIExpression is to track the location of a local variable. The !DIExpression in the lower (or upper) bound is intended as a way to describe how to find or compute the bound’s value from the
array descriptor “variable” (computed from a member of a hidden argument to the function). The distinction isn’t entirely clear in the example.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I’ll work on getting the patches put up. Thanks again.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">--<o:p></o:p></p>
<p class="MsoNormal">Eric<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">From: <strong><span style="font-family:"Calibri",sans-serif">Adrian Prantl</span></strong> <<a href="mailto:aprantl@apple.com">aprantl@apple.com</a>><br>
Date: Thu, Nov 1, 2018 at 3:12 PM<br>
Subject: Re: [llvm-dev] RFC: Adding debug information to LLVM to support Fortran<br>
To: Eric Schweitz <<a href="mailto:eric.schweitz2@gmail.com">eric.schweitz2@gmail.com</a>><br>
Cc: <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>><o:p></o:p></p>
<p class="MsoNormal" style="margin-bottom:12.0pt"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Thanks for sharing your plans, I made a few comments inline I noticed on my first quick read-through.<o:p></o:p></p>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">-- adrian<o:p></o:p></p>
<div>
<p class="MsoNormal"><br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">On Nov 1, 2018, at 1:29 PM, Eric Schweitz via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<o:p></o:p></p>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><b>From:</b> flang-dev <<a href="mailto:flang-dev-bounces@lists.flang-compiler.org" target="_blank">flang-dev-bounces@lists.flang-compiler.org</a>>
<b>On Behalf Of </b>Eric Schweitz (PGI)<o:p></o:p></p>
</div>
<div>
<div>
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"><b>Sent:</b> Thursday, November 01, 2018 1:02 PM<br>
<b>To:</b> <a href="mailto:flang-dev@lists.flang-compiler.org" target="_blank">flang-dev@lists.flang-compiler.org</a><br>
<b>Subject:</b> [Flang-dev] RFC: Adding debug information to LLVM to support Fortran<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">In order to support debugging in the Flang project, work has been done to extend LLVM debug information for the Fortran language. The changes are currently available at
<a href="https://github.com/flang-compiler/llvm" target="_blank">https://github.com/flang-compiler/llvm</a>.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">In order to upstream these changes into LLVM itself, three smaller changesets, described below, will be uploaded to
<a href="https://reviews.llvm.org/" target="_blank">https://reviews.llvm.org</a> for code review.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<h2><span style="font-size:16.0pt">1. Elemental, Pure, and Recursive Procedures</span><o:p></o:p></h2>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">DWARF 4 defines attributes for these Fortran procedure specifiers: DW_AT_elemental, DW_AT_pure, DW_AT_recursive, resp. LLVM has a way of informing the DWARF generator of simple
boolean attributes in the metadata via the flags parameter. We have added these new values to the existing collection of flags.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!60 = !DISubprogram(…, flags: DIFlagElemental)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!61 = !DISubprogram(…, flags: DIFlagPure)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!62 = !DISubprogram(…, flags: DIFlagRecursive)<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">That change should be fairly straightforward, although we are starting to run out on bits in DIFLags, so we may need to come up with a clever encoding (such as reusing bits that aren't used in a DISubprogram context).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<p class="MsoNormal"><br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<h2><span style="font-size:16.0pt">2. Fortran Type Support</span><o:p></o:p></h2>
<h2>2.1 CHARACTER Intrinsic Type<o:p></o:p></h2>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">There is no analog in C for the Fortran CHARACTER type. The Fortran CHARACTER type maps to the DWARF tag, DW_TAG_string_type. We have added a new named DI to LLVM to generate this
DWARF information.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!21 = !DIStringType(name: “character(5)”, size: 40)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">This produces the following DWARF information.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
DW_TAG_string_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
DW_AT_name: “character(5)”<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_AT_byte_size: 5<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">CHARACTER types can also have deferred length. This is supported in the new metadata as follows.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!22 = !DIStringType(name: “character(*)!1”, size: 32, stringLength: !23, stringLengthExpression: !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!23 = !DILocalVariable(scope: !3, arg: 4, file: !4, type: !5, flags: DIFlagArtificial)<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal">Can you take a look at how variable-length arrays in C99 are implemented in Clang at the moment? It would be nice to use a similar scheme here.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">This will generate the following DWARF information.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
DW_TAG_string_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
DW_AT_name: character(*)!1<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in">
DW_AT_string_length: 0x9b (location list)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in">
DW_AT_byte_size: 4<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<h2>2.2 Fortran Array Types and Bounds<o:p></o:p></h2>
<h2><span style="font-size:11.0pt;font-weight:normal">In this section we refer to the DWARF tag, DW_TAG_array_type, which is used to describe Fortran arrays.</span><o:p></o:p></h2>
<h2><span style="font-size:11.0pt;font-weight:normal">However in Fortran, arrays are not types but are rather runtime data objects, a multidimensional rectangular set of scalar data of homogeneous type. An array object has dimensions (rank and corank) and
extents in those dimensions. The rank and ranges of the extents of an array may not be known until runtime. Arrays may be reshaped, acted upon in whole or in part, or otherwise be referenced (perhaps even in reverse order) non-contiguously. Furthermore arrays
may be allocated and deallocated at runtime and aliased through other POINTER objects. In short, Fortran array objects are not readily mappable to the C family of languages model of arrays, and more expressive DWARF information is required.</span><o:p></o:p></h2>
<h2><span style="font-size:12.0pt">2.2.1 Explicit array dimensions</span><o:p></o:p></h2>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">An array may be given a constant size as in the following example. The example shows a two-dimensional array, named array, that has indices from 1 to 10 for the rows and 2 to 11
for the columns.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
<span style="font-family:"Courier New"">TYPE(t) :: array(10,2:11)</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">For this declaration, the compiler generates the following LLVM metadata.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!100 = !DIFortranArrayType(baseType: !7, elements: !101)<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Since the DI* hierarchy really just is the DWARF type hierarchy, I don't think we will need to introduce any fortran-specific names for arrays.<o:p></o:p></p>
</div>
<p class="MsoNormal"><br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!101 = !{ !102, !103 }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!102 = !DIFortranSubrange(constLowerBound: 1, constUpperBound: 10)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
!103 = !DIFortranSubrange(constLowerBound: 2, constUpperBound: 11)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The DWARF generated for this is as follows. (DWARF asserts in the standard that arrays are interpreted as column-major.)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_TAG_array_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_AT_name: array<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_AT_type: 4d08 ;TYPE(t)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:70.8pt">
DW_TAG_subrange_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_type: int<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_lower_bound: 1<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_upper_bound: 10<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:70.8pt">
DW_TAG_subrange_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_type: int<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_lower_bound: 2<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_upper_bound: 11<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<h2><span style="font-size:12.0pt">2.2.2 Adjustable arrays</span><o:p></o:p></h2>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">By adjustable arrays, we mean that an array may have its size passed explicitly as another argument.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
<span style="font-family:"Courier New"">SUBROUTINE subr2(array2,N)</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
<span style="font-family:"Courier New""> INTEGER :: N</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
<span style="font-family:"Courier New""> TYPE(t) :: array2(N)</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">In this case, the compiler expresses the !DISubrange as an expression that references the dummy argument,
<span style="font-family:"Courier New"">N</span>.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
call void @llvm.dbg.declare(metadata i64* %N, metadata !113, metadata !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
…<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!110 = !DIFortranArrayType(baseType: !7, elements: !111)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!111 = !{ !112 }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!112 = !DIFortranSubrange(lowerBound: 1, upperBound: !113, upperBoundExpression: !DIExpression(DW_OP_deref)<u>)</u><o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal">It would be better (and much more robust in presence of optimizations) if the DIExpression were part of a @llvm.dbg.declare / value intrinsic tying the DILocalVariable to an LLVM SSA value.<o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!113 = !DILocalVariable(scope: !2, name: “zb1”, file: !3, type: !4, flags: DIFlagArtificial)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">It turned out that gdb didn’t properly interpret location lists or variable references in the DW_AT_lower_bound and DW_AT_upper_bound attribute forms, so the compiler must generate
either a constant or a block with the DW_OP operations for each of them.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_TAG_array_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_AT_name: array2<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_AT_type: 4d08 ;TYPE(t)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:70.8pt">
DW_TAG_subrange_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_type: int<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_lower_bound: 1<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_upper_bound: 2 byte block: 91 70<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<h2><span style="font-size:12.0pt">2.2.3 Assumed size arrays</span><o:p></o:p></h2>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">An assumed size array leaves the last dimension of the array unspecified.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
<span style="font-family:"Courier New"">SUBROUTINE subr3(array3)</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
<span style="font-family:"Courier New""> TYPE(t) :: array3(*)</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The compiler generates DWARF information without an upper bound, such as in this snippet.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_TAG_array_type<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_AT_name: array3<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:70.8pt">
DW_TAG_subrange_type<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_type = int<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.55pt">
DW_AT_lower_bound = 1<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">This DWARF is produced by omission of the upper bound information.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!122 = !DIFortranSubrange(lowerBound: 1)<o:p></o:p></p>
<h3> <o:p></o:p></h3>
<h2><span style="font-size:12.0pt">2.2.4 Assumed shape arrays</span><o:p></o:p></h2>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Fortran also has assumed shape arrays, which allow extra state to be passed into the procedure to describe the shape of the array dummy argument. This extra information is the array
descriptor, generated by the compiler, and passed as a hidden argument.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
<span style="font-family:"Courier New"">SUBROUTINE subr4(array4)</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
<span style="font-family:"Courier New""> TYPE(t) :: array4(:,:)</span><o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">In this case, the compiler generates DWARF expressions to access the results of the procedure’s usage of the array descriptor argument when it computes the lower bound (DW_AT_lower_bound)
and upper bound (DW_AT_upper_bound).<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
…<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
call void @llvm.dbg.declare(metadata i64* %4, metadata !134, metadata !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
call void @llvm.dbg.declare(metadata i64* %8, metadata !136, metadata !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
call void @llvm.dbg.declare(metadata i64* %9, metadata !137, metadata !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
call void @llvm.dbg.declare(metadata i64* %13, metadata !139, metadata !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
…<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!130 = !DIFortranArrayType(baseType: !80, elements: !131)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!131 = !{ !132, !133 }<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!132 = !DISubrange(lowerBound: !134, lowerBoundExpression: !DIExpression(DW_OP_deref), upperBound: !136, upperBoundExpression: !DIExpression(DW_OP_deref))<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.3pt">
!133 = !DISubrange(lowerBound: !137, lowerBoundExpression: !DIExpression(DW_OP_deref), upperBound: !139, upperBoundExpression: !DIExpression(DW_OP_deref))<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<p class="MsoNormal">same here.<br>
<br>
<o:p></o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!134 = !DILocalVariable(scope: !2, file: !3, type: !9, flags: DIArtificial)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!136 = !DILocalVariable(scope: !2, file: !3, type: !9, flags: DIArtificial)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!137 = !DILocalVariable(scope: !2, file: !3, type: !9, flags: DIArtificial)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!139 = !DILocalVariable(scope: !2, file: !3, type: !9, flags: DIArtificial)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The DWARF generated for this is as follows.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:35.4pt">
DW_TAG_array_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in;text-indent:.5in">
DW_AT_name: array4<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:34.8pt;text-indent:.5in">
DW_AT_type: 4d08 ;TYPE(t)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:70.8pt">
DW_TAG_subrange_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_type: int<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_lower_bound: 2 byte block: 91 78<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_upper_bound: 2 byte block: 91 70<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:70.8pt">
DW_TAG_subrange_type:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_type: int<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_lower_bound: 2 byte block: 91 68<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
DW_AT_upper_bound: 2 byte block: 91 60<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:106.2pt">
<o:p></o:p></p>
<h2><span style="font-size:12.0pt">2.2.5 Assumed rank arrays and coarrays</span><o:p></o:p></h2>
<h2><span style="font-size:11.0pt;font-weight:normal">This changeset does not address DWARF 5 extensions to support assumed rank arrays or coarrays.</span><o:p></o:p></h2>
<h2><span style="font-size:11.0pt;font-weight:normal"> </span><o:p></o:p></h2>
<h2><span style="font-size:16.0pt">3. Fortran COMMON Block</span><o:p></o:p></h2>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">COMMON blocks are a feature of Fortran that has no direct analog in C languages, but they are similar to data sections in assembly language programming. A COMMON block is a named
area of memory that holds a collection of variables. Fortran subprograms may map the COMMON block memory area to their own, possibly distinct, non-empty list of variables. A Fortran COMMON block might look like the following example.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
COMMON /ALPHA/ I, J<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">For this construct, the compiler generates a new scope-like DI construct (!DICommonBlock) into which variables (see I, J above) can be placed. As the common block implies a range
of storage with global lifetime, the !DICommonBlock refers to a !DIGlobalVariable. The Fortran variable that comprise the COMMON block are also linked via metadata to offsets within the global variable that stands for the entire common block.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
@alpha_ = common global %alphabytes_ zeroinitializer, align 64, !dbg !27, !dbg !30, !dbg !33<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!14 = distinct !DISubprogram(…)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!20 = distinct !DICommonBlock(scope: !14, declaration: !25, name: "alpha")<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!25 = distinct !DIGlobalVariable(scope: !20, name: "common alpha", type: !24)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!27 = !DIGlobalVariableExpression(var: !25, expr: !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!29 = distinct !DIGlobalVariable(scope: !20, name: "i", file: !3, type: !28)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!30 = !DIGlobalVariableExpression(var: !29, expr: !DIExpression())<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!31 = distinct !DIGlobalVariable(scope: !20, name: "j", file: !3, type: !28)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!32 = !DIExpression(DW_OP_plus_uconst, 4)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
!33 = !DIGlobalVariableExpression(var: !31, expr: !32)<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">The DWARF generated for this is as follows.<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in">
DW_TAG_common_block:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in">
DW_AT_name: alpha<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in">
DW_AT_location: @alpha_+0<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in">
DW_TAG_variable:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.5in">
DW_AT_name: common alpha<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.5in">
DW_AT_type: array of 8 bytes<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.5in">
DW_AT_location: @alpha_+0<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in;text-indent:.5in">
DW_TAG_variable:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in;text-indent:.5in">
DW_AT_name: i<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in;text-indent:.5in">
DW_AT_type: integer*4<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in;text-indent:.5in">
DW_AT_location: @alpha+0<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in;text-indent:.5in">
DW_TAG_variable:<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in;text-indent:.5in">
DW_AT_name: j<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in;text-indent:.5in">
DW_AT_type: integer*4<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:1.0in;text-indent:.5in">
DW_AT_location: @alpha+4<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">--<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto">Eric<o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
<p class="MsoNormal" style="mso-margin-top-alt:auto;mso-margin-bottom-alt:auto"> <o:p></o:p></p>
</div>
</div>
</div>
</div>
<p class="MsoNormal">_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><o:p></o:p></p>
</div>
</blockquote>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
<div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="100%" align="center">
</div>
</div>
<div>
<p class="MsoNormal">This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact
the sender by reply email and destroy all copies of the original message. <o:p></o:p></p>
</div>
<div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="100%" align="center">
</div>
</div>
</div>
</body>
</html>