Hello,
I want to make gfortran produce better debug information, but I want to do it
in a way that doesn't make it hard/impossible to read back in sufficient
information for LTO to work for gfortran.
I haven't really been following the whole LTO thing much, but if I understand
correctly, the goal is to reconstruct information about declarations from
DWARF information that we write out for those declarations. If that's the
case, I wonder how LTO will handle artificial "variables" and formal argument
lists.
For example, gfortran adds additional formal arguments for functions that take
a CHARACTER string as a formal argument, e.g.
program test
implicit none
call sub("Hi World!")
contains
subroutine sub(c)
character*10 c
end subroutine
end
produces as a GIMPLE dump:
MAIN__ ()
{
static void sub (char[1:10] &, int4);
_gfortran_set_std (70, 127, 0);
sub ("Hi World!", 9);
}
sub (c, _c)
{
(void) 0;
}
where _c is strlen("Hi World!"). From a user perspective, it would be better
to hide _c for the debugger because it is not something that the user had in
the original program. I have a patch to hide that parameter, that is, it
stops GCC from writing out DW_TAG_formal_parameter for _c. But I am worried
about how this will work out later if/when someone tries to make LTO work for
gfortran too.
Can you still reconstruct the correct function prototype for LTO from the
debug info if you don't write debug info for _c?
Similarly, LTO has to somehow deal with DECL_VALUE_EXPR and the debug
information that is produced from it. Gfortran (and iiuc other front ends
and SRA) use this DECL_VALUE_EXPR to produce fake variables that point to
some location to improve the debug experience of the user. For Fortran we
use it to create fake variables to point at members of a COMMON block, for
example, so that the user can do "p A" for a variable A in a common block,
instead of "p name_of_the_common_block.A". Is there already some provision
to handle this kind of trickery in LTO?
Finally, consider another Fortran example:
program debug_array_dimensions
implicit none
integer i(10,10)
i(2,9) = 1
end
Gfortran currently produces the following wrong debug information for this
example:
<2><94>: Abbrev Number: 3 (DW_TAG_variable)
DW_AT_name : i
DW_AT_decl_file : 1
DW_AT_decl_line : 1
DW_AT_type : <a2>
DW_AT_location : 3 byte block: 91 e0 7c (DW_OP_fbreg: -416)
<1><a2>: Abbrev Number: 4 (DW_TAG_array_type)
DW_AT_type : <bb>
DW_AT_sibling : <b3>
<2><ab>: Abbrev Number: 5 (DW_TAG_subrange_type)
DW_AT_type : <b3>
DW_AT_lower_bound : 0
DW_AT_upper_bound : 99
<1><b3>: Abbrev Number: 6 (DW_TAG_base_type)
DW_AT_byte_size : 8
DW_AT_encoding : 5 (signed)
DW_AT_name : int8
<1><bb>: Abbrev Number: 6 (DW_TAG_base_type)
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
DW_AT_name : int4
Note the sinlge DW_TAG_subrange_type <0, 99> for the type of "i", instead of
two times DW_TAG_subrange_type <1, 10> instead. This happens because in
gfortran all arrays are flattened (iirc to make code generation easier). I
would like to make gfortran write out the correct debug information, e.g.
something with
<2><ae>: Abbrev Number: 5 (DW_TAG_subrange_type)
DW_AT_type : <bb>
DW_AT_upper_bound : 10
<2><b4>: Abbrev Number: 5 (DW_TAG_subrange_type)
DW_AT_type : <bb>
DW_AT_upper_bound : 10
but what would happen if LTO reads this in and re-constructs the type of "i"
from this information? I imagine it would lead to mis-matches of the GIMPLE
code that you read in, where "i" is a 1x100 array, and the re-constructed
variable "i" which would be a 10x10 2D array.
Has anyone working on LTO already thought of these challanges?
I'm all new to both DWARF and LTO, so forgive me if my rant doesn't make
sense ;-)
Gr.
Steven