On Tue, Nov 3, 2015 at 10:58 PM, Mike Stump <mikest...@comcast.net> wrote:
> On Nov 3, 2015, at 12:46 AM, Richard Sandiford <richard.sandif...@arm.com> 
> wrote:
>> This isn't just an argument about the DWARF standard though.  It's an
>> argument about GCC internals.  Presumably these hypothetical BLKmode
>> types would need to support addition,
>
> I don’t recall seeing that as a requirement in the dwarf standard, nor in the 
> language standard of the hypothetical language I posited.  Further, I don’t 
> recall seeing a prohibition on fetching from memory, combining three byte to 
> form a 24 bit value in a 64 bit register on x86_64, nor the prohibition on 
> doing a 64-bit add on that architecture.  Do you have a quote to support your 
> position?  Further, I don’t even see support that add must be supported in 
> the language front end I posited.  Since I control it, you can’t can’t 
> require much of anything in it.
>
>> but plus:BLK is not well formed,
>
> BLKmode is well formed in gcc.  I can’t image what this even means.
>
>> and wouldn't distinguish between your 3-byte and 152-bit cases.
>
> A 3 byte value in dwarf has a byte length of 3, and a 152 bit value has a 
> byte length of 19.  I fail to see why in dwarf they cannot be distinguished.  
> A cleaver front end can track the values in that front end, and regions of 
> memory that is uses to back objects, usually the front end does track 
> objects, and when asked to, will generate dwarf for them.  I believe that 
> front ends are able to track object byte sized for objects.  I believe that 
> the C++ front end does this for example, and will generate dwarf.
>
>> I don’t think const_int and const_wide_int are logically different.
>
> They aren’t.  Indeed, the code for const_wide_int was copied from const_int 
> and/or const_double and only enhanced to have an arbitrary size.
>
>> There's the
>> historical decision that const_int doesn't have a stored mode, but I
>> don't think that was because we wanted to support const_ints that are
>> conceptually BLKmode.
>
> So, given that what must be, given the semantics of dwarf, and the totality 
> of semantics available to a front end, BLKmode values are perfectly well 
> defined.  I don’t know why you would think otherwise.  Further, arguing that 
> we must break them, because…  is silly, without the because elaborated.  A 
> constant value that is known at compile time to be an arbitrary value whose 
> type is a signed n byte int can be represented in const_int when n fits, and 
> can be expressed as a const_wide_int when n fits and can be expressed in 
> dwarf.  Further, const_int is not unreasonable to represent constants, 
> further, there is no prohibition on a front end having constants, nor on the 
> size of those constants being n bytes in size, at least for values of n where 
> n can be supported directly by const_wide_int. If there were one, you could 
> be able to quote it.
>
>> I think from an rtl perspective the only sensible way for frontends to
>> cope with integers whose size doesn't match an rtl mode is to promote
>> to the next widest mode,
>
> No, again, to support your position, you’d have to quote the part of gcc that 
> disclaims support.  You have not.  You can think there is a prohibition on 3 
> byte ints, if you want.  I can’t fix that.  What I can object to, is adding a 
> line to the document that says that gcc cannot be used to write a front end 
> that supports 3 byte ints, or 19 byte ints.
>
>> which is what the stor-layout.c code I quoted
>> does.  Obviously if your 3 byte type is actually 3 bytes in memory rather
>> than 4, and no 3-byte mode is available, you can't just load and store
>> the value using a normal rtl move.  You have to use bitfield extraction
>> and insertion instead.
>
> So?  Another technique that a front end could use is to fetch a HImode, and a 
> QImode value, shift and or them together, but no matter.
>
>> I picked this PR up because it was wide-int-related, even though
>> (as is probably all too obvious from this thread) I'm not familiar
>> with the dwarf2out.c code.  It's actually your commit that I'm trying
>> to fix here (r201707).  Would you mind taking the PR over and handling
>> it the way you think it should be handled?
>
> So, I did up the patch:
>
> Index: rtl.h
> ===================================================================
> --- rtl.h       (revision 229720)
> +++ rtl.h       (working copy)
> @@ -2086,6 +2086,15 @@
>  inline unsigned int
>  wi::int_traits <rtx_mode_t>::get_precision (const rtx_mode_t &x)
>  {
> +  /* VOIDmode CONST_WIDE_INT pairings are used for debug information
> +     when the type of the underlying object has not been tracked and
> +     is unimportant so we form a precision from the value of the
> +     constant.  This is sufficient for dwarf generation as dwarf can
> +     track the type separately from the value.  */
> +  if (x.second == VOIDmode
> +      && CONST_WIDE_INT_P (x.first))
> +    return CONST_WIDE_INT_NUNITS (x.first) * HOST_BITS_PER_WIDE_INT;
> +
>    return GET_MODE_PRECISION (x.second);
>  }

I think you should limit the effect of this patch to the dwarf2out use
as the above doesn't make
sense to me.  As Richard said, a (plus:BLK ...) isn't well-formed.

Ideally we'd have an assert that you don't create a rtx_mode_t with
VOIDmode or BLKmode.

Handling the CONST_WIDE_INT in dwarf2out.c the same as we did before
(with CONST_DOUBLE)
looks sensible as far of fixing a regression (I assume the diff to the
dwarf results in essentially the
same DWARF as what was present before wide-int).

Richard.

> Index: wide-int.h
> ===================================================================
> --- wide-int.h  (revision 229720)
> +++ wide-int.h  (working copy)
> @@ -156,6 +156,10 @@
>              rtx r = ...
>              wide_int x = std::make_pair (r, mode);
>
> +   If the mode is VOIDmode, then the precision of the wide_int will be
> +   the number of bits used to represent the rtl's value.  This is used for
> +   untyped constants for dwarf debug information.
> +
>     Similarly, a wide_int can only be constructed from a host value if
>     the target precision is given explicitly, such as in:
>
> The intent is to exactly match what gcc did before, to have wide-int handling 
> match what const_int does, and what const_double did in the past, merely 
> extended to support arbitrarily large values.  I find, in this case, what was 
> done in the past to be valid and desirable.  I don’t find any reason to 
> deviate from what was done before.
>
> The test case from the PR changes like this:
>
> --- t-bad.s     2015-11-03 16:19:13.786248224 -0500
> +++ t-fixed.s   2015-11-03 16:02:48.414290258 -0500
> @@ -23,7 +23,7 @@ test:
>  .Letext0:
>         .section        .debug_info,"",@progbits
>  .Ldebug_info0:
> -       .long   0x63    # Length of Compilation Unit Info
> +       .long   0x74    # Length of Compilation Unit Info
>         .value  0x4     # DWARF version number
>         .long   .Ldebug_abbrev0 # Offset Into Abbrev. Section
>         .byte   0x8     # Pointer Size (in bytes)
> @@ -41,25 +41,28 @@ test:
>         .byte   0x1     # DW_AT_decl_file (t.c)
>         .byte   0x1     # DW_AT_decl_line
>                         # DW_AT_prototyped
> -       .long   0x5a    # DW_AT_type
> +       .long   0x6b    # DW_AT_type
>         .quad   .LFB0   # DW_AT_low_pc
>         .quad   .LFE0-.LFB0     # DW_AT_high_pc
>         .uleb128 0x1    # DW_AT_frame_base
>         .byte   0x9c    # DW_OP_call_frame_cfa
>                         # DW_AT_GNU_all_call_sites
> -       .long   0x5a    # DW_AT_sibling
> +       .long   0x6b    # DW_AT_sibling
>         .uleb128 0x3    # (DIE (0x4e) DW_TAG_variable)
>         .long   .LASF3  # DW_AT_name: "two127"
>         .byte   0x1     # DW_AT_decl_file (t.c)
>         .byte   0x3     # DW_AT_decl_line
> -       .long   0x61    # DW_AT_type
> +       .long   0x72    # DW_AT_type
> +       .byte   0x10
> +       .quad   0       # DW_AT_const_value
> +       .quad   0x8000000000000000      # (null)
>         .byte   0       # end of children of DIE 0x2d
> -       .uleb128 0x4    # (DIE (0x5a) DW_TAG_base_type)
> +       .uleb128 0x4    # (DIE (0x6b) DW_TAG_base_type)
>         .byte   0x10    # DW_AT_byte_size
>         .byte   0x7     # DW_AT_encoding
>         .long   .LASF4  # DW_AT_name: "__int128 unsigned"
> -       .uleb128 0x5    # (DIE (0x61) DW_TAG_const_type)
> -       .long   0x5a    # DW_AT_type
> +       .uleb128 0x5    # (DIE (0x72) DW_TAG_const_type)
> +       .long   0x6b    # DW_AT_type
>         .byte   0       # end of children of DIE 0xb
>         .section        .debug_abbrev,"",@progbits
>
> I’m not a dwarf expert, but, I see the addition of two quads for a const 
> value, and that value seems to be 1 << 127 to my untrained eye.  If I had to 
> theorizes, I’d say this is what the debug information was before.  [ checking 
> ] I checked gcc-4.8 on x86_64, and the debug information is now virtually the 
> same:
>
> *** t-48.s      2015-11-03 16:24:23.286235021 -0500
> --- t-fixed.s   2015-11-03 16:02:48.414290258 -0500
> *************** test:
> *** 28,35 ****
>         .long   .Ldebug_abbrev0 # Offset Into Abbrev. Section
>         .byte   0x8     # Pointer Size (in bytes)
>         .uleb128 0x1    # (DIE (0xb) DW_TAG_compile_unit)
> !       .long   .LASF0  # DW_AT_producer: "GNU C 4.8.4 -mtune=generic 
> -march=x86-64 -g -O -fstack-protector"
> !       .byte   0x1     # DW_AT_language
>         .ascii "t.c\0"  # DW_AT_name
>         .long   .LASF1  # DW_AT_comp_dir: "/home/mrs/net/gcc-linuxO0/gcc"
>         .quad   .Ltext0 # DW_AT_low_pc
> --- 28,35 ----
>         .long   .Ldebug_abbrev0 # Offset Into Abbrev. Section
>         .byte   0x8     # Pointer Size (in bytes)
>         .uleb128 0x1    # (DIE (0xb) DW_TAG_compile_unit)
> !       .long   .LASF0  # DW_AT_producer: "GNU C11 6.0.0 20151103 
> (experimental) [trunk revision 229720] -O -g"
> !       .byte   0xc     # DW_AT_language
>         .ascii "t.c\0"  # DW_AT_name
>         .long   .LASF1  # DW_AT_comp_dir: "/home/mrs/net/gcc-linuxO0/gcc"
>         .quad   .Ltext0 # DW_AT_low_pc
> *************** test:
> *** 55,61 ****
>         .long   0x72    # DW_AT_type
>         .byte   0x10
>         .quad   0       # DW_AT_const_value
> !       .quad   0x8000000000000000
>         .byte   0       # end of children of DIE 0x2d
>         .uleb128 0x4    # (DIE (0x6b) DW_TAG_base_type)
>         .byte   0x10    # DW_AT_byte_size
> --- 55,61 ----
>         .long   0x72    # DW_AT_type
>         .byte   0x10
>         .quad   0       # DW_AT_const_value
> !       .quad   0x8000000000000000      # (null)
>         .byte   0       # end of children of DIE 0x2d
>         .uleb128 0x4    # (DIE (0x6b) DW_TAG_base_type)
>         .byte   0x10    # DW_AT_byte_size
> *************** test:
> *** 162,168 ****
>   .Ldebug_line0:
>         .section        .debug_str,"MS",@progbits,1
>   .LASF0:
> !       .string "GNU C 4.8.4 -mtune=generic -march=x86-64 -g -O 
> -fstack-protector"
>   .LASF1:
>         .string "/home/mrs/net/gcc-linuxO0/gcc"
>   .LASF3:
> --- 162,168 ----
>   .Ldebug_line0:
>         .section        .debug_str,"MS",@progbits,1
>   .LASF0:
> !       .string "GNU C11 6.0.0 20151103 (experimental) [trunk revision 
> 229720] -O -g"
>   .LASF1:
>         .string "/home/mrs/net/gcc-linuxO0/gcc"
>   .LASF3:
> *************** test:
> *** 171,175 ****
>         .string "test"
>   .LASF4:
>         .string "__int128 unsigned"
> !       .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4"
>         .section        .note.GNU-stack,"",@progbits
> --- 171,175 ----
>         .string "test"
>   .LASF4:
>         .string "__int128 unsigned"
> !       .ident  "GCC: (GNU) 6.0.0 20151103 (experimental) [trunk revision 
> 229720]"
>         .section        .note.GNU-stack,"",@progbits
>
> The language seems weird, but, I bet it is inconsequential and an artifact of 
> how I ran the test case.  The # (null) is unfortunate, I don’t think this is 
> better than what gcc-4.8 did, but, I don’t think that was caused by my patch.
>
> So, this would be my proposal to fix the issue.  I'd invite anyone that 
> thinks the dwarf information was wrong in gcc-4.8 or wrong post the patch, to 
> let us know why.  If there are reasons why my position is wrong, I’d like to 
> hear about it, otherwise I’ll plan on checking this in with my wide-int hat 
> on.  Since this is a serious regression in debug quality, this has to go the 
> the release branches that contain wide-int.

Reply via email to