public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
@ 2011-08-20 15:52 Gerald Pfeifer
  2011-08-22  6:42 ` Eric Botcazou
  0 siblings, 1 reply; 33+ messages in thread
From: Gerald Pfeifer @ 2011-08-20 15:52 UTC (permalink / raw)
  To: Richard Henderson, gcc-patches; +Cc: bernds, avr, Ian Lance Taylor, Jeff Law

I'm afraid this patch casues i386 bootstraps to fail:

  Comparing stages 2 and 3
  warning: gcc/cc1-checksum.o differs
  warning: gcc/cc1plus-checksum.o differs
  warning: gcc/cc1obj-checksum.o differs
  Bootstrap comparison failure!
  libiberty/pic/cplus-dem.o differs
  libiberty/pic/crc32.o differs

Here is part of my binary search:

  r177170 2011-08-02 14:55:47     okay
  r177212 2011-08-02 20:26:57     okay
  r177216 2011-08-02 21:09:26     okay
  r177218 2011-08-02 22:18:35     comparison failure

This is also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50010 .


Gerald


2011-08-02  Richard Henderson  <rth@redhat.com>

        PR target/49864
        * reg-notes.def (REG_ARGS_SIZE): New.
        * calls.c (emit_call_1): Emit REG_ARGS_SIZE for call_pop.
        (expand_call): Add REG_ARGS_SIZE to emit_stack_restore.
        * cfgcleanup.c (old_insns_match_p): Don't allow cross-jumping to
        different stack levels.
        * combine-stack-adj.c (adjust_frame_related_expr): Remove.
        (maybe_move_args_size_note): New.
        (combine_stack_adjustments_for_block): Use it.
        * combine.c (distribute_notes): Place REG_ARGS_SIZE.
        * dwarf2cfi.c (dw_cfi_row_struct): Remove args_size member.
        (dw_trace_info): Add beg_true_args_size, end_true_args_size,
        beg_delay_args_size, end_delay_args_size, eh_head, args_size_undefined.
        (cur_cfa): New.
        (queued_args_size): Remove.
        (add_cfi_args_size): Assert size is non-negative.
        (stack_adjust_offset, dwarf2out_args_size): Remove.
        (dwarf2out_stack_adjust, dwarf2out_notice_stack_adjust): Remove.
        (notice_args_size, notice_eh_throw): New.
        (dwarf2out_frame_debug_def_cfa): Use cur_cfa.
        (dwarf2out_frame_debug_adjust_cfa): Likewise.
        (dwarf2out_frame_debug_cfa_offset): Likewise.
        (dwarf2out_frame_debug_expr): Likewise.  Don't stack_adjust_offset.
        (dwarf2out_frame_debug): Don't handle non-frame-related-p insns.
        (change_cfi_row): Don't emit args_size.
        (maybe_record_trace_start_abnormal): Split out from ...
        (maybe_record_trace_start): Here.  Set args_size_undefined.
        (create_trace_edges): Update to match.
        (scan_trace): Handle REG_ARGS_SIZE.
        (connect_traces): Connect args_size between EH insns.
        * emit-rtl.c (try_split): Handle REG_ARGS_SIZE.
        * explow.c (suppress_reg_args_size): New.
        (adjust_stack_1): Split out from ...
        (adjust_stack): ... here.
        (anti_adjust_stack): Use it.
        (allocate_dynamic_stack_space): Suppress REG_ARGS_SIZE.
        * expr.c (mem_autoinc_base): New.
        (fixup_args_size_notes): New.
        (emit_single_push_insn_1): Rename from emit_single_push_insn.
        (emit_single_push_insn): New.  Generate REG_ARGS_SIZE.
        * recog.c (peep2_attempt): Handle REG_ARGS_SIZE.
        * reload1.c (reload_as_needed): Likewise.
        * rtl.h (fixup_args_size_notes): Declare.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-20 15:52 [RFC] Cleanup DW_CFA_GNU_args_size handling Gerald Pfeifer
@ 2011-08-22  6:42 ` Eric Botcazou
  2011-08-23 22:20   ` Richard Henderson
  0 siblings, 1 reply; 33+ messages in thread
From: Eric Botcazou @ 2011-08-22  6:42 UTC (permalink / raw)
  To: Gerald Pfeifer
  Cc: gcc-patches, Richard Henderson, bernds, avr, Ian Lance Taylor, Jeff Law

> I'm afraid this patch casues i386 bootstraps to fail:
>
>   Comparing stages 2 and 3
>   warning: gcc/cc1-checksum.o differs
>   warning: gcc/cc1plus-checksum.o differs
>   warning: gcc/cc1obj-checksum.o differs
>   Bootstrap comparison failure!
>   libiberty/pic/cplus-dem.o differs
>   libiberty/pic/crc32.o differs

Probably stating the obvious, but the outcome is the same for i586.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-22  6:42 ` Eric Botcazou
@ 2011-08-23 22:20   ` Richard Henderson
  2011-08-24  6:44     ` Gerald Pfeifer
  2011-08-24 17:38     ` Eric Botcazou
  0 siblings, 2 replies; 33+ messages in thread
From: Richard Henderson @ 2011-08-23 22:20 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: Gerald Pfeifer, gcc-patches, bernds, avr, Ian Lance Taylor, Jeff Law

On 08/21/2011 02:51 PM, Eric Botcazou wrote:
>> I'm afraid this patch casues i386 bootstraps to fail:
>>
>>   Comparing stages 2 and 3
>>   warning: gcc/cc1-checksum.o differs
>>   warning: gcc/cc1plus-checksum.o differs
>>   warning: gcc/cc1obj-checksum.o differs
>>   Bootstrap comparison failure!
>>   libiberty/pic/cplus-dem.o differs
>>   libiberty/pic/crc32.o differs
> 
> Probably stating the obvious, but the outcome is the same for i586.
> 

I've been trying for 2 days to replicate this with various
configurations and none have failed.


r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-23 22:20   ` Richard Henderson
@ 2011-08-24  6:44     ` Gerald Pfeifer
  2011-08-24  7:38       ` Richard Henderson
  2011-08-24 17:38     ` Eric Botcazou
  1 sibling, 1 reply; 33+ messages in thread
From: Gerald Pfeifer @ 2011-08-24  6:44 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Eric Botcazou, gcc-patches, bernds, avr, Ian Lance Taylor, Jeff Law

[-- Attachment #1: Type: TEXT/PLAIN, Size: 638 bytes --]

On Tue, 23 Aug 2011, Richard Henderson wrote:
> I've been trying for 2 days to replicate this with various
> configurations and none have failed.

Thanks for investigating, and sorry that this proves a worthy opponent!


On my testers, the system compiler used for bootstrap is GCC 4.2.
Could that make a difference?


Also, comparing stage2-libiberty/fnmatch.o  and stage3-libiberty/fnmatch.o
I noticed that the latter is more than three times the size.

objdump -d does not show any difference.  objdump -W, however, shows
lots of additional DWARF debugging information.  I am attaching a diff 
between the two.

Does that help?

Gerald

[-- Attachment #2: Type: TEXT/PLAIN, Size: 51425 bytes --]

--- 2	2011-08-23 22:36:47.000000000 +0000
+++ 3	2011-08-23 22:36:41.000000000 +0000
@@ -1,3 +1,1079 @@
 
-stage2-libiberty/fnmatch.o:     file format elf32-i386-freebsd
+stage3-libiberty/fnmatch.o:     file format elf32-i386-freebsd
+
+The section .debug_frame contains:
+
+00000000 00000010 ffffffff CIE
+  Version:               1
+  Augmentation:          ""
+  Code alignment factor: 1
+  Data alignment factor: -4
+  Return address column: 8
+
+  DW_CFA_def_cfa: r4 ofs 4
+  DW_CFA_offset: r8 at cfa-4
+  DW_CFA_nop
+  DW_CFA_nop
+
+00000014 0000003c 00000000 FDE cie=00000000 pc=00000000..00000515
+  DW_CFA_advance_loc: 1 to 00000001
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_advance_loc: 1 to 00000002
+  DW_CFA_def_cfa_offset: 12
+  DW_CFA_advance_loc: 1 to 00000003
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 1 to 00000004
+  DW_CFA_def_cfa_offset: 20
+  DW_CFA_advance_loc: 3 to 00000007
+  DW_CFA_def_cfa_offset: 96
+  DW_CFA_offset: r5 at cfa-8
+  DW_CFA_offset: r7 at cfa-12
+  DW_CFA_offset: r6 at cfa-16
+  DW_CFA_offset: r3 at cfa-20
+  DW_CFA_advance_loc1: 241 to 000000f8
+  DW_CFA_remember_state
+  DW_CFA_def_cfa_offset: 20
+  DW_CFA_advance_loc: 1 to 000000f9
+  DW_CFA_restore: r3
+  DW_CFA_def_cfa_offset: 16
+  DW_CFA_advance_loc: 1 to 000000fa
+  DW_CFA_restore: r6
+  DW_CFA_def_cfa_offset: 12
+  DW_CFA_advance_loc: 1 to 000000fb
+  DW_CFA_restore: r7
+  DW_CFA_def_cfa_offset: 8
+  DW_CFA_advance_loc: 1 to 000000fc
+  DW_CFA_restore: r5
+  DW_CFA_def_cfa_offset: 4
+  DW_CFA_advance_loc: 4 to 00000100
+  DW_CFA_restore_state
+  DW_CFA_nop
+  DW_CFA_nop
+
+The section .debug_info contains:
+
+  Compilation Unit @ offset 0x0:
+   Length:        1043
+   Version:       2
+   Abbrev Offset: 0
+   Pointer Size:  4
+ <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
+  < c>     DW_AT_producer    : (indirect string, offset: 0x13f): GNU C 4.7.0 20110823 (experimental)	
+  <10>     DW_AT_language    : 1	(ANSI C)
+  <11>     DW_AT_name        : (indirect string, offset: 0x172): /scratch/tmp/gerald/gcc-HEAD/libiberty/fnmatch.c	
+  <15>     DW_AT_low_pc      : 0	
+  <19>     DW_AT_high_pc     : 0x515	
+  <1d>     DW_AT_stmt_list   : 0	
+ <1><21>: Abbrev Number: 2 (DW_TAG_base_type)
+  <22>     DW_AT_byte_size   : 1	
+  <23>     DW_AT_encoding    : 6	(signed char)
+  <24>     DW_AT_name        : (indirect string, offset: 0xfc): signed char	
+ <1><28>: Abbrev Number: 2 (DW_TAG_base_type)
+  <29>     DW_AT_byte_size   : 1	
+  <2a>     DW_AT_encoding    : 8	(unsigned char)
+  <2b>     DW_AT_name        : (indirect string, offset: 0xe0): unsigned char	
+ <1><2f>: Abbrev Number: 2 (DW_TAG_base_type)
+  <30>     DW_AT_byte_size   : 2	
+  <31>     DW_AT_encoding    : 5	(signed)
+  <32>     DW_AT_name        : (indirect string, offset: 0x2a): short int	
+ <1><36>: Abbrev Number: 2 (DW_TAG_base_type)
+  <37>     DW_AT_byte_size   : 2	
+  <38>     DW_AT_encoding    : 7	(unsigned)
+  <39>     DW_AT_name        : (indirect string, offset: 0x1ae): short unsigned int	
+ <1><3d>: Abbrev Number: 3 (DW_TAG_base_type)
+  <3e>     DW_AT_byte_size   : 4	
+  <3f>     DW_AT_encoding    : 5	(signed)
+  <40>     DW_AT_name        : int	
+ <1><44>: Abbrev Number: 4 (DW_TAG_typedef)
+  <45>     DW_AT_name        : (indirect string, offset: 0x59): __uint32_t	
+  <49>     DW_AT_decl_file   : 2	
+  <4a>     DW_AT_decl_line   : 56	
+  <4b>     DW_AT_type        : <4f>	
+ <1><4f>: Abbrev Number: 2 (DW_TAG_base_type)
+  <50>     DW_AT_byte_size   : 4	
+  <51>     DW_AT_encoding    : 7	(unsigned)
+  <52>     DW_AT_name        : (indirect string, offset: 0x132): unsigned int	
+ <1><56>: Abbrev Number: 2 (DW_TAG_base_type)
+  <57>     DW_AT_byte_size   : 8	
+  <58>     DW_AT_encoding    : 5	(signed)
+  <59>     DW_AT_name        : (indirect string, offset: 0x96): long long int	
+ <1><5d>: Abbrev Number: 2 (DW_TAG_base_type)
+  <5e>     DW_AT_byte_size   : 8	
+  <5f>     DW_AT_encoding    : 7	(unsigned)
+  <60>     DW_AT_name        : (indirect string, offset: 0x10e): long long unsigned int	
+ <1><64>: Abbrev Number: 2 (DW_TAG_base_type)
+  <65>     DW_AT_byte_size   : 4	
+  <66>     DW_AT_encoding    : 7	(unsigned)
+  <67>     DW_AT_name        : (indirect string, offset: 0x21a): long unsigned int	
+ <1><6b>: Abbrev Number: 2 (DW_TAG_base_type)
+  <6c>     DW_AT_byte_size   : 12	
+  <6d>     DW_AT_encoding    : 4	(float)
+  <6e>     DW_AT_name        : (indirect string, offset: 0xc8): long double	
+ <1><72>: Abbrev Number: 4 (DW_TAG_typedef)
+  <73>     DW_AT_name        : (indirect string, offset: 0x1d5): __size_t	
+  <77>     DW_AT_decl_file   : 2	
+  <78>     DW_AT_decl_line   : 89	
+  <79>     DW_AT_type        : <44>	
+ <1><7d>: Abbrev Number: 2 (DW_TAG_base_type)
+  <7e>     DW_AT_byte_size   : 1	
+  <7f>     DW_AT_encoding    : 6	(signed char)
+  <80>     DW_AT_name        : (indirect string, offset: 0x1d0): char	
+ <1><84>: Abbrev Number: 2 (DW_TAG_base_type)
+  <85>     DW_AT_byte_size   : 4	
+  <86>     DW_AT_encoding    : 5	(signed)
+  <87>     DW_AT_name        : (indirect string, offset: 0xa4): long int	
+ <1><8b>: Abbrev Number: 4 (DW_TAG_typedef)
+  <8c>     DW_AT_name        : (indirect string, offset: 0xd4): __ct_rune_t	
+  <90>     DW_AT_decl_file   : 3	
+  <91>     DW_AT_decl_line   : 88	
+  <92>     DW_AT_type        : <3d>	
+ <1><96>: Abbrev Number: 4 (DW_TAG_typedef)
+  <97>     DW_AT_name        : (indirect string, offset: 0x6b): __rune_t	
+  <9b>     DW_AT_decl_file   : 3	
+  <9c>     DW_AT_decl_line   : 89	
+  <9d>     DW_AT_type        : <8b>	
+ <1><a1>: Abbrev Number: 2 (DW_TAG_base_type)
+  <a2>     DW_AT_byte_size   : 4	
+  <a3>     DW_AT_encoding    : 7	(unsigned)
+  <a4>     DW_AT_name        : (indirect string, offset: 0x3d): sizetype	
+ <1><a8>: Abbrev Number: 5 (DW_TAG_structure_type)
+  <a9>     DW_AT_byte_size   : 16	
+  <aa>     DW_AT_decl_file   : 4	
+  <ab>     DW_AT_decl_line   : 48	
+  <ac>     DW_AT_sibling     : <e9>	
+ <2><b0>: Abbrev Number: 6 (DW_TAG_member)
+  <b1>     DW_AT_name        : (indirect string, offset: 0x243): __min	
+  <b5>     DW_AT_decl_file   : 4	
+  <b6>     DW_AT_decl_line   : 49	
+  <b7>     DW_AT_type        : <96>	
+  <bb>     DW_AT_data_member_location: 2 byte block: 23 0 	(DW_OP_plus_uconst: 0)
+ <2><be>: Abbrev Number: 6 (DW_TAG_member)
+  <bf>     DW_AT_name        : (indirect string, offset: 0x1fa): __max	
+  <c3>     DW_AT_decl_file   : 4	
+  <c4>     DW_AT_decl_line   : 50	
+  <c5>     DW_AT_type        : <96>	
+  <c9>     DW_AT_data_member_location: 2 byte block: 23 4 	(DW_OP_plus_uconst: 4)
+ <2><cc>: Abbrev Number: 6 (DW_TAG_member)
+  <cd>     DW_AT_name        : (indirect string, offset: 0x1e9): __map	
+  <d1>     DW_AT_decl_file   : 4	
+  <d2>     DW_AT_decl_line   : 51	
+  <d3>     DW_AT_type        : <96>	
+  <d7>     DW_AT_data_member_location: 2 byte block: 23 8 	(DW_OP_plus_uconst: 8)
+ <2><da>: Abbrev Number: 6 (DW_TAG_member)
+  <db>     DW_AT_name        : (indirect string, offset: 0x251): __types	
+  <df>     DW_AT_decl_file   : 4	
+  <e0>     DW_AT_decl_line   : 52	
+  <e1>     DW_AT_type        : <e9>	
+  <e5>     DW_AT_data_member_location: 2 byte block: 23 c 	(DW_OP_plus_uconst: 12)
+ <1><e9>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <ea>     DW_AT_byte_size   : 4	
+  <eb>     DW_AT_type        : <64>	
+ <1><ef>: Abbrev Number: 4 (DW_TAG_typedef)
+  <f0>     DW_AT_name        : (indirect string, offset: 0x1ef): _RuneEntry	
+  <f4>     DW_AT_decl_file   : 4	
+  <f5>     DW_AT_decl_line   : 53	
+  <f6>     DW_AT_type        : <a8>	
+ <1><fa>: Abbrev Number: 5 (DW_TAG_structure_type)
+  <fb>     DW_AT_byte_size   : 8	
+  <fc>     DW_AT_decl_file   : 4	
+  <fd>     DW_AT_decl_line   : 55	
+  <fe>     DW_AT_sibling     : <11f>	
+ <2><102>: Abbrev Number: 6 (DW_TAG_member)
+  <103>     DW_AT_name        : (indirect string, offset: 0x264): __nranges	
+  <107>     DW_AT_decl_file   : 4	
+  <108>     DW_AT_decl_line   : 56	
+  <109>     DW_AT_type        : <3d>	
+  <10d>     DW_AT_data_member_location: 2 byte block: 23 0 	(DW_OP_plus_uconst: 0)
+ <2><110>: Abbrev Number: 6 (DW_TAG_member)
+  <111>     DW_AT_name        : (indirect string, offset: 0x34): __ranges	
+  <115>     DW_AT_decl_file   : 4	
+  <116>     DW_AT_decl_line   : 57	
+  <117>     DW_AT_type        : <11f>	
+  <11b>     DW_AT_data_member_location: 2 byte block: 23 4 	(DW_OP_plus_uconst: 4)
+ <1><11f>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <120>     DW_AT_byte_size   : 4	
+  <121>     DW_AT_type        : <ef>	
+ <1><125>: Abbrev Number: 4 (DW_TAG_typedef)
+  <126>     DW_AT_name        : (indirect string, offset: 0x1a3): _RuneRange	
+  <12a>     DW_AT_decl_file   : 4	
+  <12b>     DW_AT_decl_line   : 58	
+  <12c>     DW_AT_type        : <fa>	
+ <1><130>: Abbrev Number: 8 (DW_TAG_structure_type)
+  <131>     DW_AT_byte_size   : 3156	
+  <133>     DW_AT_decl_file   : 4	
+  <134>     DW_AT_decl_line   : 60	
+  <135>     DW_AT_sibling     : <1f7>	
+ <2><139>: Abbrev Number: 6 (DW_TAG_member)
+  <13a>     DW_AT_name        : (indirect string, offset: 0x74): __magic	
+  <13e>     DW_AT_decl_file   : 4	
+  <13f>     DW_AT_decl_line   : 61	
+  <140>     DW_AT_type        : <1f7>	
+  <144>     DW_AT_data_member_location: 2 byte block: 23 0 	(DW_OP_plus_uconst: 0)
+ <2><147>: Abbrev Number: 6 (DW_TAG_member)
+  <148>     DW_AT_name        : (indirect string, offset: 0x279): __encoding	
+  <14c>     DW_AT_decl_file   : 4	
+  <14d>     DW_AT_decl_line   : 62	
+  <14e>     DW_AT_type        : <207>	
+  <152>     DW_AT_data_member_location: 2 byte block: 23 8 	(DW_OP_plus_uconst: 8)
+ <2><155>: Abbrev Number: 6 (DW_TAG_member)
+  <156>     DW_AT_name        : (indirect string, offset: 0x26e): __sgetrune	
+  <15a>     DW_AT_decl_file   : 4	
+  <15b>     DW_AT_decl_line   : 64	
+  <15c>     DW_AT_type        : <242>	
+  <160>     DW_AT_data_member_location: 2 byte block: 23 28 	(DW_OP_plus_uconst: 40)
+ <2><163>: Abbrev Number: 6 (DW_TAG_member)
+  <164>     DW_AT_name        : (indirect string, offset: 0x200): __sputrune	
+  <168>     DW_AT_decl_file   : 4	
+  <169>     DW_AT_decl_line   : 65	
+  <16a>     DW_AT_type        : <273>	
+  <16e>     DW_AT_data_member_location: 2 byte block: 23 2c 	(DW_OP_plus_uconst: 44)
+ <2><171>: Abbrev Number: 6 (DW_TAG_member)
+  <172>     DW_AT_name        : (indirect string, offset: 0xb9): __invalid_rune	
+  <176>     DW_AT_decl_file   : 4	
+  <177>     DW_AT_decl_line   : 66	
+  <178>     DW_AT_type        : <96>	
+  <17c>     DW_AT_data_member_location: 2 byte block: 23 30 	(DW_OP_plus_uconst: 48)
+ <2><17f>: Abbrev Number: 6 (DW_TAG_member)
+  <180>     DW_AT_name        : (indirect string, offset: 0x238): __runetype	
+  <184>     DW_AT_decl_file   : 4	
+  <185>     DW_AT_decl_line   : 68	
+  <186>     DW_AT_type        : <279>	
+  <18a>     DW_AT_data_member_location: 2 byte block: 23 34 	(DW_OP_plus_uconst: 52)
+ <2><18d>: Abbrev Number: 6 (DW_TAG_member)
+  <18e>     DW_AT_name        : (indirect string, offset: 0x259): __maplower	
+  <192>     DW_AT_decl_file   : 4	
+  <193>     DW_AT_decl_line   : 69	
+  <194>     DW_AT_type        : <289>	
+  <198>     DW_AT_data_member_location: 3 byte block: 23 b4 8 	(DW_OP_plus_uconst: 1076)
+ <2><19c>: Abbrev Number: 6 (DW_TAG_member)
+  <19d>     DW_AT_name        : (indirect string, offset: 0x46): __mapupper	
+  <1a1>     DW_AT_decl_file   : 4	
+  <1a2>     DW_AT_decl_line   : 70	
+  <1a3>     DW_AT_type        : <289>	
+  <1a7>     DW_AT_data_member_location: 3 byte block: 23 b4 10 	(DW_OP_plus_uconst: 2100)
+ <2><1ab>: Abbrev Number: 6 (DW_TAG_member)
+  <1ac>     DW_AT_name        : (indirect string, offset: 0x163): __runetype_ext	
+  <1b0>     DW_AT_decl_file   : 4	
+  <1b1>     DW_AT_decl_line   : 77	
+  <1b2>     DW_AT_type        : <125>	
+  <1b6>     DW_AT_data_member_location: 3 byte block: 23 b4 18 	(DW_OP_plus_uconst: 3124)
+ <2><1ba>: Abbrev Number: 6 (DW_TAG_member)
+  <1bb>     DW_AT_name        : (indirect string, offset: 0x20b): __maplower_ext	
+  <1bf>     DW_AT_decl_file   : 4	
+  <1c0>     DW_AT_decl_line   : 78	
+  <1c1>     DW_AT_type        : <125>	
+  <1c5>     DW_AT_data_member_location: 3 byte block: 23 bc 18 	(DW_OP_plus_uconst: 3132)
+ <2><1c9>: Abbrev Number: 6 (DW_TAG_member)
+  <1ca>     DW_AT_name        : (indirect string, offset: 0x1c1): __mapupper_ext	
+  <1ce>     DW_AT_decl_file   : 4	
+  <1cf>     DW_AT_decl_line   : 79	
+  <1d0>     DW_AT_type        : <125>	
+  <1d4>     DW_AT_data_member_location: 3 byte block: 23 c4 18 	(DW_OP_plus_uconst: 3140)
+ <2><1d8>: Abbrev Number: 6 (DW_TAG_member)
+  <1d9>     DW_AT_name        : (indirect string, offset: 0x1de): __variable	
+  <1dd>     DW_AT_decl_file   : 4	
+  <1de>     DW_AT_decl_line   : 81	
+  <1df>     DW_AT_type        : <299>	
+  <1e3>     DW_AT_data_member_location: 3 byte block: 23 cc 18 	(DW_OP_plus_uconst: 3148)
+ <2><1e7>: Abbrev Number: 6 (DW_TAG_member)
+  <1e8>     DW_AT_name        : (indirect string, offset: 0x1b): __variable_len	
+  <1ec>     DW_AT_decl_file   : 4	
+  <1ed>     DW_AT_decl_line   : 82	
+  <1ee>     DW_AT_type        : <3d>	
+  <1f2>     DW_AT_data_member_location: 3 byte block: 23 d0 18 	(DW_OP_plus_uconst: 3152)
+ <1><1f7>: Abbrev Number: 9 (DW_TAG_array_type)
+  <1f8>     DW_AT_type        : <7d>	
+  <1fc>     DW_AT_sibling     : <207>	
+ <2><200>: Abbrev Number: 10 (DW_TAG_subrange_type)
+  <201>     DW_AT_type        : <a1>	
+  <205>     DW_AT_upper_bound : 7	
+ <1><207>: Abbrev Number: 9 (DW_TAG_array_type)
+  <208>     DW_AT_type        : <7d>	
+  <20c>     DW_AT_sibling     : <217>	
+ <2><210>: Abbrev Number: 10 (DW_TAG_subrange_type)
+  <211>     DW_AT_type        : <a1>	
+  <215>     DW_AT_upper_bound : 31	
+ <1><217>: Abbrev Number: 11 (DW_TAG_subroutine_type)
+  <218>     DW_AT_prototyped  : 1	
+  <219>     DW_AT_type        : <96>	
+  <21d>     DW_AT_sibling     : <231>	
+ <2><221>: Abbrev Number: 12 (DW_TAG_formal_parameter)
+  <222>     DW_AT_type        : <231>	
+ <2><226>: Abbrev Number: 12 (DW_TAG_formal_parameter)
+  <227>     DW_AT_type        : <72>	
+ <2><22b>: Abbrev Number: 12 (DW_TAG_formal_parameter)
+  <22c>     DW_AT_type        : <23c>	
+ <1><231>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <232>     DW_AT_byte_size   : 4	
+  <233>     DW_AT_type        : <237>	
+ <1><237>: Abbrev Number: 13 (DW_TAG_const_type)
+  <238>     DW_AT_type        : <7d>	
+ <1><23c>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <23d>     DW_AT_byte_size   : 4	
+  <23e>     DW_AT_type        : <231>	
+ <1><242>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <243>     DW_AT_byte_size   : 4	
+  <244>     DW_AT_type        : <217>	
+ <1><248>: Abbrev Number: 11 (DW_TAG_subroutine_type)
+  <249>     DW_AT_prototyped  : 1	
+  <24a>     DW_AT_type        : <3d>	
+  <24e>     DW_AT_sibling     : <267>	
+ <2><252>: Abbrev Number: 12 (DW_TAG_formal_parameter)
+  <253>     DW_AT_type        : <96>	
+ <2><257>: Abbrev Number: 12 (DW_TAG_formal_parameter)
+  <258>     DW_AT_type        : <267>	
+ <2><25c>: Abbrev Number: 12 (DW_TAG_formal_parameter)
+  <25d>     DW_AT_type        : <72>	
+ <2><261>: Abbrev Number: 12 (DW_TAG_formal_parameter)
+  <262>     DW_AT_type        : <26d>	
+ <1><267>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <268>     DW_AT_byte_size   : 4	
+  <269>     DW_AT_type        : <7d>	
+ <1><26d>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <26e>     DW_AT_byte_size   : 4	
+  <26f>     DW_AT_type        : <267>	
+ <1><273>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <274>     DW_AT_byte_size   : 4	
+  <275>     DW_AT_type        : <248>	
+ <1><279>: Abbrev Number: 9 (DW_TAG_array_type)
+  <27a>     DW_AT_type        : <64>	
+  <27e>     DW_AT_sibling     : <289>	
+ <2><282>: Abbrev Number: 10 (DW_TAG_subrange_type)
+  <283>     DW_AT_type        : <a1>	
+  <287>     DW_AT_upper_bound : 255	
+ <1><289>: Abbrev Number: 9 (DW_TAG_array_type)
+  <28a>     DW_AT_type        : <96>	
+  <28e>     DW_AT_sibling     : <299>	
+ <2><292>: Abbrev Number: 10 (DW_TAG_subrange_type)
+  <293>     DW_AT_type        : <a1>	
+  <297>     DW_AT_upper_bound : 255	
+ <1><299>: Abbrev Number: 14 (DW_TAG_pointer_type)
+  <29a>     DW_AT_byte_size   : 4	
+ <1><29b>: Abbrev Number: 4 (DW_TAG_typedef)
+  <29c>     DW_AT_name        : (indirect string, offset: 0x22c): _RuneLocale	
+  <2a0>     DW_AT_decl_file   : 4	
+  <2a1>     DW_AT_decl_line   : 83	
+  <2a2>     DW_AT_type        : <130>	
+ <1><2a6>: Abbrev Number: 15 (DW_TAG_subprogram)
+  <2a7>     DW_AT_external    : 1	
+  <2a8>     DW_AT_name        : (indirect string, offset: 0x249): fnmatch	
+  <2ac>     DW_AT_decl_file   : 1	
+  <2ad>     DW_AT_decl_line   : 68	
+  <2ae>     DW_AT_prototyped  : 1	
+  <2af>     DW_AT_type        : <3d>	
+  <2b3>     DW_AT_low_pc      : 0	
+  <2b7>     DW_AT_high_pc     : 0x515	
+  <2bb>     DW_AT_frame_base  : 0	(location list)
+  <2bf>     Unknown AT value: 2117: 1	
+  <2c0>     DW_AT_sibling     : <38e>	
+ <2><2c4>: Abbrev Number: 16 (DW_TAG_formal_parameter)
+  <2c5>     DW_AT_name        : (indirect string, offset: 0x13): pattern	
+  <2c9>     DW_AT_decl_file   : 1	
+  <2ca>     DW_AT_decl_line   : 68	
+  <2cb>     DW_AT_type        : <231>	
+  <2cf>     DW_AT_location    : 2 byte block: 91 0 	(DW_OP_fbreg: 0)
+ <2><2d2>: Abbrev Number: 16 (DW_TAG_formal_parameter)
+  <2d3>     DW_AT_name        : (indirect string, offset: 0xad): string	
+  <2d7>     DW_AT_decl_file   : 1	
+  <2d8>     DW_AT_decl_line   : 68	
+  <2d9>     DW_AT_type        : <231>	
+  <2dd>     DW_AT_location    : 2 byte block: 91 4 	(DW_OP_fbreg: 4)
+ <2><2e0>: Abbrev Number: 16 (DW_TAG_formal_parameter)
+  <2e1>     DW_AT_name        : (indirect string, offset: 0x108): flags	
+  <2e5>     DW_AT_decl_file   : 1	
+  <2e6>     DW_AT_decl_line   : 68	
+  <2e7>     DW_AT_type        : <3d>	
+  <2eb>     DW_AT_location    : 2 byte block: 91 8 	(DW_OP_fbreg: 8)
+ <2><2ee>: Abbrev Number: 17 (DW_TAG_variable)
+  <2ef>     DW_AT_name        : p	
+  <2f1>     DW_AT_decl_file   : 1	
+  <2f2>     DW_AT_decl_line   : 70	
+  <2f3>     DW_AT_type        : <231>	
+  <2f7>     DW_AT_location    : 0x9a	(location list)
+ <2><2fb>: Abbrev Number: 17 (DW_TAG_variable)
+  <2fc>     DW_AT_name        : n	
+  <2fe>     DW_AT_decl_file   : 1	
+  <2ff>     DW_AT_decl_line   : 70	
+  <300>     DW_AT_type        : <231>	
+  <304>     DW_AT_location    : 0x1e2	(location list)
+ <2><308>: Abbrev Number: 17 (DW_TAG_variable)
+  <309>     DW_AT_name        : c	
+  <30b>     DW_AT_decl_file   : 1	
+  <30c>     DW_AT_decl_line   : 71	
+  <30d>     DW_AT_type        : <28>	
+  <311>     DW_AT_location    : 0x25a	(location list)
+ <2><315>: Abbrev Number: 18 (DW_TAG_label)
+  <316>     DW_AT_name        : (indirect string, offset: 0x51): matched	
+  <31a>     DW_AT_decl_file   : 1	
+  <31b>     DW_AT_decl_line   : 184	
+ <2><31c>: Abbrev Number: 19 (DW_TAG_lexical_block)
+  <31d>     DW_AT_ranges      : 0	
+  <321>     DW_AT_sibling     : <359>	
+ <3><325>: Abbrev Number: 20 (DW_TAG_variable)
+  <326>     DW_AT_name        : (indirect string, offset: 0x8f): negate	
+  <32a>     DW_AT_decl_file   : 1	
+  <32b>     DW_AT_decl_line   : 127	
+  <32c>     DW_AT_type        : <3d>	
+  <330>     DW_AT_location    : 0x43d	(location list)
+ <3><334>: Abbrev Number: 21 (DW_TAG_lexical_block)
+  <335>     DW_AT_ranges      : 0x38	
+ <4><339>: Abbrev Number: 20 (DW_TAG_variable)
+  <33a>     DW_AT_name        : (indirect string, offset: 0x64): cstart	
+  <33e>     DW_AT_decl_file   : 1	
+  <33f>     DW_AT_decl_line   : 143	
+  <340>     DW_AT_type        : <28>	
+  <344>     DW_AT_location    : 0x497	(location list)
+ <4><348>: Abbrev Number: 20 (DW_TAG_variable)
+  <349>     DW_AT_name        : (indirect string, offset: 0xb4): cend	
+  <34d>     DW_AT_decl_file   : 1	
+  <34e>     DW_AT_decl_line   : 143	
+  <34f>     DW_AT_type        : <28>	
+  <353>     DW_AT_location    : 0x514	(location list)
+ <2><359>: Abbrev Number: 21 (DW_TAG_lexical_block)
+  <35a>     DW_AT_ranges      : 0x78	
+ <3><35e>: Abbrev Number: 17 (DW_TAG_variable)
+  <35f>     DW_AT_name        : c1	
+  <362>     DW_AT_decl_file   : 1	
+  <363>     DW_AT_decl_line   : 115	
+  <364>     DW_AT_type        : <28>	
+  <368>     DW_AT_location    : 0x5d3	(location list)
+ <3><36c>: Abbrev Number: 22 (Unknown TAG value: 4109)
+  <36d>     DW_AT_low_pc      : 0x3b5	
+  <371>     DW_AT_abstract_origin: <2a6>	
+ <4><375>: Abbrev Number: 23 (Unknown TAG value: 410a)
+  <376>     DW_AT_location    : 2 byte block: 74 0 	(DW_OP_breg4: 0)
+  <379>     Unknown AT value: 2111: 2 byte block: 75 0 	
+ <4><37c>: Abbrev Number: 23 (Unknown TAG value: 410a)
+  <37d>     DW_AT_location    : 2 byte block: 74 4 	(DW_OP_breg4: 4)
+  <380>     Unknown AT value: 2111: 2 byte block: 73 0 	
+ <4><383>: Abbrev Number: 23 (Unknown TAG value: 410a)
+  <384>     DW_AT_location    : 2 byte block: 74 8 	(DW_OP_breg4: 8)
+  <387>     Unknown AT value: 2111: 3 byte block: 91 48 6 	
+ <1><38e>: Abbrev Number: 9 (DW_TAG_array_type)
+  <38f>     DW_AT_type        : <28>	
+  <393>     DW_AT_sibling     : <39e>	
+ <2><397>: Abbrev Number: 10 (DW_TAG_subrange_type)
+  <398>     DW_AT_type        : <a1>	
+  <39c>     DW_AT_upper_bound : 255	
+ <1><39e>: Abbrev Number: 24 (DW_TAG_variable)
+  <39f>     DW_AT_name        : (indirect string, offset: 0x125): _sch_tolower	
+  <3a3>     DW_AT_decl_file   : 5	
+  <3a4>     DW_AT_decl_line   : 111	
+  <3a5>     DW_AT_type        : <3ab>	
+  <3a9>     DW_AT_external    : 1	
+  <3aa>     DW_AT_declaration : 1	
+ <1><3ab>: Abbrev Number: 13 (DW_TAG_const_type)
+  <3ac>     DW_AT_type        : <38e>	
+ <1><3b0>: Abbrev Number: 24 (DW_TAG_variable)
+  <3b1>     DW_AT_name        : (indirect string, offset: 0xee): __mb_sb_limit	
+  <3b5>     DW_AT_decl_file   : 6	
+  <3b6>     DW_AT_decl_line   : 86	
+  <3b7>     DW_AT_type        : <3d>	
+  <3bb>     DW_AT_external    : 1	
+  <3bc>     DW_AT_declaration : 1	
+ <1><3bd>: Abbrev Number: 24 (DW_TAG_variable)
+  <3be>     DW_AT_name        : (indirect string, offset: 0x0): _DefaultRuneLocale	
+  <3c2>     DW_AT_decl_file   : 4	
+  <3c3>     DW_AT_decl_line   : 87	
+  <3c4>     DW_AT_type        : <29b>	
+  <3c8>     DW_AT_external    : 1	
+  <3c9>     DW_AT_declaration : 1	
+ <1><3ca>: Abbrev Number: 24 (DW_TAG_variable)
+  <3cb>     DW_AT_name        : (indirect string, offset: 0x7c): _CurrentRuneLocale	
+  <3cf>     DW_AT_decl_file   : 4	
+  <3d0>     DW_AT_decl_line   : 88	
+  <3d1>     DW_AT_type        : <3d7>	
+  <3d5>     DW_AT_external    : 1	
+  <3d6>     DW_AT_declaration : 1	
+ <1><3d7>: Abbrev Number: 7 (DW_TAG_pointer_type)
+  <3d8>     DW_AT_byte_size   : 4	
+  <3d9>     DW_AT_type        : <29b>	
+ <1><3dd>: Abbrev Number: 24 (DW_TAG_variable)
+  <3de>     DW_AT_name        : (indirect string, offset: 0x125): _sch_tolower	
+  <3e2>     DW_AT_decl_file   : 5	
+  <3e3>     DW_AT_decl_line   : 111	
+  <3e4>     DW_AT_type        : <3ea>	
+  <3e8>     DW_AT_external    : 1	
+  <3e9>     DW_AT_declaration : 1	
+ <1><3ea>: Abbrev Number: 13 (DW_TAG_const_type)
+  <3eb>     DW_AT_type        : <38e>	
+ <1><3ef>: Abbrev Number: 24 (DW_TAG_variable)
+  <3f0>     DW_AT_name        : (indirect string, offset: 0xee): __mb_sb_limit	
+  <3f4>     DW_AT_decl_file   : 6	
+  <3f5>     DW_AT_decl_line   : 86	
+  <3f6>     DW_AT_type        : <3d>	
+  <3fa>     DW_AT_external    : 1	
+  <3fb>     DW_AT_declaration : 1	
+ <1><3fc>: Abbrev Number: 24 (DW_TAG_variable)
+  <3fd>     DW_AT_name        : (indirect string, offset: 0x0): _DefaultRuneLocale	
+  <401>     DW_AT_decl_file   : 4	
+  <402>     DW_AT_decl_line   : 87	
+  <403>     DW_AT_type        : <29b>	
+  <407>     DW_AT_external    : 1	
+  <408>     DW_AT_declaration : 1	
+ <1><409>: Abbrev Number: 24 (DW_TAG_variable)
+  <40a>     DW_AT_name        : (indirect string, offset: 0x7c): _CurrentRuneLocale	
+  <40e>     DW_AT_decl_file   : 4	
+  <40f>     DW_AT_decl_line   : 88	
+  <410>     DW_AT_type        : <3d7>	
+  <414>     DW_AT_external    : 1	
+  <415>     DW_AT_declaration : 1	
+
+Contents of the .debug_abbrev section:
+
+  Number TAG
+   1      DW_TAG_compile_unit    [has children]
+    DW_AT_producer     DW_FORM_strp
+    DW_AT_language     DW_FORM_data1
+    DW_AT_name         DW_FORM_strp
+    DW_AT_low_pc       DW_FORM_addr
+    DW_AT_high_pc      DW_FORM_addr
+    DW_AT_stmt_list    DW_FORM_data4
+   2      DW_TAG_base_type    [no children]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_encoding     DW_FORM_data1
+    DW_AT_name         DW_FORM_strp
+   3      DW_TAG_base_type    [no children]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_encoding     DW_FORM_data1
+    DW_AT_name         DW_FORM_string
+   4      DW_TAG_typedef    [no children]
+    DW_AT_name         DW_FORM_strp
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+   5      DW_TAG_structure_type    [has children]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_sibling      DW_FORM_ref4
+   6      DW_TAG_member    [no children]
+    DW_AT_name         DW_FORM_strp
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_data_member_location DW_FORM_block1
+   7      DW_TAG_pointer_type    [no children]
+    DW_AT_byte_size    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+   8      DW_TAG_structure_type    [has children]
+    DW_AT_byte_size    DW_FORM_data2
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_sibling      DW_FORM_ref4
+   9      DW_TAG_array_type    [has children]
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_sibling      DW_FORM_ref4
+   10      DW_TAG_subrange_type    [no children]
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_upper_bound  DW_FORM_data1
+   11      DW_TAG_subroutine_type    [has children]
+    DW_AT_prototyped   DW_FORM_flag
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_sibling      DW_FORM_ref4
+   12      DW_TAG_formal_parameter    [no children]
+    DW_AT_type         DW_FORM_ref4
+   13      DW_TAG_const_type    [no children]
+    DW_AT_type         DW_FORM_ref4
+   14      DW_TAG_pointer_type    [no children]
+    DW_AT_byte_size    DW_FORM_data1
+   15      DW_TAG_subprogram    [has children]
+    DW_AT_external     DW_FORM_flag
+    DW_AT_name         DW_FORM_strp
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_prototyped   DW_FORM_flag
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_low_pc       DW_FORM_addr
+    DW_AT_high_pc      DW_FORM_addr
+    DW_AT_frame_base   DW_FORM_data4
+    Unknown AT value: 2117 DW_FORM_flag
+    DW_AT_sibling      DW_FORM_ref4
+   16      DW_TAG_formal_parameter    [no children]
+    DW_AT_name         DW_FORM_strp
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_location     DW_FORM_block1
+   17      DW_TAG_variable    [no children]
+    DW_AT_name         DW_FORM_string
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_location     DW_FORM_data4
+   18      DW_TAG_label    [no children]
+    DW_AT_name         DW_FORM_strp
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+   19      DW_TAG_lexical_block    [has children]
+    DW_AT_ranges       DW_FORM_data4
+    DW_AT_sibling      DW_FORM_ref4
+   20      DW_TAG_variable    [no children]
+    DW_AT_name         DW_FORM_strp
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_location     DW_FORM_data4
+   21      DW_TAG_lexical_block    [has children]
+    DW_AT_ranges       DW_FORM_data4
+   22      Unknown TAG value: 4109    [has children]
+    DW_AT_low_pc       DW_FORM_addr
+    DW_AT_abstract_origin DW_FORM_ref4
+   23      Unknown TAG value: 410a    [no children]
+    DW_AT_location     DW_FORM_block1
+    Unknown AT value: 2111 DW_FORM_block1
+   24      DW_TAG_variable    [no children]
+    DW_AT_name         DW_FORM_strp
+    DW_AT_decl_file    DW_FORM_data1
+    DW_AT_decl_line    DW_FORM_data1
+    DW_AT_type         DW_FORM_ref4
+    DW_AT_external     DW_FORM_flag
+    DW_AT_declaration  DW_FORM_flag
+
+Contents of the .debug_loc section:
+
+    Offset   Begin    End      Expression
+    00000000 00000000 00000001 (DW_OP_breg4: 4)
+    00000000 00000001 00000002 (DW_OP_breg4: 8)
+    00000000 00000002 00000003 (DW_OP_breg4: 12)
+    00000000 00000003 00000004 (DW_OP_breg4: 16)
+    00000000 00000004 00000007 (DW_OP_breg4: 20)
+    00000000 00000007 000000f8 (DW_OP_breg4: 96)
+    00000000 000000f8 000000f9 (DW_OP_breg4: 20)
+    00000000 000000f9 000000fa (DW_OP_breg4: 16)
+    00000000 000000fa 000000fb (DW_OP_breg4: 12)
+    00000000 000000fb 000000fc (DW_OP_breg4: 8)
+    00000000 000000fc 00000100 (DW_OP_breg4: 4)
+    00000000 00000100 00000515 (DW_OP_breg4: 96)
+    00000000 <End of list>
+    0000009a 0000000b 0000000e (DW_OP_fbreg: 0)
+    0000009a 0000000e 00000055 (DW_OP_fbreg: 0; DW_OP_deref; DW_OP_plus_uconst: 1; (Unknown location op))
+    0000009a 00000055 0000008b (DW_OP_fbreg: -56)
+    0000009a 0000008b 00000098 (DW_OP_reg2)
+    0000009a 00000098 0000009c (DW_OP_reg7)
+    0000009a 000000b8 000000d9 (DW_OP_fbreg: -56)
+    0000009a 000000d9 000000dd (DW_OP_reg7)
+    0000009a 000000dd 000000ee (DW_OP_fbreg: -56)
+    0000009a 000000fd 000001a4 (DW_OP_fbreg: -56)
+    0000009a 000001a4 000001c1 (DW_OP_reg2)
+    0000009a 000001c1 000001e7 (DW_OP_reg7)
+    0000009a 000001e7 00000287 (DW_OP_reg2)
+    0000009a 00000287 00000293 (DW_OP_breg7: 2; (Unknown location op))
+    0000009a 00000293 000002b9 (DW_OP_reg2)
+    0000009a 000002b9 000002d2 (DW_OP_fbreg: -56)
+    0000009a 000002d2 00000355 (DW_OP_reg2)
+    0000009a 00000355 000003c5 (DW_OP_reg5)
+    0000009a 000003c5 000003d7 (DW_OP_breg7: 2; (Unknown location op))
+    0000009a 000003d7 000003dc (DW_OP_reg2)
+    0000009a 000003dc 00000447 (DW_OP_fbreg: -56)
+    0000009a 00000447 00000482 (DW_OP_reg2)
+    0000009a 00000482 0000049c (DW_OP_fbreg: -56)
+    0000009a 0000049c 000004a7 (DW_OP_reg2)
+    0000009a 000004a7 000004cc (DW_OP_fbreg: -56)
+    0000009a 000004cc 000004e5 (DW_OP_reg2)
+    0000009a 000004e5 000004ee (DW_OP_fbreg: 0; DW_OP_deref; DW_OP_plus_uconst: 1; (Unknown location op))
+    0000009a 000004ee 00000515 (DW_OP_reg2)
+    0000009a <End of list>
+    000001e2 00000007 00000055 (DW_OP_fbreg: 4)
+    000001e2 00000055 0000009c (DW_OP_reg3)
+    000001e2 000000b8 000000ee (DW_OP_reg3)
+    000001e2 000000fd 000002d2 (DW_OP_reg3)
+    000001e2 000002ed 000002f2 (DW_OP_reg3)
+    000001e2 00000316 00000320 (DW_OP_reg3)
+    000001e2 00000355 0000049c (DW_OP_reg3)
+    000001e2 000004a7 000004e5 (DW_OP_reg3)
+    000001e2 000004e5 000004ee (DW_OP_fbreg: 4)
+    000001e2 000004fc 00000515 (DW_OP_reg3)
+    000001e2 <End of list>
+    0000025a 0000000e 00000055 (DW_OP_fbreg: 0; DW_OP_deref)
+    0000025a 00000055 0000007d (DW_OP_reg0)
+    0000025a 0000007d 0000008b (DW_OP_reg2)
+    0000025a 00000091 0000009c (DW_OP_breg2: 0)
+    0000025a 0000009c 000000a1 (DW_OP_reg0)
+    0000025a 000000b8 000000c8 (DW_OP_reg0)
+    0000025a 000000d0 000000e3 (DW_OP_breg2: 1)
+    0000025a 000000fd 00000103 (DW_OP_reg0)
+    0000025a 00000149 0000015d (DW_OP_reg0)
+    0000025a 000001a1 000001b0 (DW_OP_fbreg: -56; DW_OP_deref)
+    0000025a 000001b0 000001e4 (DW_OP_reg0)
+    0000025a 000001e4 000001f3 (DW_OP_breg7: 0)
+    0000025a 000001f3 000002b1 (DW_OP_reg0)
+    0000025a 000002b1 000002b4 (DW_OP_breg2: 0)
+    0000025a 000002b4 000002b9 (DW_OP_breg2: -1)
+    0000025a 000002b9 000002cb (DW_OP_reg0)
+    0000025a 000002cf 000002d2 (DW_OP_breg2: 1)
+    0000025a 000002d2 000002e4 (DW_OP_breg2: -1)
+    0000025a 000002e4 000002e7 (DW_OP_reg1)
+    0000025a 000002e7 000002ed (DW_OP_breg2: 0)
+    0000025a 000002ed 000002f2 (DW_OP_breg2: -1)
+    0000025a 000002f2 00000310 (DW_OP_reg1)
+    0000025a 00000310 00000316 (DW_OP_breg2: 0)
+    0000025a 00000316 0000031b (DW_OP_breg2: -1)
+    0000025a 0000031b 00000378 (DW_OP_reg1)
+    0000025a 000003c5 000003dc (DW_OP_reg0)
+    0000025a 000003dc 00000400 (DW_OP_const1u: 92; (Unknown location op))
+    0000025a 00000400 00000412 (DW_OP_reg0)
+    0000025a 00000432 0000043e (DW_OP_reg2)
+    0000025a 0000044c 00000460 (DW_OP_reg0)
+    0000025a 00000463 00000468 (DW_OP_breg2: 0)
+    0000025a 00000468 00000476 (DW_OP_breg1: 0)
+    0000025a 00000476 00000478 (DW_OP_const1u: 92; (Unknown location op))
+    0000025a 00000478 00000482 (DW_OP_reg0)
+    0000025a 00000482 0000048c (DW_OP_breg7: 0)
+    0000025a 0000048c 0000049c (DW_OP_reg7)
+    0000025a 0000049c 000004a7 (DW_OP_reg1)
+    0000025a 000004cc 000004e5 (DW_OP_reg0)
+    0000025a 000004e5 000004ee (DW_OP_fbreg: 0; DW_OP_deref)
+    0000025a 000004ee 000004fc (DW_OP_reg1)
+    0000025a 000004fc 00000504 (DW_OP_reg0)
+    0000025a <End of list>
+    0000043d 00000187 000001a1 (DW_OP_reg0)
+    0000043d 000001a1 000002b9 (DW_OP_fbreg: -40)
+    0000043d 000003c5 000003dc (DW_OP_fbreg: -40)
+    0000043d 0000043e 0000044c (DW_OP_reg0)
+    0000043d 0000044c 00000482 (DW_OP_fbreg: -40)
+    0000043d 000004cc 000004e5 (DW_OP_fbreg: -40)
+    0000043d 000004fc 00000515 (DW_OP_fbreg: -40)
+    0000043d <End of list>
+    00000497 000001b0 000001bb (DW_OP_reg0)
+    00000497 000001bb 000001c1 (DW_OP_breg2: 0)
+    00000497 000001c1 000001cc (DW_OP_reg1)
+    00000497 000001cc 0000023c (DW_OP_fbreg: -61)
+    00000497 0000023c 0000024d (DW_OP_reg0)
+    00000497 0000024d 000002b9 (DW_OP_fbreg: -61)
+    00000497 000003c5 000003dc (DW_OP_fbreg: -61)
+    00000497 0000044c 00000482 (DW_OP_fbreg: -61)
+    00000497 000004cc 000004e5 (DW_OP_fbreg: -61)
+    00000497 000004fc 00000515 (DW_OP_fbreg: -61)
+    00000497 <End of list>
+    00000514 000001b0 000001bb (DW_OP_reg0)
+    00000514 000001bb 000001c1 (DW_OP_breg2: 0)
+    00000514 000001c1 000001c9 (DW_OP_reg1)
+    00000514 000001cc 00000204 (DW_OP_fbreg: -61)
+    00000514 00000204 0000022e (DW_OP_reg5)
+    00000514 0000023c 0000024d (DW_OP_reg0)
+    00000514 0000024d 00000267 (DW_OP_reg5)
+    00000514 00000278 00000287 (DW_OP_fbreg: -61)
+    00000514 00000287 00000293 (DW_OP_breg7: 1)
+    00000514 00000293 0000029d (DW_OP_reg5)
+    00000514 0000029d 000002ae (DW_OP_reg1)
+    00000514 000002ae 000002b9 (DW_OP_reg5)
+    00000514 000003c5 000003d4 (DW_OP_reg1)
+    00000514 000003d4 000003dc (DW_OP_breg7: 2)
+    00000514 00000478 00000482 (DW_OP_fbreg: -61)
+    00000514 000004cc 000004e5 (DW_OP_fbreg: -61)
+    00000514 <End of list>
+    000005d3 00000341 0000034b (DW_OP_reg7)
+    000005d3 00000352 0000036f (DW_OP_reg7)
+    000005d3 <End of list>
+The section .debug_aranges contains:
+
+  Length:                   28
+  Version:                  2
+  Offset into .debug_info:  0
+  Pointer Size:             4
+  Segment Size:             0
+
+    Address    Length
+    0x00000000 0x515
+    0x00000000 0x0
+
+Contents of the .debug_ranges section:
+
+    Offset   Begin    End
+    00000000 00000042 00000055
+    00000000 00000150 000002c0
+    00000000 000003c5 000003e0
+    00000000 00000440 00000482
+    00000000 000004a7 000004e5
+    00000000 00000500 00000515
+    00000000 <End of list>
+    00000038 00000042 00000055
+    00000038 00000191 0000019e
+    00000038 000001b0 00000267
+    00000038 00000278 000002c0
+    00000038 000003c5 000003e0
+    00000038 00000478 00000482
+    00000038 000004d0 000004e5
+    00000038 <End of list>
+    00000078 0000032a 000003c5
+    00000078 000004a0 000004a7
+    00000078 <End of list>
+
+
+Dump of debug contents of section .debug_line:
+
+  Length:                      501
+  DWARF Version:               2
+  Prologue Length:             238
+  Minimum Instruction Length:  1
+  Initial value of 'is_stmt':  1
+  Line Base:                   -5
+  Line Range:                  14
+  Opcode Base:                 13
+
+ Opcodes:
+  Opcode 1 has 0 args
+  Opcode 2 has 1 args
+  Opcode 3 has 1 args
+  Opcode 4 has 1 args
+  Opcode 5 has 1 args
+  Opcode 6 has 0 args
+  Opcode 7 has 0 args
+  Opcode 8 has 0 args
+  Opcode 9 has 1 args
+  Opcode 10 has 0 args
+  Opcode 11 has 0 args
+  Opcode 12 has 1 args
+
+ The Directory Table:
+  /scratch/tmp/gerald/gcc-HEAD/libiberty
+  /usr/include/machine
+  /usr/include/sys
+  /usr/include
+  /scratch/tmp/gerald/gcc-HEAD/libiberty/../include
+
+ The File Name Table:
+  Entry	Dir	Time	Size	Name
+  1	1	0	0	fnmatch.c
+  2	2	0	0	_types.h
+  3	3	0	0	_types.h
+  4	4	0	0	runetype.h
+  5	5	0	0	safe-ctype.h
+  6	4	0	0	_ctype.h
+
+ Line Number Statements:
+  Extended opcode 2: set Address to 0x0
+  Advance Line by 68 to 69
+  Copy
+  Special opcode 103: advance Address by 7 to 0x7 and Line by 0 to 69
+  Special opcode 67: advance Address by 4 to 0xb and Line by 6 to 75
+  Advance Line by 9 to 84
+  Special opcode 201: advance Address by 14 to 0x19 and Line by 0 to 84
+  Advance Line by -9 to 75
+  Special opcode 61: advance Address by 4 to 0x1d and Line by 0 to 75
+  Advance Line by 11 to 86
+  Special opcode 61: advance Address by 4 to 0x21 and Line by 0 to 86
+  Advance Line by -11 to 75
+  Special opcode 117: advance Address by 8 to 0x29 and Line by 0 to 75
+  Advance Line by 9 to 84
+  Special opcode 61: advance Address by 4 to 0x2d and Line by 0 to 84
+  Special opcode 49: advance Address by 3 to 0x30 and Line by 2 to 86
+  Special opcode 45: advance Address by 3 to 0x33 and Line by -2 to 84
+  Special opcode 161: advance Address by 11 to 0x3e and Line by 2 to 86
+  Advance Line by 71 to 157
+  Special opcode 61: advance Address by 4 to 0x42 and Line by 0 to 157
+  Advance Line by -80 to 77
+  Advance PC by constant 17 to 0x53
+  Special opcode 33: advance Address by 2 to 0x55 and Line by 0 to 77
+  Special opcode 203: advance Address by 14 to 0x63 and Line by 2 to 79
+  Advance Line by 124 to 203
+  Advance PC by constant 17 to 0x74
+  Special opcode 19: advance Address by 1 to 0x75 and Line by 0 to 203
+  Advance Line by -128 to 75
+  Advance PC by constant 17 to 0x86
+  Special opcode 75: advance Address by 5 to 0x8b and Line by 0 to 75
+  Advance Line by 132 to 207
+  Special opcode 47: advance Address by 3 to 0x8e and Line by 0 to 207
+  Advance Line by -132 to 75
+  Special opcode 47: advance Address by 3 to 0x91 and Line by 0 to 75
+  Advance Line by 135 to 210
+  Special opcode 159: advance Address by 11 to 0x9c and Line by 0 to 210
+  Special opcode 48: advance Address by 3 to 0x9f and Line by 1 to 211
+  Special opcode 32: advance Address by 2 to 0xa1 and Line by -1 to 210
+  Special opcode 64: advance Address by 4 to 0xa5 and Line by 3 to 213
+  Special opcode 79: advance Address by 5 to 0xaa and Line by 4 to 217
+  Special opcode 29: advance Address by 2 to 0xac and Line by -4 to 213
+  Advance Line by -130 to 83
+  Special opcode 33: advance Address by 2 to 0xae and Line by 0 to 83
+  Special opcode 141: advance Address by 10 to 0xb8 and Line by -4 to 79
+  Advance Line by 13 to 92
+  Special opcode 173: advance Address by 12 to 0xc4 and Line by 0 to 92
+  Special opcode 175: advance Address by 12 to 0xd0 and Line by 2 to 94
+  Special opcode 48: advance Address by 3 to 0xd3 and Line by 1 to 95
+  Special opcode 32: advance Address by 2 to 0xd5 and Line by -1 to 94
+  Special opcode 118: advance Address by 8 to 0xdd and Line by 1 to 95
+  Special opcode 91: advance Address by 6 to 0xe3 and Line by 2 to 97
+  Advance Line by 107 to 204
+  Special opcode 187: advance Address by 13 to 0xf0 and Line by 0 to 204
+  Advance Line by 14 to 218
+  Special opcode 75: advance Address by 5 to 0xf5 and Line by 0 to 218
+  Advance Line by -136 to 82
+  Special opcode 159: advance Address by 11 to 0x100 and Line by 0 to 82
+  Special opcode 105: advance Address by 7 to 0x107 and Line by 2 to 84
+  Special opcode 175: advance Address by 12 to 0x113 and Line by 2 to 86
+  Advance PC by constant 17 to 0x124
+  Special opcode 188: advance Address by 13 to 0x131 and Line by 1 to 87
+  Advance Line by 42 to 129
+  Advance PC by constant 17 to 0x142
+  Special opcode 201: advance Address by 14 to 0x150 and Line by 0 to 129
+  Special opcode 134: advance Address by 9 to 0x159 and Line by 3 to 132
+  Advance PC by constant 17 to 0x16a
+  Special opcode 9: advance Address by 0 to 0x16a and Line by 4 to 136
+  Advance PC by constant 17 to 0x17b
+  Special opcode 90: advance Address by 6 to 0x181 and Line by 1 to 137
+  Special opcode 32: advance Address by 2 to 0x183 and Line by -1 to 136
+  Special opcode 62: advance Address by 4 to 0x187 and Line by 1 to 137
+  Special opcode 92: advance Address by 6 to 0x18d and Line by 3 to 140
+  Advance Line by 33 to 173
+  Special opcode 61: advance Address by 4 to 0x191 and Line by 0 to 173
+  Advance Line by -33 to 140
+  Special opcode 187: advance Address by 13 to 0x19e and Line by 0 to 140
+  Advance PC by constant 17 to 0x1af
+  Special opcode 24: advance Address by 1 to 0x1b0 and Line by 5 to 145
+  Special opcode 160: advance Address by 11 to 0x1bb and Line by 1 to 146
+  Special opcode 91: advance Address by 6 to 0x1c1 and Line by 2 to 148
+  Advance PC by constant 17 to 0x1d2
+  Special opcode 77: advance Address by 5 to 0x1d7 and Line by 2 to 150
+  Special opcode 122: advance Address by 8 to 0x1df and Line by 5 to 155
+  Special opcode 32: advance Address by 2 to 0x1e1 and Line by -1 to 154
+  Special opcode 90: advance Address by 6 to 0x1e7 and Line by 1 to 155
+  Special opcode 175: advance Address by 12 to 0x1f3 and Line by 2 to 157
+  Special opcode 121: advance Address by 8 to 0x1fb and Line by 4 to 161
+  Advance Line by -13 to 148
+  Special opcode 33: advance Address by 2 to 0x1fd and Line by 0 to 148
+  Advance Line by 13 to 161
+  Special opcode 75: advance Address by 5 to 0x202 and Line by 0 to 161
+  Advance Line by 12 to 173
+  Special opcode 33: advance Address by 2 to 0x204 and Line by 0 to 173
+  Advance PC by 36 to 0x228
+  Special opcode 6: advance Address by 0 to 0x228 and Line by 1 to 174
+  Special opcode 232: advance Address by 16 to 0x238 and Line by 3 to 177
+  Advance Line by -32 to 145
+  Special opcode 61: advance Address by 4 to 0x23c and Line by 0 to 145
+  Advance Line by 28 to 173
+  Advance PC by constant 17 to 0x24d
+  Special opcode 47: advance Address by 3 to 0x250 and Line by 0 to 173
+  Advance PC by constant 17 to 0x261
+  Special opcode 37: advance Address by 2 to 0x263 and Line by 4 to 177
+  Special opcode 64: advance Address by 4 to 0x267 and Line by 3 to 180
+  Advance Line by -19 to 161
+  Advance PC by constant 17 to 0x278
+  Special opcode 5: advance Address by 0 to 0x278 and Line by 0 to 161
+  Special opcode 218: advance Address by 15 to 0x287 and Line by 3 to 164
+  Special opcode 130: advance Address by 9 to 0x290 and Line by -1 to 163
+  Special opcode 50: advance Address by 3 to 0x293 and Line by 3 to 166
+  Special opcode 147: advance Address by 10 to 0x29d and Line by 2 to 168
+  Advance PC by constant 17 to 0x2ae
+  Special opcode 7: advance Address by 0 to 0x2ae and Line by 2 to 170
+  Advance Line by -68 to 102
+  Advance PC by constant 17 to 0x2bf
+  Special opcode 19: advance Address by 1 to 0x2c0 and Line by 0 to 102
+  Special opcode 163: advance Address by 11 to 0x2cb and Line by 4 to 106
+  Advance PC by 39 to 0x2f2
+  Special opcode 6: advance Address by 0 to 0x2f2 and Line by 1 to 107
+  Advance PC by constant 17 to 0x303
+  Special opcode 20: advance Address by 1 to 0x304 and Line by 1 to 108
+  Special opcode 129: advance Address by 9 to 0x30d and Line by -2 to 106
+  Advance PC by constant 17 to 0x31e
+  Special opcode 39: advance Address by 2 to 0x320 and Line by 6 to 112
+  Special opcode 32: advance Address by 2 to 0x322 and Line by -1 to 111
+  Special opcode 121: advance Address by 8 to 0x32a and Line by 4 to 115
+  Advance PC by constant 17 to 0x33b
+  Special opcode 90: advance Address by 6 to 0x341 and Line by 1 to 116
+  Advance PC by constant 17 to 0x352
+  Special opcode 6: advance Address by 0 to 0x352 and Line by 1 to 117
+  Special opcode 93: advance Address by 6 to 0x358 and Line by 4 to 121
+  Special opcode 71: advance Address by 5 to 0x35d and Line by -4 to 117
+  Special opcode 119: advance Address by 8 to 0x365 and Line by 2 to 119
+  Special opcode 60: advance Address by 4 to 0x369 and Line by -1 to 118
+  Special opcode 90: advance Address by 6 to 0x36f and Line by 1 to 119
+  Special opcode 129: advance Address by 9 to 0x378 and Line by -2 to 117
+  Special opcode 202: advance Address by 14 to 0x386 and Line by 1 to 118
+  Advance PC by constant 17 to 0x397
+  Special opcode 90: advance Address by 6 to 0x39d and Line by 1 to 119
+  Advance PC by constant 17 to 0x3ae
+  Special opcode 102: advance Address by 7 to 0x3b5 and Line by -1 to 118
+  Special opcode 133: advance Address by 9 to 0x3be and Line by 2 to 120
+  Advance Line by 44 to 164
+  Special opcode 103: advance Address by 7 to 0x3c5 and Line by 0 to 164
+  Special opcode 160: advance Address by 11 to 0x3d0 and Line by 1 to 165
+  Advance Line by -68 to 97
+  Special opcode 229: advance Address by 16 to 0x3e0 and Line by 0 to 97
+  Advance PC by constant 17 to 0x3f1
+  Special opcode 220: advance Address by 15 to 0x400 and Line by 5 to 102
+  Special opcode 189: advance Address by 13 to 0x40d and Line by 2 to 104
+  Special opcode 73: advance Address by 5 to 0x412 and Line by -2 to 102
+  Special opcode 90: advance Address by 6 to 0x418 and Line by 1 to 103
+  Advance Line by 100 to 203
+  Advance PC by constant 17 to 0x429
+  Special opcode 131: advance Address by 9 to 0x432 and Line by 0 to 203
+  Advance Line by -65 to 138
+  Special opcode 201: advance Address by 14 to 0x440 and Line by 0 to 138
+  Advance Line by 48 to 186
+  Special opcode 229: advance Address by 16 to 0x450 and Line by 0 to 186
+  Special opcode 119: advance Address by 8 to 0x458 and Line by 2 to 188
+  Special opcode 121: advance Address by 8 to 0x460 and Line by 4 to 192
+  Special opcode 43: advance Address by 3 to 0x463 and Line by -4 to 188
+  Special opcode 37: advance Address by 2 to 0x465 and Line by 4 to 192
+  Special opcode 48: advance Address by 3 to 0x468 and Line by 1 to 193
+  Special opcode 161: advance Address by 11 to 0x473 and Line by 2 to 195
+  Advance Line by -47 to 148
+  Special opcode 75: advance Address by 5 to 0x478 and Line by 0 to 148
+  Advance Line by -51 to 97
+  Special opcode 145: advance Address by 10 to 0x482 and Line by 0 to 97
+  Advance Line by 18 to 115
+  Advance PC by constant 17 to 0x493
+  Special opcode 187: advance Address by 13 to 0x4a0 and Line by 0 to 115
+  Advance Line by 17 to 132
+  Special opcode 103: advance Address by 7 to 0x4a7 and Line by 0 to 132
+  Special opcode 146: advance Address by 10 to 0x4b1 and Line by 1 to 133
+  Advance Line by 24 to 157
+  Advance PC by constant 17 to 0x4c2
+  Special opcode 201: advance Address by 14 to 0x4d0 and Line by 0 to 157
+  Advance Line by -82 to 75
+  Advance PC by constant 17 to 0x4e1
+  Special opcode 61: advance Address by 4 to 0x4e5 and Line by 0 to 75
+  Advance Line by 31 to 106
+  Special opcode 131: advance Address by 9 to 0x4ee and Line by 0 to 106
+  Advance Line by 91 to 197
+  Advance PC by constant 17 to 0x4ff
+  Special opcode 19: advance Address by 1 to 0x500 and Line by 0 to 197
+  Advance PC by 21 to 0x515
+  Extended opcode 1: End of Sequence
+
+
+Contents of the .debug_str section:
+
+  0x00000000 5f446566 61756c74 52756e65 4c6f6361 _DefaultRuneLoca
+  0x00000010 6c650070 61747465 726e005f 5f766172 le.pattern.__var
+  0x00000020 6961626c 655f6c65 6e007368 6f727420 iable_len.short 
+  0x00000030 696e7400 5f5f7261 6e676573 0073697a int.__ranges.siz
+  0x00000040 65747970 65005f5f 6d617075 70706572 etype.__mapupper
+  0x00000050 006d6174 63686564 005f5f75 696e7433 .matched.__uint3
+  0x00000060 325f7400 63737461 7274005f 5f72756e 2_t.cstart.__run
+  0x00000070 655f7400 5f5f6d61 67696300 5f437572 e_t.__magic._Cur
+  0x00000080 72656e74 52756e65 4c6f6361 6c65006e rentRuneLocale.n
+  0x00000090 65676174 65006c6f 6e67206c 6f6e6720 egate.long long 
+  0x000000a0 696e7400 6c6f6e67 20696e74 00737472 int.long int.str
+  0x000000b0 696e6700 63656e64 005f5f69 6e76616c ing.cend.__inval
+  0x000000c0 69645f72 756e6500 6c6f6e67 20646f75 id_rune.long dou
+  0x000000d0 626c6500 5f5f6374 5f72756e 655f7400 ble.__ct_rune_t.
+  0x000000e0 756e7369 676e6564 20636861 72005f5f unsigned char.__
+  0x000000f0 6d625f73 625f6c69 6d697400 7369676e mb_sb_limit.sign
+  0x00000100 65642063 68617200 666c6167 73006c6f ed char.flags.lo
+  0x00000110 6e67206c 6f6e6720 756e7369 676e6564 ng long unsigned
+  0x00000120 20696e74 005f7363 685f746f 6c6f7765  int._sch_tolowe
+  0x00000130 7200756e 7369676e 65642069 6e740047 r.unsigned int.G
+  0x00000140 4e552043 20342e37 2e302032 30313130 NU C 4.7.0 20110
+  0x00000150 38323320 28657870 6572696d 656e7461 823 (experimenta
+  0x00000160 6c29005f 5f72756e 65747970 655f6578 l).__runetype_ex
+  0x00000170 74002f73 63726174 63682f74 6d702f67 t./scratch/tmp/g
+  0x00000180 6572616c 642f6763 632d4845 41442f6c erald/gcc-HEAD/l
+  0x00000190 69626962 65727479 2f666e6d 61746368 ibiberty/fnmatch
+  0x000001a0 2e63005f 52756e65 52616e67 65007368 .c._RuneRange.sh
+  0x000001b0 6f727420 756e7369 676e6564 20696e74 ort unsigned int
+  0x000001c0 005f5f6d 61707570 7065725f 65787400 .__mapupper_ext.
+  0x000001d0 63686172 005f5f73 697a655f 74005f5f char.__size_t.__
+  0x000001e0 76617269 61626c65 005f5f6d 6170005f variable.__map._
+  0x000001f0 52756e65 456e7472 79005f5f 6d617800 RuneEntry.__max.
+  0x00000200 5f5f7370 75747275 6e65005f 5f6d6170 __sputrune.__map
+  0x00000210 6c6f7765 725f6578 74006c6f 6e672075 lower_ext.long u
+  0x00000220 6e736967 6e656420 696e7400 5f52756e nsigned int._Run
+  0x00000230 654c6f63 616c6500 5f5f7275 6e657479 eLocale.__runety
+  0x00000240 7065005f 5f6d696e 00666e6d 61746368 pe.__min.fnmatch
+  0x00000250 005f5f74 79706573 005f5f6d 61706c6f .__types.__maplo
+  0x00000260 77657200 5f5f6e72 616e6765 73005f5f wer.__nranges.__
+  0x00000270 73676574 72756e65 005f5f65 6e636f64 sgetrune.__encod
+  0x00000280 696e6700                            ing.
 

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-24  6:44     ` Gerald Pfeifer
@ 2011-08-24  7:38       ` Richard Henderson
  2011-08-24  8:46         ` Gerald Pfeifer
  0 siblings, 1 reply; 33+ messages in thread
From: Richard Henderson @ 2011-08-24  7:38 UTC (permalink / raw)
  To: Gerald Pfeifer
  Cc: Eric Botcazou, gcc-patches, bernds, avr, Ian Lance Taylor, Jeff Law

On 08/23/2011 03:42 PM, Gerald Pfeifer wrote:
> On Tue, 23 Aug 2011, Richard Henderson wrote:
>> I've been trying for 2 days to replicate this with various
>> configurations and none have failed.
> 
> Thanks for investigating, and sorry that this proves a worthy opponent!
> 
> 
> On my testers, the system compiler used for bootstrap is GCC 4.2.
> Could that make a difference?

I wouldn't think so.

> Also, comparing stage2-libiberty/fnmatch.o  and stage3-libiberty/fnmatch.o
> I noticed that the latter is more than three times the size.
> 
> objdump -d does not show any difference.  objdump -W, however, shows
> lots of additional DWARF debugging information.  I am attaching a diff 
> between the two.
> 
> Does that help?

Not really.  This is an obvious and expected difference, since
stage2 is normally compiled *without* debug information, so that
we can verify that -g0 vs -g2 doesn't alter code generation.


r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-24  7:38       ` Richard Henderson
@ 2011-08-24  8:46         ` Gerald Pfeifer
  2011-08-24  8:48           ` H.J. Lu
  0 siblings, 1 reply; 33+ messages in thread
From: Gerald Pfeifer @ 2011-08-24  8:46 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Eric Botcazou, gcc-patches, bernds, avr, Ian Lance Taylor, Jeff Law

Hmm, does a copy of my build tree (including logs in nohup.out) help?

I put up one at http://people.freebsd.org/~gerald/objtree.tar.xz .

Gerald

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-24  8:46         ` Gerald Pfeifer
@ 2011-08-24  8:48           ` H.J. Lu
  0 siblings, 0 replies; 33+ messages in thread
From: H.J. Lu @ 2011-08-24  8:48 UTC (permalink / raw)
  To: Gerald Pfeifer
  Cc: Richard Henderson, Eric Botcazou, gcc-patches, bernds, avr,
	Ian Lance Taylor, Jeff Law

On Tue, Aug 23, 2011 at 6:07 PM, Gerald Pfeifer <gerald@pfeifer.com> wrote:
> Hmm, does a copy of my build tree (including logs in nohup.out) help?
>
> I put up one at http://people.freebsd.org/~gerald/objtree.tar.xz .
>

I couldn't reproduce the bootstrap failure n Linux/ia32 either.  Have
you tried the latest
binutils?



-- 
H.J.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-23 22:20   ` Richard Henderson
  2011-08-24  6:44     ` Gerald Pfeifer
@ 2011-08-24 17:38     ` Eric Botcazou
  2011-09-04 18:39       ` Gerald Pfeifer
  1 sibling, 1 reply; 33+ messages in thread
From: Eric Botcazou @ 2011-08-24 17:38 UTC (permalink / raw)
  To: Richard Henderson
  Cc: Gerald Pfeifer, gcc-patches, bernds, avr, Ian Lance Taylor, Jeff Law

> I've been trying for 2 days to replicate this with various
> configurations and none have failed.

I configure for i586 with --enable-checking=yes,rtl.  And I also have a 
comparison failure on x86-64 with the same configure options:

Bootstrap comparison failure!
libcpp/lex.o differs

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-24 17:38     ` Eric Botcazou
@ 2011-09-04 18:39       ` Gerald Pfeifer
  2011-09-09 10:01         ` Eric Botcazou
  0 siblings, 1 reply; 33+ messages in thread
From: Gerald Pfeifer @ 2011-09-04 18:39 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: Richard Henderson, gcc-patches, bernds, avr, Ian Lance Taylor, Jeff Law

On Wed, 24 Aug 2011, Eric Botcazou wrote:
>> I've been trying for 2 days to replicate this with various 
>> configurations and none have failed.
> I configure for i586 with --enable-checking=yes,rtl.  And I also have a 
> comparison failure on x86-64 with the same configure options:

Which version of binutils are you using, Eric?  And which ones have
you been using, Richard?


My failures are with binutils 2.17.50 on FreeBSD 9/i386 where this is
the system toolchain.  Using a manual installation of binutils 2.21.1
there makes bootstrap pass for me.

Gerald

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-09-04 18:39       ` Gerald Pfeifer
@ 2011-09-09 10:01         ` Eric Botcazou
  2011-09-09 19:07           ` Eric Botcazou
  0 siblings, 1 reply; 33+ messages in thread
From: Eric Botcazou @ 2011-09-09 10:01 UTC (permalink / raw)
  To: Gerald Pfeifer
  Cc: Richard Henderson, gcc-patches, bernds, avr, Ian Lance Taylor, Jeff Law

> Which version of binutils are you using, Eric?

Binutils CVS from this morning:

Target: i586-suse-linux
Configured 
with: /home/eric/svn/gcc/configure --build=i586-suse-linux --prefix=/home/eric/install/gcc --with-as=/home/eric/build/binutils/native32/gas/as-new --with-ld=/home/eric/build/binutils/native32/ld/ld-new --enable-languages=c,c++,ada --enable-checking=yes,rtl --enable-__cxa_atexit --disable-nls --disable-libmudflap --disable-initfini-array
Thread model: posix
gcc version 4.7.0 20110909 (experimental) [trunk revision 178719] (GCC)

eric@atlantis:~/build/gcc/native32> /home/eric/build/binutils/native32/gas/as-new --version
GNU assembler (GNU Binutils) 2.21.53.20110909
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `i586-suse-linux'.

eric@atlantis:~/build/gcc/native32> /home/eric/build/binutils/native32/ld/ld-new --version
GNU ld (GNU Binutils) 2.21.53.20110909
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

Comparing stages 2 and 3
warning: gcc/cc1-checksum.o differs
warning: gcc/cc1plus-checksum.o differs
Bootstrap comparison failure!
gcc/ada/sprint.o differs
libiberty/pic/regex.o differs
libiberty/pic/cplus-dem.o differs
libiberty/pic/alloca.o differs
libiberty/pic/argv.o differs
libiberty/pic/crc32.o differs
libiberty/pic/fdmatch.o differs
libiberty/pic/floatformat.o differs
libiberty/pic/hashtab.o differs
libiberty/pic/pex-common.o differs
libiberty/pic/simple-object-coff.o differs
make[2]: *** [compare] Error 1

For libiberty/pic/argv.o, the difference lies within the .eh_frame section.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-09-09 10:01         ` Eric Botcazou
@ 2011-09-09 19:07           ` Eric Botcazou
  2011-09-09 20:02             ` H.J. Lu
  0 siblings, 1 reply; 33+ messages in thread
From: Eric Botcazou @ 2011-09-09 19:07 UTC (permalink / raw)
  To: gcc-patches
  Cc: Gerald Pfeifer, Richard Henderson, bernds, avr, Ian Lance Taylor,
	Jeff Law

> Binutils CVS from this morning:

OK, I see.  For some reasons, this build has:

#define HAVE_GAS_CFI_DIRECTIVE 0

and another build with binutils 2.20 succeeds, but it has:

#define HAVE_GAS_CFI_DIRECTIVE 1


So bootstrap is broken without CFI directives.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-09-09 19:07           ` Eric Botcazou
@ 2011-09-09 20:02             ` H.J. Lu
  2011-09-10 14:08               ` Eric Botcazou
  0 siblings, 1 reply; 33+ messages in thread
From: H.J. Lu @ 2011-09-09 20:02 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: gcc-patches, Gerald Pfeifer, Richard Henderson, bernds, avr,
	Ian Lance Taylor, Jeff Law

On Fri, Sep 9, 2011 at 11:15 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> Binutils CVS from this morning:
>
> OK, I see.  For some reasons, this build has:
>
> #define HAVE_GAS_CFI_DIRECTIVE 0
>
> and another build with binutils 2.20 succeeds, but it has:
>
> #define HAVE_GAS_CFI_DIRECTIVE 1
>

I have no problems with binutils in CVS today.  That
may be another --with-as/--with-ld issue similar to

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50237

-- 
H.J.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-09-09 20:02             ` H.J. Lu
@ 2011-09-10 14:08               ` Eric Botcazou
  2011-09-10 19:03                 ` H.J. Lu
  0 siblings, 1 reply; 33+ messages in thread
From: Eric Botcazou @ 2011-09-10 14:08 UTC (permalink / raw)
  To: H.J. Lu
  Cc: gcc-patches, Gerald Pfeifer, Richard Henderson, bernds, avr,
	Ian Lance Taylor, Jeff Law

> I have no problems with binutils in CVS today.  That
> may be another --with-as/--with-ld issue similar to
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50237

No, this was a pilot error on my side.  Now I have HAVE_GAS_CFI_DIRECTIVE to 1 
but the bootstrap still fails if --disable-initfini-array isn't specified.

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-09-10 14:08               ` Eric Botcazou
@ 2011-09-10 19:03                 ` H.J. Lu
  2011-09-11  2:35                   ` Gerald Pfeifer
  0 siblings, 1 reply; 33+ messages in thread
From: H.J. Lu @ 2011-09-10 19:03 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: gcc-patches, Gerald Pfeifer, Richard Henderson, bernds, avr,
	Ian Lance Taylor, Jeff Law

On Sat, Sep 10, 2011 at 4:01 AM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> I have no problems with binutils in CVS today.  That
>> may be another --with-as/--with-ld issue similar to
>>
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50237
>
> No, this was a pilot error on my side.  Now I have HAVE_GAS_CFI_DIRECTIVE to 1

One problem with --with-as/--with-ld is we are using nm/objdump/readelf
from the different version of binutils to test as/ld features.  Sometimes, it
doesn't work too well.  For example, we have

gcc_GAS_CHECK_FEATURE([working cfi advance], gcc_cv_as_cfi_advance_working,
  ,,
[       .text
        .cfi_startproc
        .cfi_adjust_cfa_offset 64
        .skip 75040, 0
        .cfi_adjust_cfa_offset 128
        .cfi_endproc],
[[
if $gcc_cv_objdump -Wf conftest.o 2>/dev/null \
    | grep 'DW_CFA_advance_loc[24]:[    ][      ]*75040[        ]'
>/dev/null; then
   gcc_cv_as_cfi_advance_working=yes
fi

Our assembler supports CFI, but objdump may be too old to dump
DW_CFA_advance_loc
and this feature is mis-detected.

> but the bootstrap still fails if --disable-initfini-array isn't specified.
>

Please try:

http://gcc.gnu.org/ml/gcc-patches/2011-09/msg00668.html

-- 
H.J.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-09-10 19:03                 ` H.J. Lu
@ 2011-09-11  2:35                   ` Gerald Pfeifer
  0 siblings, 0 replies; 33+ messages in thread
From: Gerald Pfeifer @ 2011-09-11  2:35 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Eric Botcazou, gcc-patches, Richard Henderson, bernds, avr,
	Ian Lance Taylor, Jeff Law

On Sat, 10 Sep 2011, H.J. Lu wrote:
> Our assembler supports CFI, but objdump may be too old to dump 
> DW_CFA_advance_loc and this feature is mis-detected.

Should this be autoconf-ed, then?  As a test for objdump?

(FWIW my bootstrap comparison failure, cf. http://gcc.gnu.org/PR50010 ,
also seems to occur when I configure with --disable-initfini-array.)

Gerald

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-02 22:32 ` Richard Henderson
  2011-08-03 14:31   ` H.J. Lu
@ 2011-12-21  5:20   ` Jie Zhang
  1 sibling, 0 replies; 33+ messages in thread
From: Jie Zhang @ 2011-12-21  5:20 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches, bernds, avr, iant

Hi,

On Tue, Aug 2, 2011 at 6:32 PM, Richard Henderson <rth@redhat.com> wrote:
> I got Jeff Law to review the reload change on IRC
> and committed the composite patch.
>
> Tested on x86_64, i586, avr, and h8300.  Most other
> tier1 targets ought not be affected, as this patch
> only applies to ACCUMULATE_OUTGOING_ARGS == 0 targets.
>
This commit may have caused

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51552


Regards,
Jie

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 14:31   ` H.J. Lu
@ 2011-08-03 17:39     ` H.J. Lu
  0 siblings, 0 replies; 33+ messages in thread
From: H.J. Lu @ 2011-08-03 17:39 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches, bernds, avr, iant

On Wed, Aug 3, 2011 at 7:31 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Aug 2, 2011 at 3:32 PM, Richard Henderson <rth@redhat.com> wrote:
>> I got Jeff Law to review the reload change on IRC
>> and committed the composite patch.
>>
>> Tested on x86_64, i586, avr, and h8300.  Most other
>> tier1 targets ought not be affected, as this patch
>> only applies to ACCUMULATE_OUTGOING_ARGS == 0 targets.
>>
>
> It may have caused:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49964
>
>

It breaks -march=corei7-avx.


-- 
H.J.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 15:15   ` Richard Henderson
@ 2011-08-03 17:01     ` Ulrich Weigand
  0 siblings, 0 replies; 33+ messages in thread
From: Ulrich Weigand @ 2011-08-03 17:01 UTC (permalink / raw)
  To: Richard Henderson; +Cc: avr, bernds, GCC Patches, iant

Richard Henderson <rth@redhat.com> wrote on 08/03/2011 04:15:26 PM:
> On 08/03/2011 07:07 AM, Ulrich Weigand wrote:
> > Was this assert intended to impose requirements on target's
> > restore_stack_block implemtations?  What exactly are those
> > supposed to be?
>
> The assert was not intended to impose requirements, but to figure
> out if I needed to do anything special here.
>
> Binutils has no simulator for spu.  Can you file a bug with a
> specific test case and CC me?

Certainly, this is now PR 49968.  You should be able to reproduce
the ICE with a spu-elf cross-cc1 without anything else.  If you'd
like me to test anything on spu natively, just let me know ...

Bye,
Ulrich

--
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 14:08       ` Georg-Johann Lay
  2011-08-03 15:13         ` Richard Henderson
@ 2011-08-03 16:24         ` Jeff Law
  1 sibling, 0 replies; 33+ messages in thread
From: Jeff Law @ 2011-08-03 16:24 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: Richard Henderson, GCC Patches, Denis Chertykov

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 08/03/11 08:07, Georg-Johann Lay wrote:
> Georg-Johann Lay wrote:
>> Richard Henderson wrote:
>>> On 08/01/2011 11:42 AM, Georg-Johann Lay wrote:
>>>> Is there a specific reason not to define 
>>>> ACCUMULATE_OUTGOING_ARGS on AVR?
>>> Yes.  So that you can use PUSH.  But as I said in PR49881, you
>>> probably want to provide -maccumulate-outgoing-args.
>>> 
>>> I have a follow-up patch to the last one in that PR...
>>> 
>>> 
>>> r~
>> 
>> PUSH is fine but what about POP?
>> 
>> It's very expensive to pop several bytes, i.e. disabling IRQs,
>> loading and storing SP and the like. Usung store+displacement has
>> not this drawback and as I wrote, come code degradations you
>> explained in PR49881 are artifacts of PR46278, i.e. fake X
>> addressing.
>> 
>> Johann
>> 
> 
> Tried this test case:
> 
> #include <stdio.h>
> 
> void foo () { printf ("%d %d %d", 1, 2, 3); printf ("%d %d %d", 3, 4,
> 5); printf ("%d %d %d", 1, 4, 5); }
> 
> Attached the output: The compiler happily pushes onto the stack but
> pops only at the end of the function. So in a function with many such
> calls that would eat up great deal of RAM. It that what we want?
> 
> RETURN_POPS_ARGS cannot help here.
Popping arguments is deferred until the accumulated size of the deferred
argument pops reaches a particular threshold or certain other conditions
are met (see NO_DEFER_POP).

I don't recall the parameters used to determine when the accumulated
size is large enough to force pops, but I'm sure you can find it with a
little searching in the GCC sources.

Ahhh, memories of the m68k...

jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJOOXY4AAoJEBRtltQi2kC79VkH/Ar4NFKpU9mMXS+Pswz3vuOT
6Mv0pWGmuACBz7r69NZ9WNb2PQBXTJUp/vQJUbvKxIBFWmtEc6wRO1kYz3NuZ9FX
MRTXO+Mo3TWkFtzr5krq6d3r0CYVwa3ta/U/XNwvoo+XAUVkuYQgJi0C85yBQBwM
M9Q8nzWaJxAohSh+r6tOIBBdFG66YnfmZAYxLnsOaS5akm4tMuS6D5KFnJVJZbc7
btjNYzLvjCBXuekuHCyaq3HxpTTmhKWCFXuy55fUiOZGJJabPfTfbXlRaM5pGkPk
eo6gR9ydvMIt0RbYCSpqNy1RE+bOfeawqnoE/Mx86ZIzJZuLWOz+3K8UI5cINJ4=
=2Kgl
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 15:49           ` Georg-Johann Lay
@ 2011-08-03 15:53             ` Richard Henderson
  0 siblings, 0 replies; 33+ messages in thread
From: Richard Henderson @ 2011-08-03 15:53 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: GCC Patches, Denis Chertykov

On 08/03/2011 08:47 AM, Georg-Johann Lay wrote:
> With ACCUMULATE_OUTGOING_ARGS it looks much better: there is just
> one such block in the prologue/epilogue.
> 
> I think ACCUMULATE_OUTGOING_ARGS would be a win definitely.

That's what I thought too, but with the test case in PR49881
I couldn't make A_O_A come out smaller than PUSHes.  The
reason being the function didn't otherwise need a frame
pointer and we got to use REG_Y for something more useful.

Perhaps that test case isn't the rule for real-world code.
That's why I suggested implementing the command-line switch,
to give the user an option of trying both and selecting the
smaller option for their particular code.


r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 15:13         ` Richard Henderson
@ 2011-08-03 15:49           ` Georg-Johann Lay
  2011-08-03 15:53             ` Richard Henderson
  0 siblings, 1 reply; 33+ messages in thread
From: Georg-Johann Lay @ 2011-08-03 15:49 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches, Denis Chertykov

Richard Henderson wrote:
> On 08/03/2011 07:07 AM, Georg-Johann Lay wrote:
>> #include <stdio.h>
>>
>> void foo ()
>> {
>>     printf ("%d %d %d", 1, 2, 3);
>>     printf ("%d %d %d", 3, 4, 5);
>>     printf ("%d %d %d", 1, 4, 5);
>> }
>>
>> Attached the output: The compiler happily pushes onto the stack
>> but pops only at the end of the function. So in a function with
>> many such calls that would eat up great deal of RAM. It that
>> what we want?
> 
> Add more printfs and find out.  We'll consume 32 bytes and then
> pop it all off in the middle of the function, then start again.
> 
> See the use of pending_stack_adjust in expand_call.
> 
> 
> r~
> 

Yes, the following blocks are sprinkled all over the function:

	in r24,__SP_L__	 ;  222	*movhi_sp/2	[length = 2]
	in r25,__SP_H__
	adiw r24,32	 ;  134	*addhi3/2	[length = 1]
	in __tmp_reg__,__SREG__	 ;  223	*movhi_sp/1	[length = 5]
	cli
	out __SP_H__,r25
	out __SREG__,__tmp_reg__
	out __SP_L__,r24

With ACCUMULATE_OUTGOING_ARGS it looks much better: there is just
one such block in the prologue/epilogue.

I think ACCUMULATE_OUTGOING_ARGS would be a win definitely.

Pushing more than 63 bytes for one function is no real world
code for AVR and I think we can focus on functions receiving
<= 63 bytes on stack.

Johann

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 14:07 ` Ulrich Weigand
@ 2011-08-03 15:15   ` Richard Henderson
  2011-08-03 17:01     ` Ulrich Weigand
  0 siblings, 1 reply; 33+ messages in thread
From: Richard Henderson @ 2011-08-03 15:15 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: GCC Patches, bernds, avr, iant

On 08/03/2011 07:07 AM, Ulrich Weigand wrote:
> Was this assert intended to impose requirements on target's
> restore_stack_block implemtations?  What exactly are those
> supposed to be?

The assert was not intended to impose requirements, but to figure
out if I needed to do anything special here.

Binutils has no simulator for spu.  Can you file a bug with a 
specific test case and CC me?


r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 14:08       ` Georg-Johann Lay
@ 2011-08-03 15:13         ` Richard Henderson
  2011-08-03 15:49           ` Georg-Johann Lay
  2011-08-03 16:24         ` Jeff Law
  1 sibling, 1 reply; 33+ messages in thread
From: Richard Henderson @ 2011-08-03 15:13 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: GCC Patches, Denis Chertykov

On 08/03/2011 07:07 AM, Georg-Johann Lay wrote:
> #include <stdio.h>
> 
> void foo ()
> {
>     printf ("%d %d %d", 1, 2, 3);
>     printf ("%d %d %d", 3, 4, 5);
>     printf ("%d %d %d", 1, 4, 5);
> }
> 
> Attached the output: The compiler happily pushes onto the stack
> but pops only at the end of the function. So in a function with
> many such calls that would eat up great deal of RAM. It that
> what we want?

Add more printfs and find out.  We'll consume 32 bytes and then
pop it all off in the middle of the function, then start again.

See the use of pending_stack_adjust in expand_call.


r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-02 22:32 ` Richard Henderson
@ 2011-08-03 14:31   ` H.J. Lu
  2011-08-03 17:39     ` H.J. Lu
  2011-12-21  5:20   ` Jie Zhang
  1 sibling, 1 reply; 33+ messages in thread
From: H.J. Lu @ 2011-08-03 14:31 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches, bernds, avr, iant

On Tue, Aug 2, 2011 at 3:32 PM, Richard Henderson <rth@redhat.com> wrote:
> I got Jeff Law to review the reload change on IRC
> and committed the composite patch.
>
> Tested on x86_64, i586, avr, and h8300.  Most other
> tier1 targets ought not be affected, as this patch
> only applies to ACCUMULATE_OUTGOING_ARGS == 0 targets.
>

It may have caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49964


-- 
H.J.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-03 12:16     ` Georg-Johann Lay
@ 2011-08-03 14:08       ` Georg-Johann Lay
  2011-08-03 15:13         ` Richard Henderson
  2011-08-03 16:24         ` Jeff Law
  0 siblings, 2 replies; 33+ messages in thread
From: Georg-Johann Lay @ 2011-08-03 14:08 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches, Denis Chertykov

[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]

Georg-Johann Lay wrote:
> Richard Henderson wrote:
>> On 08/01/2011 11:42 AM, Georg-Johann Lay wrote:
>>> Is there a specific reason not to define
>>> ACCUMULATE_OUTGOING_ARGS on AVR?
>> Yes.  So that you can use PUSH.  But as I said in PR49881,
>> you probably want to provide -maccumulate-outgoing-args.
>>
>> I have a follow-up patch to the last one in that PR...
>>
>>
>> r~
> 
> PUSH is fine but what about POP?
> 
> It's very expensive to pop several bytes, i.e. disabling IRQs, loading and storing SP and the like.
> Usung store+displacement has not this drawback and as I wrote, come code degradations you explained
> in PR49881 are artifacts of PR46278, i.e. fake X addressing.
> 
> Johann
> 

Tried this test case:

#include <stdio.h>

void foo ()
{
    printf ("%d %d %d", 1, 2, 3);
    printf ("%d %d %d", 3, 4, 5);
    printf ("%d %d %d", 1, 4, 5);
}

Attached the output: The compiler happily pushes onto the stack
but pops only at the end of the function. So in a function with
many such calls that would eat up great deal of RAM. It that
what we want?

RETURN_POPS_ARGS cannot help here.

Johann






[-- Attachment #2: printf.s --]
[-- Type: text/plain, Size: 5323 bytes --]

	.file	"printf.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
 ;  GNU C (GCC) version 4.7.0 20110803 (experimental) (avr)
 ; 	compiled by GNU C version 4.3.2 [gcc-4_3-branch revision 141291], GMP version 5.0.1, MPFR version 3.0.0-p8, MPC version 0.8.2
 ;  GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
 ;  options passed:  printf.c -Os -fverbose-asm
 ;  options enabled:  -fauto-inc-dec -fbranch-count-reg -fcaller-saves
 ;  -fcombine-stack-adjustments -fcommon -fcompare-elim -fcprop-registers
 ;  -fcrossjumping -fcse-follow-jumps -fdebug-types-section -fdefer-pop
 ;  -fdevirtualize -fearly-inlining -feliminate-unused-debug-types
 ;  -fexpensive-optimizations -fforward-propagate -ffunction-cse -fgcse
 ;  -fgcse-lm -fguess-branch-probability -fident -fif-conversion
 ;  -fif-conversion2 -findirect-inlining -finline -finline-functions
 ;  -finline-functions-called-once -finline-small-functions -fipa-cp
 ;  -fipa-profile -fipa-pure-const -fipa-reference -fipa-sra
 ;  -fira-share-save-slots -fira-share-spill-slots -fivopts
 ;  -fkeep-static-consts -fleading-underscore -fmath-errno
 ;  -fmerge-constants -fmerge-debug-strings -fmove-loop-invariants
 ;  -fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls
 ;  -fpartial-inlining -fpeephole -fpeephole2 -fprefetch-loop-arrays
 ;  -freg-struct-return -fregmove -freorder-blocks -freorder-functions
 ;  -frerun-cse-after-loop -fsched-critical-path-heuristic
 ;  -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock
 ;  -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec
 ;  -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fshow-column
 ;  -fsigned-zeros -fsplit-ivs-in-unroller -fsplit-wide-types
 ;  -fstrict-aliasing -fstrict-overflow -fstrict-volatile-bitfields
 ;  -fthread-jumps -ftoplevel-reorder -ftrapping-math -ftree-bit-ccp
 ;  -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copy-prop
 ;  -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse
 ;  -ftree-forwprop -ftree-fre -ftree-loop-if-convert -ftree-loop-im
 ;  -ftree-loop-ivcanon -ftree-loop-optimize -ftree-parallelize-loops=
 ;  -ftree-phiprop -ftree-pre -ftree-pta -ftree-reassoc -ftree-scev-cprop
 ;  -ftree-sink -ftree-slp-vectorize -ftree-sra -ftree-switch-conversion
 ;  -ftree-ter -ftree-vect-loop-version -ftree-vrp -funit-at-a-time
 ;  -fverbose-asm -fzero-initialized-in-bss

	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"%d %d %d"
	.text
.global	foo
	.type	foo, @function
foo:
	push r14	 ; 	 ;  66	pushqi1/1	[length = 1]
	push r15	 ; 	 ;  67	pushqi1/1	[length = 1]
	push r16	 ; 	 ;  68	pushqi1/1	[length = 1]
	push r17	 ; 	 ;  69	pushqi1/1	[length = 1]
	push r28	 ; 	 ;  70	pushqi1/1	[length = 1]
	push r29	 ; 	 ;  71	pushqi1/1	[length = 1]
/* prologue: function */
/* frame size = 0 */
/* stack size = 6 */
.L__stack_usage = 6
	push __zero_reg__	 ;  5	pushqi1/2	[length = 1]
	ldi r24,lo8(3)	 ; ,	 ;  82	*reload_inqi	[length = 2]
	mov r14,r24	 ;  tmp42,
	push r14	 ;  tmp42	 ;  7	pushqi1/1	[length = 1]
	push __zero_reg__	 ;  8	pushqi1/2	[length = 1]
	ldi r24,lo8(2)	 ;  tmp43,	 ;  9	*movqi/2	[length = 1]
	push r24	 ;  tmp43	 ;  10	pushqi1/1	[length = 1]
	push __zero_reg__	 ;  11	pushqi1/2	[length = 1]
	ldi r17,lo8(1)	 ;  tmp44,	 ;  12	*movqi/2	[length = 1]
	push r17	 ;  tmp44	 ;  13	pushqi1/1	[length = 1]
	ldi r28,lo8(.LC0)	 ;  tmp45,	 ;  14	*movhi/4	[length = 2]
	ldi r29,hi8(.LC0)	 ;  tmp45,
	push r29	 ;  tmp24	 ;  16	pushqi1/1	[length = 1]
	push r28	 ;  tmp25	 ;  19	pushqi1/1	[length = 1]
	rcall printf	 ; 	 ;  20	*call_value_insn/2	[length = 1]
	push __zero_reg__	 ;  21	pushqi1/2	[length = 1]
	ldi r25,lo8(5)	 ; ,	 ;  83	*reload_inqi	[length = 2]
	mov r15,r25	 ;  tmp49,
	push r15	 ;  tmp49	 ;  23	pushqi1/1	[length = 1]
	push __zero_reg__	 ;  24	pushqi1/2	[length = 1]
	ldi r16,lo8(4)	 ;  tmp50,	 ;  25	*movqi/2	[length = 1]
	push r16	 ;  tmp50	 ;  26	pushqi1/1	[length = 1]
	push __zero_reg__	 ;  27	pushqi1/2	[length = 1]
	push r14	 ;  tmp42	 ;  29	pushqi1/1	[length = 1]
	push r29	 ;  tmp24	 ;  32	pushqi1/1	[length = 1]
	push r28	 ;  tmp25	 ;  35	pushqi1/1	[length = 1]
	rcall printf	 ; 	 ;  36	*call_value_insn/2	[length = 1]
	push __zero_reg__	 ;  37	pushqi1/2	[length = 1]
	push r15	 ;  tmp49	 ;  39	pushqi1/1	[length = 1]
	push __zero_reg__	 ;  40	pushqi1/2	[length = 1]
	push r16	 ;  tmp50	 ;  42	pushqi1/1	[length = 1]
	push __zero_reg__	 ;  43	pushqi1/2	[length = 1]
	push r17	 ;  tmp44	 ;  45	pushqi1/1	[length = 1]
	push r29	 ;  tmp24	 ;  48	pushqi1/1	[length = 1]
	push r28	 ;  tmp25	 ;  51	pushqi1/1	[length = 1]
	rcall printf	 ; 	 ;  52	*call_value_insn/2	[length = 1]
	in r24,__SP_L__	 ; 	 ;  64	*movhi_sp/2	[length = 2]
	in r25,__SP_H__	 ; 
	adiw r24,24	 ; ,	 ;  53	*addhi3/2	[length = 1]
	in __tmp_reg__,__SREG__	 ;  65	*movhi_sp/1	[length = 5]
	cli
	out __SP_H__,r25	 ; 
	out __SREG__,__tmp_reg__
	out __SP_L__,r24	 ; 
/* epilogue start */
	pop r29	 ; 	 ;  74	popqi	[length = 1]
	pop r28	 ; 	 ;  75	popqi	[length = 1]
	pop r17	 ; 	 ;  76	popqi	[length = 1]
	pop r16	 ; 	 ;  77	popqi	[length = 1]
	pop r15	 ; 	 ;  78	popqi	[length = 1]
	pop r14	 ; 	 ;  79	popqi	[length = 1]
	ret	 ;  80	return_from_epilogue	[length = 1]
	.size	foo, .-foo
	.ident	"GCC: (GNU) 4.7.0 20110803 (experimental)"
.global __do_copy_data

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-01 17:40 Richard Henderson
                   ` (2 preceding siblings ...)
  2011-08-02 22:32 ` Richard Henderson
@ 2011-08-03 14:07 ` Ulrich Weigand
  2011-08-03 15:15   ` Richard Henderson
  3 siblings, 1 reply; 33+ messages in thread
From: Ulrich Weigand @ 2011-08-03 14:07 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches, bernds, avr, iant

Richard Henderson wrote:

>  	  emit_stack_restore (SAVE_BLOCK, old_stack_level);
>  	  stack_pointer_delta = old_stack_pointer_delta;
> +
> +	  /* ??? Is this assert warrented, given emit_stack_restore?
> +	     or should we just mark the last insn no matter what?  */
> +	  last = get_last_insn ();
> +	  set = single_set (last);
> +	  gcc_assert (set != NULL);
> +	  gcc_assert (SET_DEST (set) == stack_pointer_rtx);

This assert triggers on spu-elf, because our restore_stack_block
pattern emits something else as its last instruction: we restore
a stack backchain link after restoring the stack pointer.

Even if we were to swap the order to restore the backchain first,
like rs6000 does, the assert would still trigger, since we cannot
use stack_pointer_rtx to restore the stack pointer; this is because
on SPU, the stack pointer is a vector register, and the ABI says to
maintain the remaining free stack space in a high slot of that
vector.  Therefore, restore_stack_block uses a vector add into
a register generated via gen_rtx_REG (V4SImode, STACK_POINTER_REGNUM)
instead of just plain stack_pointer_rtx ...

Was this assert intended to impose requirements on target's
restore_stack_block implemtations?  What exactly are those
supposed to be?

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-01 18:47   ` Richard Henderson
  2011-08-01 19:53     ` Denis Chertykov
@ 2011-08-03 12:16     ` Georg-Johann Lay
  2011-08-03 14:08       ` Georg-Johann Lay
  1 sibling, 1 reply; 33+ messages in thread
From: Georg-Johann Lay @ 2011-08-03 12:16 UTC (permalink / raw)
  To: Richard Henderson; +Cc: GCC Patches, Denis Chertykov, Denis Chertykov

Richard Henderson wrote:
> On 08/01/2011 11:42 AM, Georg-Johann Lay wrote:
>> Is there a specific reason not to define
>> ACCUMULATE_OUTGOING_ARGS on AVR?
> 
> Yes.  So that you can use PUSH.  But as I said in PR49881,
> you probably want to provide -maccumulate-outgoing-args.
> 
> I have a follow-up patch to the last one in that PR...
> 
> 
> r~

PUSH is fine but what about POP?

It's very expensive to pop several bytes, i.e. disabling IRQs, loading and storing SP and the like.
Usung store+displacement has not this drawback and as I wrote, come code degradations you explained
in PR49881 are artifacts of PR46278, i.e. fake X addressing.

Johann



^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-01 17:40 Richard Henderson
  2011-08-01 18:43 ` Georg-Johann Lay
  2011-08-02  2:00 ` Richard Henderson
@ 2011-08-02 22:32 ` Richard Henderson
  2011-08-03 14:31   ` H.J. Lu
  2011-12-21  5:20   ` Jie Zhang
  2011-08-03 14:07 ` Ulrich Weigand
  3 siblings, 2 replies; 33+ messages in thread
From: Richard Henderson @ 2011-08-02 22:32 UTC (permalink / raw)
  To: GCC Patches; +Cc: bernds, avr, iant

I got Jeff Law to review the reload change on IRC
and committed the composite patch.

Tested on x86_64, i586, avr, and h8300.  Most other
tier1 targets ought not be affected, as this patch
only applies to ACCUMULATE_OUTGOING_ARGS == 0 targets.


r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-01 17:40 Richard Henderson
  2011-08-01 18:43 ` Georg-Johann Lay
@ 2011-08-02  2:00 ` Richard Henderson
  2011-08-02 22:32 ` Richard Henderson
  2011-08-03 14:07 ` Ulrich Weigand
  3 siblings, 0 replies; 33+ messages in thread
From: Richard Henderson @ 2011-08-02  2:00 UTC (permalink / raw)
  To: GCC Patches; +Cc: bernds, avr, iant, law

[-- Attachment #1: Type: text/plain, Size: 546 bytes --]

Testing on h8300, newlib/libm/math/ef_j0.c revealed a crash.

The problem is that PREV turned out to be unlinked when we came to 

                  fixup_args_size_notes (prev, PREV_INSN (next),
                                         INTVAL (XEXP (p, 0)));

I'm not sure how this didn't previously crash at

                fixup_eh_region_note (insn, prev, next);

Thanks to reload inheritance deleting insns out from under, I can't
think of any other mechanism than to have a marker note before INSN
that won't get deleted.

Comments?


r~


[-- Attachment #2: commit-90060c3 --]
[-- Type: text/plain, Size: 1707 bytes --]

commit 90060c3e9508d3bd0c930ba13cbe3230c7ea0b8f
Author: Richard Henderson <rth@redhat.com>
Date:   Mon Aug 1 18:47:04 2011 -0700

    reload: Work around reload inheritence deleting insns.

diff --git a/gcc/reload1.c b/gcc/reload1.c
index 3233580..ba6ce37 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -4548,7 +4548,7 @@ reload_as_needed (int live_known)
 #if defined (AUTO_INC_DEC)
   int i;
 #endif
-  rtx x;
+  rtx x, marker;
 
   memset (spill_reg_rtx, 0, sizeof spill_reg_rtx);
   memset (spill_reg_store, 0, sizeof spill_reg_store);
@@ -4559,6 +4559,10 @@ reload_as_needed (int live_known)
 
   set_initial_elim_offsets ();
 
+  /* Generate a marker insn that we will move around.  */
+  marker = emit_note (NOTE_INSN_DELETED);
+  unlink_insn_chain (marker, marker);
+
   for (chain = reload_insn_chain; chain; chain = chain->next)
     {
       rtx prev = 0;
@@ -4631,7 +4635,10 @@ reload_as_needed (int live_known)
 	      rtx next = NEXT_INSN (insn);
 	      rtx p;
 
+	      /* ??? PREV can get deleted by reload inheritance.
+		 Work around this by emitting a marker note.  */
 	      prev = PREV_INSN (insn);
+	      reorder_insns_nobb (marker, marker, prev);
 
 	      /* Now compute which reload regs to reload them into.  Perhaps
 		 reusing reload regs from previous insns, or else output
@@ -4649,6 +4656,9 @@ reload_as_needed (int live_known)
 		 and that we moved the structure into).  */
 	      subst_reloads (insn);
 
+	      prev = PREV_INSN (marker);
+	      unlink_insn_chain (marker, marker);
+
 	      /* Adjust the exception region notes for loads and stores.  */
 	      if (cfun->can_throw_non_call_exceptions && !CALL_P (insn))
 		fixup_eh_region_note (insn, prev, next);

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-01 18:47   ` Richard Henderson
@ 2011-08-01 19:53     ` Denis Chertykov
  2011-08-03 12:16     ` Georg-Johann Lay
  1 sibling, 0 replies; 33+ messages in thread
From: Denis Chertykov @ 2011-08-01 19:53 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Georg-Johann Lay, GCC Patches, bernds, iant

2011/8/1 Richard Henderson <rth@redhat.com>:
> On 08/01/2011 11:42 AM, Georg-Johann Lay wrote:
>> Is there a specific reason not to define
>> ACCUMULATE_OUTGOING_ARGS on AVR?

I havn't define ACCUMULATE_OUTGOING_ARGS because AVR have a very small
displacement for memory addressing (63 bytes) and I think that better
to have a minimal possible frame size (because of difficult addressing
of a local variables outside of fp+63 boundary).

Generally, ACCUMULATE_OUTGOING_ARGS enlarge the frame size.

Denis.

PS: I didn't try ACCUMULATE_OUTGOING_ARGS for AVR. May be results will
be better than I think.

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-01 18:43 ` Georg-Johann Lay
@ 2011-08-01 18:47   ` Richard Henderson
  2011-08-01 19:53     ` Denis Chertykov
  2011-08-03 12:16     ` Georg-Johann Lay
  0 siblings, 2 replies; 33+ messages in thread
From: Richard Henderson @ 2011-08-01 18:47 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: GCC Patches, bernds, iant, Denis Chertykov

On 08/01/2011 11:42 AM, Georg-Johann Lay wrote:
> Is there a specific reason not to define
> ACCUMULATE_OUTGOING_ARGS on AVR?

Yes.  So that you can use PUSH.  But as I said in PR49881,
you probably want to provide -maccumulate-outgoing-args.

I have a follow-up patch to the last one in that PR...


r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* Re: [RFC] Cleanup DW_CFA_GNU_args_size handling
  2011-08-01 17:40 Richard Henderson
@ 2011-08-01 18:43 ` Georg-Johann Lay
  2011-08-01 18:47   ` Richard Henderson
  2011-08-02  2:00 ` Richard Henderson
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 33+ messages in thread
From: Georg-Johann Lay @ 2011-08-01 18:43 UTC (permalink / raw)
  To: GCC Patches; +Cc: Richard Henderson, bernds, iant, Denis Chertykov

Richard Henderson schrieb:
> This is related primarily to PR49864 but also to PR49879.
> 
> The fundamental problem in the first test case is that the
> AVR target cannot perform
> 
>    (set (stack-pointer-rtx)
> 	(plus (stack-pointer-rtx) (const_int large)))
> 
> where "large" is in fact really quite small.  This gets
> dutifully reloaded to
> 
>    (set (reg temp) (stack-pointer-rtx))
> 
>    (set (reg temp) (plus (reg temp) (const_int large)))
> 
>    (set (stack-pointer-rtx) (reg temp))
> 
> which, we have to admit, is perfectly reasonable.
> 
> The code that we had in stack_adjust_offset would not
> properly handle anything except immediate addends to
> the stack pointer.  Indeed, if it saw any other sort
> of stack pointer adjustment, it gave up and assumed 
> that we'd reset the args_size level to 0.
> 
> This exact problem hasn't shown up on other targets
> either (1) because they ACCUMULATE_OUTGOING_ARGS, or
> (2) while they may not be able to handle very large
> addends to the stack pointer, we usually don't let
> the pushed arguments grow to very large numbers; we
> regularly reduce stack_pointer_delta.
> 
> AVR is special in that it can't *really* perform any
> direct addition to the stack pointer at all; "large"
> is non-zero only because of a peephole pattern to use
> pop insns into a scratch register for small adjustments.

In CCing Denis.

http://gcc.gnu.org/ml/gcc-patches/2011-08/msg00075.html

Is there a specific reason not to define
ACCUMULATE_OUTGOING_ARGS on AVR?

Addind/subtracting to SP is very expensive on AVR, even
IRQs have to be disabled.

Johann

> I briefly considered adding an insn pattern that would
> handle the entire mov/add/mov thing with a scratch, so
> that we wouldn't have to do anything special.  It seemed
> relatively unlikely that any other port would be this
> severely limited.
> 
> However, then came a look at the second PR, where we
> performed cross-jumping between two blocks with different
> args_size values.
> 
> For the specific case of the PR, this "merely" resulted
> in wrong-debug, because we would in fact generate invalid
> unwind info for one of the two paths.
> 
> That said, I see no reason why this same cross-jump could
> not occur with a real throw as opposed to an abort.  And
> in that case we would have wrong-code.
> 
> I consulted the IRC oracle, and Ian didn't have any 
> objections in principal to a new reg-note.
> 
> Comments?
> 
> r~

^ permalink raw reply	[flat|nested] 33+ messages in thread

* [RFC] Cleanup DW_CFA_GNU_args_size handling
@ 2011-08-01 17:40 Richard Henderson
  2011-08-01 18:43 ` Georg-Johann Lay
                   ` (3 more replies)
  0 siblings, 4 replies; 33+ messages in thread
From: Richard Henderson @ 2011-08-01 17:40 UTC (permalink / raw)
  To: GCC Patches; +Cc: bernds, avr, iant

[-- Attachment #1: Type: text/plain, Size: 2053 bytes --]

This is related primarily to PR49864 but also to PR49879.

The fundamental problem in the first test case is that the
AVR target cannot perform

   (set (stack-pointer-rtx)
	(plus (stack-pointer-rtx) (const_int large)))

where "large" is in fact really quite small.  This gets
dutifully reloaded to

   (set (reg temp) (stack-pointer-rtx))

   (set (reg temp) (plus (reg temp) (const_int large)))

   (set (stack-pointer-rtx) (reg temp))

which, we have to admit, is perfectly reasonable.

The code that we had in stack_adjust_offset would not
properly handle anything except immediate addends to
the stack pointer.  Indeed, if it saw any other sort
of stack pointer adjustment, it gave up and assumed 
that we'd reset the args_size level to 0.

This exact problem hasn't shown up on other targets
either (1) because they ACCUMULATE_OUTGOING_ARGS, or
(2) while they may not be able to handle very large
addends to the stack pointer, we usually don't let
the pushed arguments grow to very large numbers; we
regularly reduce stack_pointer_delta.

AVR is special in that it can't *really* perform any
direct addition to the stack pointer at all; "large"
is non-zero only because of a peephole pattern to use
pop insns into a scratch register for small adjustments.

I briefly considered adding an insn pattern that would
handle the entire mov/add/mov thing with a scratch, so
that we wouldn't have to do anything special.  It seemed
relatively unlikely that any other port would be this
severely limited.

However, then came a look at the second PR, where we
performed cross-jumping between two blocks with different
args_size values.

For the specific case of the PR, this "merely" resulted
in wrong-debug, because we would in fact generate invalid
unwind info for one of the two paths.

That said, I see no reason why this same cross-jump could
not occur with a real throw as opposed to an abort.  And
in that case we would have wrong-code.

I consulted the IRC oracle, and Ian didn't have any 
objections in principal to a new reg-note.

Comments?


r~

[-- Attachment #2: d-args-size-1 --]
[-- Type: text/plain, Size: 57504 bytes --]

	* reg-notes.def (REG_ARGS_SIZE): New.
	* calls.c (emit_call_1): Emit REG_ARGS_SIZE for call_pop.
	(expand_call): Add REG_ARGS_SIZE to emit_stack_restore.
	* cfgcleanup.c (old_insns_match_p): Don't allow cross-jumping to
	different stack levels.
	* combine-stack-adj.c (adjust_frame_related_expr): Remove.
	(maybe_move_args_size_note): New.
	(combine_stack_adjustments_for_block): Use it.
	* combine.c (distribute_notes): Place REG_ARGS_SIZE.
	* dwarf2cfi.c (dw_cfi_row_struct): Remove args_size member.
	(dw_trace_info): Add beg_true_args_size, end_true_args_size,
	beg_delay_args_size, end_delay_args_size, eh_head, args_size_undefined.
	(cur_cfa): New.
	(queued_args_size): Remove.
	(add_cfi_args_size): Assert size is non-negative.
	(stack_adjust_offset, dwarf2out_args_size): Remove.
	(dwarf2out_stack_adjust, dwarf2out_notice_stack_adjust): Remove.
	(notice_args_size, notice_eh_throw): New.
	(dwarf2out_frame_debug_def_cfa): Use cur_cfa.
	(dwarf2out_frame_debug_adjust_cfa): Likewise.
	(dwarf2out_frame_debug_cfa_offset): Likewise.
	(dwarf2out_frame_debug_expr): Likewise.  Don't stack_adjust_offset.
	(dwarf2out_frame_debug): Don't handle non-frame-related-p insns.
	(change_cfi_row): Don't emit args_size.
	(maybe_record_trace_start_abnormal): Split out from ...
	(maybe_record_trace_start): Here.  Set args_size_undefined.
	(create_trace_edges): Update to match.
	(scan_trace): Handle REG_ARGS_SIZE.
	(connect_traces): Connect args_size between EH insns.
	* emit-rtl.c (try_split): Handle REG_ARGS_SIZE.
	* explow.c (suppress_reg_args_size): New.
	(adjust_stack_1): Split out from ...
	(adjust_stack): ... here.
	(anti_adjust_stack): Use it.
	(allocate_dynamic_stack_space): Suppress REG_ARGS_SIZE.
	* expr.c (mem_autoinc_base): New.
	(fixup_args_size_notes): New.
	(emit_single_push_insn_1): Rename from emit_single_push_insn.
	(emit_single_push_insn): New.  Generate REG_ARGS_SIZE.
	* recog.c (peep2_attempt): Handle REG_ARGS_SIZE.
	* reload1.c (reload_as_needed): Likewise.
	* rtl.h (fixup_args_size_notes): Declare.



diff --git a/gcc/calls.c b/gcc/calls.c
index dfa9ceb..ab42fd6 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -434,6 +434,8 @@ emit_call_1 (rtx funexp, tree fntree ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
       rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
       stack_pointer_delta -= n_popped;
 
+      add_reg_note (call_insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+
       /* If popup is needed, stack realign must use DRAP  */
       if (SUPPORTS_STACK_ALIGNMENT)
         crtl->need_drap = true;
@@ -3126,8 +3128,19 @@ expand_call (tree exp, rtx target, int ignore)
 
       if (old_stack_level)
 	{
+	  rtx last, set;
+
 	  emit_stack_restore (SAVE_BLOCK, old_stack_level);
 	  stack_pointer_delta = old_stack_pointer_delta;
+
+	  /* ??? Is this assert warrented, given emit_stack_restore?
+	     or should we just mark the last insn no matter what?  */
+	  last = get_last_insn ();
+	  set = single_set (last);
+	  gcc_assert (set != NULL);
+	  gcc_assert (SET_DEST (set) == stack_pointer_rtx);
+	  add_reg_note (last, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+
 	  pending_stack_adjust = old_pending_adj;
 	  old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
 	  stack_arg_under_construction = old_stack_arg_under_construction;
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 7f72e68..7173013 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1078,6 +1078,16 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
   if (NOTE_INSN_BASIC_BLOCK_P (i1) && NOTE_INSN_BASIC_BLOCK_P (i2))
     return dir_both;
 
+  /* ??? Do not allow cross-jumping between different stack levels.  */
+  p1 = find_reg_note (i1, REG_ARGS_SIZE, NULL);
+  p2 = find_reg_note (i2, REG_ARGS_SIZE, NULL);
+  if (p1)
+    p1 = XEXP (p1, 0);
+  if (p2)
+    p2 = XEXP (p2, 0);
+  if (!rtx_equal_p (p1, p2))
+    return dir_none;
+
   p1 = PATTERN (i1);
   p2 = PATTERN (i2);
 
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index d267b70..bca0784 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -296,68 +296,22 @@ record_stack_refs (rtx *xp, void *data)
   return 0;
 }
 
-/* Adjust or create REG_FRAME_RELATED_EXPR note when merging a stack
-   adjustment into a frame related insn.  */
+/* If INSN has a REG_ARGS_SIZE note, move it to LAST.  */
 
 static void
-adjust_frame_related_expr (rtx last_sp_set, rtx insn,
-			   HOST_WIDE_INT this_adjust)
+maybe_move_args_size_note (rtx last, rtx insn)
 {
-  rtx note = find_reg_note (last_sp_set, REG_FRAME_RELATED_EXPR, NULL_RTX);
-  rtx new_expr = NULL_RTX;
+  rtx note, last_note;
 
-  if (note == NULL_RTX && RTX_FRAME_RELATED_P (insn))
+  note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
+  if (note == NULL)
     return;
 
-  if (note
-      && GET_CODE (XEXP (note, 0)) == SEQUENCE
-      && XVECLEN (XEXP (note, 0), 0) >= 2)
-    {
-      rtx expr = XEXP (note, 0);
-      rtx last = XVECEXP (expr, 0, XVECLEN (expr, 0) - 1);
-      int i;
-
-      if (GET_CODE (last) == SET
-	  && RTX_FRAME_RELATED_P (last) == RTX_FRAME_RELATED_P (insn)
-	  && SET_DEST (last) == stack_pointer_rtx
-	  && GET_CODE (SET_SRC (last)) == PLUS
-	  && XEXP (SET_SRC (last), 0) == stack_pointer_rtx
-	  && CONST_INT_P (XEXP (SET_SRC (last), 1)))
-	{
-	  XEXP (SET_SRC (last), 1)
-	    = GEN_INT (INTVAL (XEXP (SET_SRC (last), 1)) + this_adjust);
-	  return;
-	}
-
-      new_expr = gen_rtx_SEQUENCE (VOIDmode,
-				   rtvec_alloc (XVECLEN (expr, 0) + 1));
-      for (i = 0; i < XVECLEN (expr, 0); i++)
-	XVECEXP (new_expr, 0, i) = XVECEXP (expr, 0, i);
-    }
-  else
-    {
-      new_expr = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (2));
-      if (note)
-	XVECEXP (new_expr, 0, 0) = XEXP (note, 0);
-      else
-	{
-	  rtx expr = copy_rtx (single_set_for_csa (last_sp_set));
-
-	  XEXP (SET_SRC (expr), 1)
-	    = GEN_INT (INTVAL (XEXP (SET_SRC (expr), 1)) - this_adjust);
-	  RTX_FRAME_RELATED_P (expr) = 1;
-	  XVECEXP (new_expr, 0, 0) = expr;
-	}
-    }
-
-  XVECEXP (new_expr, 0, XVECLEN (new_expr, 0) - 1)
-    = copy_rtx (single_set_for_csa (insn));
-  RTX_FRAME_RELATED_P (XVECEXP (new_expr, 0, XVECLEN (new_expr, 0) - 1))
-    = RTX_FRAME_RELATED_P (insn);
-  if (note)
-    XEXP (note, 0) = new_expr;
+  last_note = find_reg_note (last, REG_ARGS_SIZE, NULL_RTX);
+  if (last_note)
+    XEXP (last_note, 0) = XEXP (note, 0);
   else
-    add_reg_note (last_sp_set, REG_FRAME_RELATED_EXPR, new_expr);
+    add_reg_note (last, REG_ARGS_SIZE, XEXP (note, 0));
 }
 
 /* Subroutine of combine_stack_adjustments, called for each basic block.  */
@@ -431,9 +385,8 @@ combine_stack_adjustments_for_block (basic_block bb)
 						  last_sp_adjust + this_adjust,
 						  this_adjust))
 		    {
-		      if (RTX_FRAME_RELATED_P (last_sp_set))
-			adjust_frame_related_expr (last_sp_set, insn,
-						   this_adjust);
+		      maybe_move_args_size_note (last_sp_set, insn);
+
 		      /* It worked!  */
 		      delete_insn (insn);
 		      last_sp_adjust += this_adjust;
diff --git a/gcc/combine.c b/gcc/combine.c
index b5cf245..c24f081 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13273,6 +13273,16 @@ distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2, rtx elim_i2,
 	    }
 	  break;
 
+	case REG_ARGS_SIZE:
+	  {
+	    /* ??? How to distribute between i3-i1.  Assume i3 contains the
+	       entire adjustment.  Assert i3 contains at least some adjust.  */
+	    int old_size, args_size = INTVAL (XEXP (note, 0));
+	    old_size = fixup_args_size_notes (PREV_INSN (i3), i3, args_size);
+	    gcc_assert (old_size != args_size);
+	  }
+	  break;
+
 	case REG_NORETURN:
 	case REG_SETJMP:
 	  /* These notes must remain with the call.  It should not be
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 99b37ab..5757d1d 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -70,9 +70,6 @@ typedef struct GTY(()) dw_cfi_row_struct
 
   /* The expressions for any register column that is saved.  */
   cfi_vec reg_save;
-
-  /* The value of any DW_CFA_GNU_args_size.  */
-  HOST_WIDE_INT args_size;
 } dw_cfi_row;
 
 /* The caller's ORIG_REG is saved in SAVED_IN_REG.  */
@@ -109,6 +106,16 @@ typedef struct
   /* The row state at the beginning and end of the trace.  */
   dw_cfi_row *beg_row, *end_row;
 
+  /* Tracking for DW_CFA_GNU_args_size.  The "true" sizes are those we find
+     while scanning insns.  However, the args_size value is irrelevant at
+     any point except can_throw_internal_p insns.  Therefore the "delay"
+     sizes the values that must actually be emitted for this trace.  */
+  HOST_WIDE_INT beg_true_args_size, end_true_args_size;
+  HOST_WIDE_INT beg_delay_args_size, end_delay_args_size;
+
+  /* The first EH insn in the trace, where beg_delay_args_size must be set.  */
+  rtx eh_head;
+
   /* The following variables contain data used in interpreting frame related
      expressions.  These are not part of the "real" row state as defined by
      Dwarf, but it seems like they need to be propagated into a trace in case
@@ -141,6 +148,9 @@ typedef struct
 
   /* True if this trace immediately follows NOTE_INSN_SWITCH_TEXT_SECTIONS.  */
   bool switch_sections;
+
+  /* True if we've seen different values incoming to beg_true_args_size.  */
+  bool args_size_undefined;
 } dw_trace_info;
 
 DEF_VEC_O (dw_trace_info);
@@ -179,6 +189,10 @@ static dw_trace_info *cur_trace;
 /* The current, i.e. most recently generated, row of the CFI table.  */
 static dw_cfi_row *cur_row;
 
+/* A copy of the current CFA, for use during the processing of a
+   single insn.  */
+static dw_cfa_location *cur_cfa;
+
 /* We delay emitting a register save until either (a) we reach the end
    of the prologue or (b) the register is clobbered.  This clusters
    register saves so that there are fewer pc advances.  */
@@ -194,10 +208,6 @@ DEF_VEC_ALLOC_O (queued_reg_save, heap);
 
 static VEC(queued_reg_save, heap) *queued_reg_saves;
 
-/* The (really) current value for DW_CFA_GNU_args_size.  We delay actually
-   emitting this data, i.e. updating CUR_ROW, without async unwind.  */
-static HOST_WIDE_INT queued_args_size;
-
 /* True if any CFI directives were emitted at the current insn.  */
 static bool any_cfis_emitted;
 
@@ -413,6 +423,10 @@ add_cfi_args_size (HOST_WIDE_INT size)
 {
   dw_cfi_ref cfi = new_cfi ();
 
+  /* While we can occasionally have args_size < 0 internally, this state
+     should not persist at a point we actually need an opcode.  */
+  gcc_assert (size >= 0);
+
   cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
   cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
 
@@ -663,16 +677,6 @@ cfi_row_equal_p (dw_cfi_row *a, dw_cfi_row *b)
   else if (!cfa_equal_p (&a->cfa, &b->cfa))
     return false;
 
-  /* Logic suggests that we compare args_size here.  However, if
-     EXIT_IGNORE_STACK we don't bother tracking the args_size after
-     the last time it really matters within the function.  This does
-     in fact lead to paths with differing arg_size, but in cases for
-     which it doesn't matter.  */
-  /* ??? If we really want to sanity check the output of the optimizers,
-     find a way to backtrack from epilogues to the last EH site.  This
-     would allow us to distinguish regions with garbage args_size and
-     regions where paths ought to agree.  */
-
   n_a = VEC_length (dw_cfi_ref, a->reg_save);
   n_b = VEC_length (dw_cfi_ref, b->reg_save);
   n_max = MAX (n_a, n_b);
@@ -836,214 +840,66 @@ reg_save (unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
   update_row_reg_save (cur_row, reg, cfi);
 }
 
-/* Given a SET, calculate the amount of stack adjustment it
-   contains.  */
-
-static HOST_WIDE_INT
-stack_adjust_offset (const_rtx pattern, HOST_WIDE_INT cur_args_size,
-		     HOST_WIDE_INT cur_offset)
-{
-  const_rtx src = SET_SRC (pattern);
-  const_rtx dest = SET_DEST (pattern);
-  HOST_WIDE_INT offset = 0;
-  enum rtx_code code;
-
-  if (dest == stack_pointer_rtx)
-    {
-      code = GET_CODE (src);
-
-      /* Assume (set (reg sp) (reg whatever)) sets args_size
-	 level to 0.  */
-      if (code == REG && src != stack_pointer_rtx)
-	{
-	  offset = -cur_args_size;
-#ifndef STACK_GROWS_DOWNWARD
-	  offset = -offset;
-#endif
-	  return offset - cur_offset;
-	}
-
-      if (! (code == PLUS || code == MINUS)
-	  || XEXP (src, 0) != stack_pointer_rtx
-	  || !CONST_INT_P (XEXP (src, 1)))
-	return 0;
-
-      /* (set (reg sp) (plus (reg sp) (const_int))) */
-      offset = INTVAL (XEXP (src, 1));
-      if (code == PLUS)
-	offset = -offset;
-      return offset;
-    }
-
-  if (MEM_P (src) && !MEM_P (dest))
-    dest = src;
-  if (MEM_P (dest))
-    {
-      /* (set (mem (pre_dec (reg sp))) (foo)) */
-      src = XEXP (dest, 0);
-      code = GET_CODE (src);
-
-      switch (code)
-	{
-	case PRE_MODIFY:
-	case POST_MODIFY:
-	  if (XEXP (src, 0) == stack_pointer_rtx)
-	    {
-	      rtx val = XEXP (XEXP (src, 1), 1);
-	      /* We handle only adjustments by constant amount.  */
-	      gcc_assert (GET_CODE (XEXP (src, 1)) == PLUS
-			  && CONST_INT_P (val));
-	      offset = -INTVAL (val);
-	      break;
-	    }
-	  return 0;
-
-	case PRE_DEC:
-	case POST_DEC:
-	  if (XEXP (src, 0) == stack_pointer_rtx)
-	    {
-	      offset = GET_MODE_SIZE (GET_MODE (dest));
-	      break;
-	    }
-	  return 0;
-
-	case PRE_INC:
-	case POST_INC:
-	  if (XEXP (src, 0) == stack_pointer_rtx)
-	    {
-	      offset = -GET_MODE_SIZE (GET_MODE (dest));
-	      break;
-	    }
-	  return 0;
-
-	default:
-	  return 0;
-	}
-    }
-  else
-    return 0;
-
-  return offset;
-}
-
-/* Add a CFI to update the running total of the size of arguments
-   pushed onto the stack.  */
+/* A subroutine of scan_trace.  Check INSN for a REG_ARGS_SIZE note
+   and adjust data structures to match.  */
 
 static void
-dwarf2out_args_size (HOST_WIDE_INT size)
+notice_args_size (rtx insn)
 {
-  if (size == cur_row->args_size)
-    return;
-
-  cur_row->args_size = size;
-  add_cfi_args_size (size);
-}
+  HOST_WIDE_INT args_size, delta;
+  rtx note;
 
-/* Record a stack adjustment of OFFSET bytes.  */
-
-static void
-dwarf2out_stack_adjust (HOST_WIDE_INT offset)
-{
-  dw_cfa_location loc = cur_row->cfa;
+  note = find_reg_note (insn, REG_ARGS_SIZE, NULL);
+  if (note == NULL)
+    return;
 
-  if (loc.reg == dw_stack_pointer_regnum)
-    loc.offset += offset;
+  args_size = INTVAL (XEXP (note, 0));
+  delta = args_size - cur_trace->end_true_args_size;
+  if (delta == 0)
+    return;
 
-  if (cur_trace->cfa_store.reg == dw_stack_pointer_regnum)
-    cur_trace->cfa_store.offset += offset;
+  cur_trace->end_true_args_size = args_size;
 
-  /* ??? The assumption seems to be that if A_O_A, the only CFA adjustments
-     involving the stack pointer are inside the prologue and marked as
-     RTX_FRAME_RELATED_P.  That said, should we not verify this assumption
-     by *asserting* A_O_A at this point?  Why else would we have a change
-     to the stack pointer?  */
-  if (ACCUMULATE_OUTGOING_ARGS)
-    return;
+  /* If the CFA is computed off the stack pointer, then we must adjust
+     the computation of the CFA as well.  */
+  if (cur_cfa->reg == dw_stack_pointer_regnum)
+    {
+      gcc_assert (!cur_cfa->indirect);
 
+      /* Convert a change in args_size (always a positive in the
+	 direction of stack growth) to a change in stack pointer.  */
 #ifndef STACK_GROWS_DOWNWARD
-  offset = -offset;
+      delta = -delta;
 #endif
-
-  queued_args_size += offset;
-  if (queued_args_size < 0)
-    queued_args_size = 0;
-
-  def_cfa_1 (&loc);
-  if (flag_asynchronous_unwind_tables)
-    dwarf2out_args_size (queued_args_size);
+      cur_cfa->offset += delta;
+    }
 }
 
-/* Check INSN to see if it looks like a push or a stack adjustment, and
-   make a note of it if it does.  EH uses this information to find out
-   how much extra space it needs to pop off the stack.  */
+/* A subroutine of scan_trace.  INSN is can_throw_internal.  Update the
+   data within the trace related to EH insns and args_size.  */
 
 static void
-dwarf2out_notice_stack_adjust (rtx insn, bool after_p)
+notice_eh_throw (rtx insn)
 {
-  HOST_WIDE_INT offset;
-  int i;
-
-  /* Don't handle epilogues at all.  Certainly it would be wrong to do so
-     with this function.  Proper support would require all frame-related
-     insns to be marked, and to be able to handle saving state around
-     epilogues textually in the middle of the function.  */
-  if (prologue_epilogue_contains (insn))
-    return;
-
-  /* If INSN is an instruction from target of an annulled branch, the
-     effects are for the target only and so current argument size
-     shouldn't change at all.  */
-  if (final_sequence
-      && INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))
-      && INSN_FROM_TARGET_P (insn))
-    return;
+  HOST_WIDE_INT args_size;
 
-  /* If only calls can throw, and we have a frame pointer,
-     save up adjustments until we see the CALL_INSN.  */
-  if (!flag_asynchronous_unwind_tables
-      && cur_row->cfa.reg != dw_stack_pointer_regnum)
+  args_size = cur_trace->end_true_args_size;
+  if (cur_trace->eh_head == NULL)
     {
-      if (CALL_P (insn) && !after_p)
-	{
-	  /* Extract the size of the args from the CALL rtx itself.  */
-	  insn = PATTERN (insn);
-	  if (GET_CODE (insn) == PARALLEL)
-	    insn = XVECEXP (insn, 0, 0);
-	  if (GET_CODE (insn) == SET)
-	    insn = SET_SRC (insn);
-	  gcc_assert (GET_CODE (insn) == CALL);
-	  dwarf2out_args_size (INTVAL (XEXP (insn, 1)));
-	}
-      return;
+      cur_trace->eh_head = insn;
+      cur_trace->beg_delay_args_size = args_size;
+      cur_trace->end_delay_args_size = args_size;
     }
-
-  if (CALL_P (insn) && !after_p)
+  else if (cur_trace->end_delay_args_size != args_size)
     {
-      if (!flag_asynchronous_unwind_tables)
-	dwarf2out_args_size (queued_args_size);
-      return;
-    }
-  else if (BARRIER_P (insn))
-    return;
-  else if (GET_CODE (PATTERN (insn)) == SET)
-    offset = stack_adjust_offset (PATTERN (insn), queued_args_size, 0);
-  else if (GET_CODE (PATTERN (insn)) == PARALLEL
-	   || GET_CODE (PATTERN (insn)) == SEQUENCE)
-    {
-      /* There may be stack adjustments inside compound insns.  Search
-	 for them.  */
-      for (offset = 0, i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
-	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
-	  offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i),
-					 queued_args_size, offset);
-    }
-  else
-    return;
-
-  if (offset == 0)
-    return;
+      cur_trace->end_delay_args_size = args_size;
 
-  dwarf2out_stack_adjust (offset);
+      /* ??? If the CFA is the stack pointer, search backward for the last
+	 CFI note and insert there.  Given that the stack changed for the
+	 args_size change, there *must* be such a note in between here and
+	 the last eh insn.  */
+      add_cfi_args_size (args_size);
+    }
 }
 
 /* Short-hand inline for the very common D_F_R (REGNO (x)) operation.  */
@@ -1201,38 +1057,34 @@ reg_saved_in (rtx reg)
 static void
 dwarf2out_frame_debug_def_cfa (rtx pat)
 {
-  dw_cfa_location loc;
-
-  memset (&loc, 0, sizeof (loc));
+  memset (cur_cfa, 0, sizeof (*cur_cfa));
 
   switch (GET_CODE (pat))
     {
     case PLUS:
-      loc.reg = dwf_regno (XEXP (pat, 0));
-      loc.offset = INTVAL (XEXP (pat, 1));
+      cur_cfa->reg = dwf_regno (XEXP (pat, 0));
+      cur_cfa->offset = INTVAL (XEXP (pat, 1));
       break;
 
     case REG:
-      loc.reg = dwf_regno (pat);
+      cur_cfa->reg = dwf_regno (pat);
       break;
 
     case MEM:
-      loc.indirect = 1;
+      cur_cfa->indirect = 1;
       pat = XEXP (pat, 0);
       if (GET_CODE (pat) == PLUS)
 	{
-	  loc.base_offset = INTVAL (XEXP (pat, 1));
+	  cur_cfa->base_offset = INTVAL (XEXP (pat, 1));
 	  pat = XEXP (pat, 0);
 	}
-      loc.reg = dwf_regno (pat);
+      cur_cfa->reg = dwf_regno (pat);
       break;
 
     default:
       /* Recurse and define an expression.  */
       gcc_unreachable ();
     }
-
-  def_cfa_1 (&loc);
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_ADJUST_CFA note.  */
@@ -1240,7 +1092,6 @@ dwarf2out_frame_debug_def_cfa (rtx pat)
 static void
 dwarf2out_frame_debug_adjust_cfa (rtx pat)
 {
-  dw_cfa_location loc = cur_row->cfa;
   rtx src, dest;
 
   gcc_assert (GET_CODE (pat) == SET);
@@ -1250,21 +1101,19 @@ dwarf2out_frame_debug_adjust_cfa (rtx pat)
   switch (GET_CODE (src))
     {
     case PLUS:
-      gcc_assert (dwf_regno (XEXP (src, 0)) == loc.reg);
-      loc.offset -= INTVAL (XEXP (src, 1));
+      gcc_assert (dwf_regno (XEXP (src, 0)) == cur_cfa->reg);
+      cur_cfa->offset -= INTVAL (XEXP (src, 1));
       break;
 
     case REG:
-	break;
+      break;
 
     default:
-	gcc_unreachable ();
+      gcc_unreachable ();
     }
 
-  loc.reg = dwf_regno (dest);
-  gcc_assert (loc.indirect == 0);
-
-  def_cfa_1 (&loc);
+  cur_cfa->reg = dwf_regno (dest);
+  gcc_assert (cur_cfa->indirect == 0);
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_OFFSET note.  */
@@ -1285,12 +1134,12 @@ dwarf2out_frame_debug_cfa_offset (rtx set)
   switch (GET_CODE (addr))
     {
     case REG:
-      gcc_assert (dwf_regno (addr) == cur_row->cfa.reg);
-      offset = -cur_row->cfa.offset;
+      gcc_assert (dwf_regno (addr) == cur_cfa->reg);
+      offset = -cur_cfa->offset;
       break;
     case PLUS:
-      gcc_assert (dwf_regno (XEXP (addr, 0)) == cur_row->cfa.reg);
-      offset = INTVAL (XEXP (addr, 1)) - cur_row->cfa.offset;
+      gcc_assert (dwf_regno (XEXP (addr, 0)) == cur_cfa->reg);
+      offset = INTVAL (XEXP (addr, 1)) - cur_cfa->offset;
       break;
     default:
       gcc_unreachable ();
@@ -1458,7 +1307,7 @@ dwarf2out_frame_debug_cfa_window_save (void)
 
   cfa	       current rule for calculating the CFA.  It usually
 	       consists of a register and an offset.  This is
-	       actually stored in cur_row->cfa, but abbreviated
+	       actually stored in *cur_cfa, but abbreviated
 	       for the purposes of this documentation.
   cfa_store    register used by prologue code to save things to the stack
 	       cfa_store.offset is the offset from the value of
@@ -1613,7 +1462,6 @@ dwarf2out_frame_debug_cfa_window_save (void)
 static void
 dwarf2out_frame_debug_expr (rtx expr)
 {
-  dw_cfa_location cfa = cur_row->cfa;
   rtx src, dest, span;
   HOST_WIDE_INT offset;
   dw_fde_ref fde;
@@ -1651,18 +1499,6 @@ dwarf2out_frame_debug_expr (rtx expr)
 	      && (!MEM_P (SET_DEST (elem)) || GET_CODE (expr) == SEQUENCE)
 	      && (RTX_FRAME_RELATED_P (elem) || par_index == 0))
 	    dwarf2out_frame_debug_expr (elem);
-	  else if (GET_CODE (elem) == SET
-		   && par_index != 0
-		   && !RTX_FRAME_RELATED_P (elem))
-	    {
-	      /* Stack adjustment combining might combine some post-prologue
-		 stack adjustment into a prologue stack adjustment.  */
-	      HOST_WIDE_INT offset
-		= stack_adjust_offset (elem, queued_args_size, 0);
-
-	      if (offset != 0)
-		dwarf2out_stack_adjust (offset);
-	    }
 	}
       return;
     }
@@ -1688,7 +1524,7 @@ dwarf2out_frame_debug_expr (rtx expr)
 	{
 	  /* Setting FP from SP.  */
 	case REG:
-	  if (cfa.reg == dwf_regno (src))
+	  if (cur_cfa->reg == dwf_regno (src))
 	    {
 	      /* Rule 1 */
 	      /* Update the CFA rule wrt SP or FP.  Make sure src is
@@ -1698,9 +1534,9 @@ dwarf2out_frame_debug_expr (rtx expr)
 		 ARM copies SP to a temporary register, and from there to
 		 FP.  So we just rely on the backends to only set
 		 RTX_FRAME_RELATED_P on appropriate insns.  */
-	      cfa.reg = dwf_regno (dest);
-	      cur_trace->cfa_temp.reg = cfa.reg;
-	      cur_trace->cfa_temp.offset = cfa.offset;
+	      cur_cfa->reg = dwf_regno (dest);
+	      cur_trace->cfa_temp.reg = cur_cfa->reg;
+	      cur_trace->cfa_temp.offset = cur_cfa->offset;
 	    }
 	  else
 	    {
@@ -1718,7 +1554,7 @@ dwarf2out_frame_debug_expr (rtx expr)
 		  && REGNO (src) == STACK_POINTER_REGNUM)
 		gcc_assert (REGNO (dest) == HARD_FRAME_POINTER_REGNUM
 			    && fde->drap_reg != INVALID_REGNUM
-			    && cfa.reg != dwf_regno (src));
+			    && cur_cfa->reg != dwf_regno (src));
 	      else
 		queue_reg_save (src, dest, 0);
 	    }
@@ -1748,8 +1584,8 @@ dwarf2out_frame_debug_expr (rtx expr)
 	      if (XEXP (src, 0) == hard_frame_pointer_rtx)
 		{
 		  /* Restoring SP from FP in the epilogue.  */
-		  gcc_assert (cfa.reg == dw_frame_pointer_regnum);
-		  cfa.reg = dw_stack_pointer_regnum;
+		  gcc_assert (cur_cfa->reg == dw_frame_pointer_regnum);
+		  cur_cfa->reg = dw_stack_pointer_regnum;
 		}
 	      else if (GET_CODE (src) == LO_SUM)
 		/* Assume we've set the source reg of the LO_SUM from sp.  */
@@ -1759,8 +1595,8 @@ dwarf2out_frame_debug_expr (rtx expr)
 
 	      if (GET_CODE (src) != MINUS)
 		offset = -offset;
-	      if (cfa.reg == dw_stack_pointer_regnum)
-		cfa.offset += offset;
+	      if (cur_cfa->reg == dw_stack_pointer_regnum)
+		cur_cfa->offset += offset;
 	      if (cur_trace->cfa_store.reg == dw_stack_pointer_regnum)
 		cur_trace->cfa_store.offset += offset;
 	    }
@@ -1772,13 +1608,13 @@ dwarf2out_frame_debug_expr (rtx expr)
 	      gcc_assert (frame_pointer_needed);
 
 	      gcc_assert (REG_P (XEXP (src, 0))
-			  && dwf_regno (XEXP (src, 0)) == cfa.reg
+			  && dwf_regno (XEXP (src, 0)) == cur_cfa->reg
 			  && CONST_INT_P (XEXP (src, 1)));
 	      offset = INTVAL (XEXP (src, 1));
 	      if (GET_CODE (src) != MINUS)
 		offset = -offset;
-	      cfa.offset += offset;
-	      cfa.reg = dw_frame_pointer_regnum;
+	      cur_cfa->offset += offset;
+	      cur_cfa->reg = dw_frame_pointer_regnum;
 	    }
 	  else
 	    {
@@ -1786,17 +1622,17 @@ dwarf2out_frame_debug_expr (rtx expr)
 
 	      /* Rule 4 */
 	      if (REG_P (XEXP (src, 0))
-		  && dwf_regno (XEXP (src, 0)) == cfa.reg
+		  && dwf_regno (XEXP (src, 0)) == cur_cfa->reg
 		  && CONST_INT_P (XEXP (src, 1)))
 		{
 		  /* Setting a temporary CFA register that will be copied
 		     into the FP later on.  */
 		  offset = - INTVAL (XEXP (src, 1));
-		  cfa.offset += offset;
-		  cfa.reg = dwf_regno (dest);
+		  cur_cfa->offset += offset;
+		  cur_cfa->reg = dwf_regno (dest);
 		  /* Or used to save regs to the stack.  */
-		  cur_trace->cfa_temp.reg = cfa.reg;
-		  cur_trace->cfa_temp.offset = cfa.offset;
+		  cur_trace->cfa_temp.reg = cur_cfa->reg;
+		  cur_trace->cfa_temp.offset = cur_cfa->offset;
 		}
 
 	      /* Rule 5 */
@@ -1806,10 +1642,10 @@ dwarf2out_frame_debug_expr (rtx expr)
 		{
 		  /* Setting a scratch register that we will use instead
 		     of SP for saving registers to the stack.  */
-		  gcc_assert (cfa.reg == dw_stack_pointer_regnum);
+		  gcc_assert (cur_cfa->reg == dw_stack_pointer_regnum);
 		  cur_trace->cfa_store.reg = dwf_regno (dest);
 		  cur_trace->cfa_store.offset
-		    = cfa.offset - cur_trace->cfa_temp.offset;
+		    = cur_cfa->offset - cur_trace->cfa_temp.offset;
 		}
 
 	      /* Rule 9 */
@@ -1870,17 +1706,15 @@ dwarf2out_frame_debug_expr (rtx expr)
               fde->stack_realignment = INTVAL (XEXP (src, 1));
               cur_trace->cfa_store.offset = 0;
 
-	      if (cfa.reg != dw_stack_pointer_regnum
-		  && cfa.reg != dw_frame_pointer_regnum)
-		fde->drap_reg = cfa.reg;
+	      if (cur_cfa->reg != dw_stack_pointer_regnum
+		  && cur_cfa->reg != dw_frame_pointer_regnum)
+		fde->drap_reg = cur_cfa->reg;
             }
           return;
 
 	default:
 	  gcc_unreachable ();
 	}
-
-      def_cfa_1 (&cfa);
       break;
 
     case MEM:
@@ -1902,8 +1736,8 @@ dwarf2out_frame_debug_expr (rtx expr)
 		      && cur_trace->cfa_store.reg == dw_stack_pointer_regnum);
 
 	  cur_trace->cfa_store.offset += offset;
-	  if (cfa.reg == dw_stack_pointer_regnum)
-	    cfa.offset = cur_trace->cfa_store.offset;
+	  if (cur_cfa->reg == dw_stack_pointer_regnum)
+	    cur_cfa->offset = cur_trace->cfa_store.offset;
 
 	  if (GET_CODE (XEXP (dest, 0)) == POST_MODIFY)
 	    offset -= cur_trace->cfa_store.offset;
@@ -1932,12 +1766,12 @@ dwarf2out_frame_debug_expr (rtx expr)
               && fde->stack_realign
               && src == hard_frame_pointer_rtx)
 	    {
-	      gcc_assert (cfa.reg != dw_frame_pointer_regnum);
+	      gcc_assert (cur_cfa->reg != dw_frame_pointer_regnum);
 	      cur_trace->cfa_store.offset = 0;
 	    }
 
-	  if (cfa.reg == dw_stack_pointer_regnum)
-	    cfa.offset = cur_trace->cfa_store.offset;
+	  if (cur_cfa->reg == dw_stack_pointer_regnum)
+	    cur_cfa->offset = cur_trace->cfa_store.offset;
 
 	  if (GET_CODE (XEXP (dest, 0)) == POST_DEC)
 	    offset += -cur_trace->cfa_store.offset;
@@ -1961,8 +1795,8 @@ dwarf2out_frame_debug_expr (rtx expr)
 
 	    regno = dwf_regno (XEXP (XEXP (dest, 0), 0));
 
-	    if (cfa.reg == regno)
-	      offset -= cfa.offset;
+	    if (cur_cfa->reg == regno)
+	      offset -= cur_cfa->offset;
 	    else if (cur_trace->cfa_store.reg == regno)
 	      offset -= cur_trace->cfa_store.offset;
 	    else
@@ -1979,8 +1813,8 @@ dwarf2out_frame_debug_expr (rtx expr)
 	  {
 	    unsigned int regno = dwf_regno (XEXP (dest, 0));
 
-	    if (cfa.reg == regno)
-	      offset = -cfa.offset;
+	    if (cur_cfa->reg == regno)
+	      offset = -cur_cfa->offset;
 	    else if (cur_trace->cfa_store.reg == regno)
 	      offset = -cur_trace->cfa_store.offset;
 	    else
@@ -2012,11 +1846,11 @@ dwarf2out_frame_debug_expr (rtx expr)
       if (REG_P (src)
 	  && REGNO (src) != STACK_POINTER_REGNUM
 	  && REGNO (src) != HARD_FRAME_POINTER_REGNUM
-	  && dwf_regno (src) == cfa.reg)
+	  && dwf_regno (src) == cur_cfa->reg)
 	{
 	  /* We're storing the current CFA reg into the stack.  */
 
-	  if (cfa.offset == 0)
+	  if (cur_cfa->offset == 0)
 	    {
               /* Rule 19 */
               /* If stack is aligned, putting CFA reg into stack means
@@ -2026,28 +1860,23 @@ dwarf2out_frame_debug_expr (rtx expr)
 		 value.  */
               if (fde
                   && fde->stack_realign
-                  && cfa.indirect == 0
-                  && cfa.reg != dw_frame_pointer_regnum)
+                  && cur_cfa->indirect == 0
+                  && cur_cfa->reg != dw_frame_pointer_regnum)
                 {
-		  dw_cfa_location cfa_exp;
-
-		  gcc_assert (fde->drap_reg == cfa.reg);
+		  gcc_assert (fde->drap_reg == cur_cfa->reg);
 
-		  cfa_exp.indirect = 1;
-		  cfa_exp.reg = dw_frame_pointer_regnum;
-		  cfa_exp.base_offset = offset;
-		  cfa_exp.offset = 0;
+		  cur_cfa->indirect = 1;
+		  cur_cfa->reg = dw_frame_pointer_regnum;
+		  cur_cfa->base_offset = offset;
+		  cur_cfa->offset = 0;
 
 		  fde->drap_reg_saved = 1;
-
-		  def_cfa_1 (&cfa_exp);
 		  break;
                 }
 
 	      /* If the source register is exactly the CFA, assume
 		 we're saving SP like any other register; this happens
 		 on the ARM.  */
-	      def_cfa_1 (&cfa);
 	      queue_reg_save (stack_pointer_rtx, NULL_RTX, offset);
 	      break;
 	    }
@@ -2061,16 +1890,13 @@ dwarf2out_frame_debug_expr (rtx expr)
 		x = XEXP (x, 0);
 	      gcc_assert (REG_P (x));
 
-	      cfa.reg = dwf_regno (x);
-	      cfa.base_offset = offset;
-	      cfa.indirect = 1;
-	      def_cfa_1 (&cfa);
+	      cur_cfa->reg = dwf_regno (x);
+	      cur_cfa->base_offset = offset;
+	      cur_cfa->indirect = 1;
 	      break;
 	    }
 	}
 
-      def_cfa_1 (&cfa);
-
       span = NULL;
       if (REG_P (src))
 	span = targetm.dwarf_register_span (src);
@@ -2101,33 +1927,17 @@ dwarf2out_frame_debug_expr (rtx expr)
     }
 }
 
-/* Record call frame debugging information for INSN, which either
-   sets SP or FP (adjusting how we calculate the frame address) or saves a
-   register to the stack.  If INSN is NULL_RTX, initialize our state.
-
-   If AFTER_P is false, we're being called before the insn is emitted,
-   otherwise after.  Call instructions get invoked twice.  */
+/* Record call frame debugging information for INSN, which either sets
+   SP or FP (adjusting how we calculate the frame address) or saves a
+   register to the stack.  */
 
 static void
-dwarf2out_frame_debug (rtx insn, bool after_p)
+dwarf2out_frame_debug (rtx insn)
 {
   rtx note, n;
   bool handled_one = false;
   bool need_flush = false;
 
-  if (!NONJUMP_INSN_P (insn) || clobbers_queued_reg_save (insn))
-    dwarf2out_flush_queued_reg_saves ();
-
-  if (!RTX_FRAME_RELATED_P (insn))
-    {
-      /* ??? This should be done unconditionally since stack adjustments
-	 matter if the stack pointer is not the CFA register anymore but
-	 is still used to save registers.  */
-      if (!ACCUMULATE_OUTGOING_ARGS)
-	dwarf2out_notice_stack_adjust (insn, after_p);
-      return;
-    }
-
   any_cfis_emitted = false;
 
   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
@@ -2265,9 +2075,6 @@ change_cfi_row (dw_cfi_row *old_row, dw_cfi_row *new_row)
 	add_cfi (cfi);
     }
 
-  if (old_row->args_size != new_row->args_size)
-    add_cfi_args_size (new_row->args_size);
-
   n_old = VEC_length (dw_cfi_ref, old_row->reg_save);
   n_new = VEC_length (dw_cfi_ref, new_row->reg_save);
   n_max = MAX (n_old, n_new);
@@ -2391,14 +2198,10 @@ add_cfis_to_fde (void)
    trace from CUR_TRACE and CUR_ROW.  */
 
 static void
-maybe_record_trace_start (rtx start, rtx origin, bool abnormal)
+maybe_record_trace_start (rtx start, rtx origin)
 {
   dw_trace_info *ti;
-
-  /* Sync queued data before propagating to a destination,
-     lest we propagate out-of-date data.  */
-  dwarf2out_flush_queued_reg_saves ();
-  dwarf2out_args_size (queued_args_size);
+  HOST_WIDE_INT args_size;
 
   ti = get_trace_info (start);
   gcc_assert (ti != NULL);
@@ -2411,15 +2214,13 @@ maybe_record_trace_start (rtx start, rtx origin, bool abnormal)
 	       (origin ? INSN_UID (origin) : 0));
     }
 
+  args_size = cur_trace->end_true_args_size;
   if (ti->beg_row == NULL)
     {
       /* This is the first time we've encountered this trace.  Propagate
 	 state across the edge and push the trace onto the work list.  */
       ti->beg_row = copy_cfi_row (cur_row);
-      /* On all abnormal edges, especially EH and non-local-goto, we take
-	 care to free the pushed arguments.  */
-      if (abnormal)
-	ti->beg_row->args_size = 0;
+      ti->beg_true_args_size = args_size;
 
       ti->cfa_store = cur_trace->cfa_store;
       ti->cfa_temp = cur_trace->cfa_temp;
@@ -2433,11 +2234,52 @@ maybe_record_trace_start (rtx start, rtx origin, bool abnormal)
     }
   else
     {
+
       /* We ought to have the same state incoming to a given trace no
 	 matter how we arrive at the trace.  Anything else means we've
 	 got some kind of optimization error.  */
       gcc_checking_assert (cfi_row_equal_p (cur_row, ti->beg_row));
+
+      /* The args_size is allowed to conflict if it isn't actually used.  */
+      if (ti->beg_true_args_size != args_size)
+	ti->args_size_undefined = true;
+    }
+}
+
+/* Similarly, but handle the args_size and CFA reset across EH
+   and non-local goto edges.  */
+
+static void
+maybe_record_trace_start_abnormal (rtx start, rtx origin)
+{
+  HOST_WIDE_INT save_args_size, delta;
+  dw_cfa_location save_cfa;
+
+  save_args_size = cur_trace->end_true_args_size;
+  if (save_args_size == 0)
+    {
+      maybe_record_trace_start (start, origin);
+      return;
+    }
+
+  delta = -save_args_size;
+  cur_trace->end_true_args_size = 0;
+
+  save_cfa = cur_row->cfa;
+  if (cur_row->cfa.reg == dw_stack_pointer_regnum)
+    {
+      /* Convert a change in args_size (always a positive in the
+	 direction of stack growth) to a change in stack pointer.  */
+#ifndef STACK_GROWS_DOWNWARD
+      delta = -delta;
+#endif
+      cur_row->cfa.offset += delta;
     }
+  
+  maybe_record_trace_start (start, origin);
+
+  cur_trace->end_true_args_size = save_args_size;
+  cur_row->cfa = save_cfa;
 }
 
 /* Propagate CUR_TRACE state to the destinations implied by INSN.  */
@@ -2452,8 +2294,9 @@ create_trace_edges (rtx insn)
   if (JUMP_P (insn))
     {
       if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
-	;
-      else if (tablejump_p (insn, NULL, &tmp))
+	return;
+
+      if (tablejump_p (insn, NULL, &tmp))
 	{
 	  rtvec vec;
 
@@ -2464,13 +2307,13 @@ create_trace_edges (rtx insn)
 	  for (i = 0; i < n; ++i)
 	    {
 	      lab = XEXP (RTVEC_ELT (vec, i), 0);
-	      maybe_record_trace_start (lab, insn, false);
+	      maybe_record_trace_start (lab, insn);
 	    }
 	}
       else if (computed_jump_p (insn))
 	{
 	  for (lab = forced_labels; lab; lab = XEXP (lab, 1))
-	    maybe_record_trace_start (XEXP (lab, 0), insn, true);
+	    maybe_record_trace_start (XEXP (lab, 0), insn);
 	}
       else if (returnjump_p (insn))
 	;
@@ -2480,14 +2323,14 @@ create_trace_edges (rtx insn)
 	  for (i = 0; i < n; ++i)
 	    {
 	      lab = XEXP (ASM_OPERANDS_LABEL (tmp, i), 0);
-	      maybe_record_trace_start (lab, insn, true);
+	      maybe_record_trace_start (lab, insn);
 	    }
 	}
       else
 	{
 	  lab = JUMP_LABEL (insn);
 	  gcc_assert (lab != NULL);
-	  maybe_record_trace_start (lab, insn, false);
+	  maybe_record_trace_start (lab, insn);
 	}
     }
   else if (CALL_P (insn))
@@ -2499,7 +2342,7 @@ create_trace_edges (rtx insn)
       /* Process non-local goto edges.  */
       if (can_nonlocal_goto (insn))
 	for (lab = nonlocal_goto_handler_labels; lab; lab = XEXP (lab, 1))
-	  maybe_record_trace_start (XEXP (lab, 0), insn, true);
+	  maybe_record_trace_start_abnormal (XEXP (lab, 0), insn);
     }
   else if (GET_CODE (PATTERN (insn)) == SEQUENCE)
     {
@@ -2515,7 +2358,7 @@ create_trace_edges (rtx insn)
     {
       eh_landing_pad lp = get_eh_landing_pad_from_rtx (insn);
       if (lp)
-	maybe_record_trace_start (lp->landing_pad, insn, true);
+	maybe_record_trace_start_abnormal (lp->landing_pad, insn);
     }
 }
 
@@ -2526,6 +2369,7 @@ static void
 scan_trace (dw_trace_info *trace)
 {
   rtx insn = trace->head;
+  dw_cfa_location this_cfa;
 
   if (dump_file)
     fprintf (dump_file, "Processing trace %u : start at %s %d\n",
@@ -2533,61 +2377,99 @@ scan_trace (dw_trace_info *trace)
 	     INSN_UID (insn));
 
   trace->end_row = copy_cfi_row (trace->beg_row);
+  trace->end_true_args_size = trace->beg_true_args_size;
 
   cur_trace = trace;
   cur_row = trace->end_row;
-  queued_args_size = cur_row->args_size;
+
+  this_cfa = cur_row->cfa;
+  cur_cfa = &this_cfa;
 
   for (insn = NEXT_INSN (insn); insn ; insn = NEXT_INSN (insn))
     {
-      rtx pat;
-
+      /* Do everything that happens "before" the insn.  */
       add_cfi_insn = PREV_INSN (insn);
 
       /* Notice the end of a trace.  */
-      if (BARRIER_P (insn) || save_point_p (insn))
+      if (BARRIER_P (insn))
+	{
+	  /* Don't bother saving the unneeded queued registers at all.  */
+	  VEC_truncate (queued_reg_save, queued_reg_saves, 0);
+	  break;
+	}
+      if (save_point_p (insn))
 	{
-	  dwarf2out_flush_queued_reg_saves ();
-	  dwarf2out_args_size (queued_args_size);
-
 	  /* Propagate across fallthru edges.  */
-	  if (!BARRIER_P (insn))
-	    maybe_record_trace_start (insn, NULL, false);
+	  dwarf2out_flush_queued_reg_saves ();
+	  maybe_record_trace_start (insn, NULL);
 	  break;
 	}
 
       if (DEBUG_INSN_P (insn) || !inside_basic_block_p (insn))
 	continue;
 
-      pat = PATTERN (insn);
-      if (asm_noperands (pat) >= 0)
+      /* Flush data before calls and jumps, and of course if necessary.  */
+      if (can_throw_internal (insn))
 	{
-	  dwarf2out_frame_debug (insn, false);
-	  add_cfi_insn = insn;
+	  dwarf2out_flush_queued_reg_saves ();
+	  notice_eh_throw (insn);
 	}
-      else
+      else if (!NONJUMP_INSN_P (insn)
+	       || clobbers_queued_reg_save (insn)
+	       || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
+	dwarf2out_flush_queued_reg_saves ();
+
+      /* Do everything that happens "after" the insn.  */
+      add_cfi_insn = insn;
+
+      /* Handle changes to the row state.  */
+      if (RTX_FRAME_RELATED_P (insn))
+	dwarf2out_frame_debug (insn);
+
+      /* Look for REG_ARGS_SIZE, and handle it.  */
+      if (GET_CODE (PATTERN (insn)) == SEQUENCE)
 	{
-	  if (GET_CODE (pat) == SEQUENCE)
+	  rtx elt, pat = PATTERN (insn);
+	  int i, n = XVECLEN (pat, 0);
+
+	  if (INSN_ANNULLED_BRANCH_P (XVECEXP (pat, 0, 0)))
 	    {
-	      int i, n = XVECLEN (pat, 0);
-	      for (i = 1; i < n; ++i)
-		dwarf2out_frame_debug (XVECEXP (pat, 0, i), false);
-	    }
+	      /* ??? Hopefully multiple delay slots are not annulled.  */
+	      gcc_assert (n == 2);
+	      elt = XVECEXP (pat, 0, 1);
+
+	      /* If ELT is an instruction from target of an annulled branch,
+		 the effects are for the target only and so the args_size
+		 and CFA along the current path shouldn't change.  */
+	      if (INSN_FROM_TARGET_P (elt))
+		{
+		  HOST_WIDE_INT restore_args_size;
 
-          if (CALL_P (insn))
-	    dwarf2out_frame_debug (insn, false);
-          else if (find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL)
-		   || (cfun->can_throw_non_call_exceptions
-		       && can_throw_internal (insn)))
-	    dwarf2out_flush_queued_reg_saves ();
+		  restore_args_size = cur_trace->end_true_args_size;
+		  cur_cfa = &cur_row->cfa;
 
-	  /* Do not separate tablejump insns from their ADDR_DIFF_VEC.
-	     Putting the note after the VEC should be ok.  */
-	  if (!tablejump_p (insn, NULL, &add_cfi_insn))
-	    add_cfi_insn = insn;
+		  notice_args_size (elt);
+		  create_trace_edges (insn);
 
-	  dwarf2out_frame_debug (insn, true);
+		  cur_trace->end_true_args_size = restore_args_size;
+		  cur_row->cfa = this_cfa;
+		  cur_cfa = &this_cfa;
+		  continue;
+		}
+	    }
+
+	  for (i = 1; i < n; ++i)
+	    {
+	      elt = XVECEXP (pat, 0, i);
+	      notice_args_size (elt);
+	    }
 	}
+      else
+	notice_args_size (insn);
+
+      /* Between frame-related-p and args_size we might have otherwise
+	 emitted two cfa adjustments.  Do it now.  */
+      def_cfa_1 (&this_cfa);
 
       /* Note that a test for control_flow_insn_p does exactly the
 	 same tests as are done to actually create the edges.  So
@@ -2599,6 +2481,7 @@ scan_trace (dw_trace_info *trace)
   add_cfi_insn = NULL;
   cur_row = NULL;
   cur_trace = NULL;
+  cur_cfa = NULL;
 }
 
 /* Scan the function and create the initial set of CFI notes.  */
@@ -2740,6 +2623,32 @@ connect_traces (void)
 	  while (note != add_cfi_insn);
 	}
     }
+
+  /* Connect args_size between traces that have can_throw_internal insns.  */
+  if (cfun->eh->lp_array != NULL)
+    {
+      HOST_WIDE_INT prev_args_size = 0;
+
+      for (i = 0; i < n; ++i)
+	{
+	  ti = VEC_index (dw_trace_info, trace_info, i);
+
+	  if (ti->switch_sections)
+	    prev_args_size = 0;
+	  if (ti->eh_head == NULL)
+	    continue;
+	  gcc_assert (!ti->args_size_undefined);
+
+	  if (ti->beg_delay_args_size != prev_args_size)
+	    {
+	      /* ??? Search back to previous CFI note.  */
+	      add_cfi_insn = PREV_INSN (ti->eh_head);
+	      add_cfi_args_size (ti->beg_delay_args_size);
+	    }
+
+	  prev_args_size = ti->end_delay_args_size;
+	}
+    }
 }
 
 /* Set up the pseudo-cfg of instruction traces, as described at the
@@ -3387,9 +3296,6 @@ dump_cfi_row (FILE *f, dw_cfi_row *row)
   FOR_EACH_VEC_ELT (dw_cfi_ref, row->reg_save, i, cfi)
     if (cfi)
       output_cfi_directive (f, cfi);
-
-  fprintf (f, "\t.cfi_GNU_args_size "HOST_WIDE_INT_PRINT_DEC "\n",
-	   row->args_size);
 }
 
 void debug_cfi_row (dw_cfi_row *row);
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 99b02ba..aa743d7 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3614,6 +3614,10 @@ try_split (rtx pat, rtx trial, int last)
 	  break;
 #endif
 
+	case REG_ARGS_SIZE:
+	  fixup_args_size_notes (NULL_RTX, insn_last, INTVAL (XEXP (note, 0)));
+	  break;
+
 	default:
 	  break;
 	}
diff --git a/gcc/explow.c b/gcc/explow.c
index 3c692f4..f8262db 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -873,14 +873,45 @@ promote_decl_mode (const_tree decl, int *punsignedp)
 }
 
 \f
+/* Controls the behaviour of {anti_,}adjust_stack.  */
+static bool suppress_reg_args_size;
+
+/* A helper for adjust_stack and anti_adjust_stack.  */
+
+static void
+adjust_stack_1 (rtx adjust, bool anti_p)
+{
+  rtx temp, insn;
+
+#ifndef STACK_GROWS_DOWNWARD
+  /* Hereafter anti_p means subtract_p.  */
+  anti_p = !anti_p;
+#endif
+
+  temp = expand_binop (Pmode,
+		       anti_p ? sub_optab : add_optab,
+		       stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
+		       OPTAB_LIB_WIDEN);
+
+  if (temp != stack_pointer_rtx)
+    insn = emit_move_insn (stack_pointer_rtx, temp);
+  else
+    {
+      insn = get_last_insn ();
+      temp = single_set (insn);
+      gcc_assert (temp != NULL && SET_DEST (temp) == stack_pointer_rtx);
+    }
+
+  if (!suppress_reg_args_size)
+    add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+}
+
 /* Adjust the stack pointer by ADJUST (an rtx for a number of bytes).
    This pops when ADJUST is positive.  ADJUST need not be constant.  */
 
 void
 adjust_stack (rtx adjust)
 {
-  rtx temp;
-
   if (adjust == const0_rtx)
     return;
 
@@ -889,17 +920,7 @@ adjust_stack (rtx adjust)
   if (CONST_INT_P (adjust))
     stack_pointer_delta -= INTVAL (adjust);
 
-  temp = expand_binop (Pmode,
-#ifdef STACK_GROWS_DOWNWARD
-		       add_optab,
-#else
-		       sub_optab,
-#endif
-		       stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
-		       OPTAB_LIB_WIDEN);
-
-  if (temp != stack_pointer_rtx)
-    emit_move_insn (stack_pointer_rtx, temp);
+  adjust_stack_1 (adjust, false);
 }
 
 /* Adjust the stack pointer by minus ADJUST (an rtx for a number of bytes).
@@ -908,8 +929,6 @@ adjust_stack (rtx adjust)
 void
 anti_adjust_stack (rtx adjust)
 {
-  rtx temp;
-
   if (adjust == const0_rtx)
     return;
 
@@ -918,17 +937,7 @@ anti_adjust_stack (rtx adjust)
   if (CONST_INT_P (adjust))
     stack_pointer_delta += INTVAL (adjust);
 
-  temp = expand_binop (Pmode,
-#ifdef STACK_GROWS_DOWNWARD
-		       sub_optab,
-#else
-		       add_optab,
-#endif
-		       stack_pointer_rtx, adjust, stack_pointer_rtx, 0,
-		       OPTAB_LIB_WIDEN);
-
-  if (temp != stack_pointer_rtx)
-    emit_move_insn (stack_pointer_rtx, temp);
+  adjust_stack_1 (adjust, true);
 }
 
 /* Round the size of a block to be pushed up to the boundary required
@@ -1416,14 +1425,18 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align,
 	}
 
       saved_stack_pointer_delta = stack_pointer_delta;
+      suppress_reg_args_size = true;
+
       if (flag_stack_check && STACK_CHECK_MOVING_SP)
 	anti_adjust_stack_and_probe (size, false);
       else
 	anti_adjust_stack (size);
+
       /* Even if size is constant, don't modify stack_pointer_delta.
 	 The constant size alloca should preserve
 	 crtl->preferred_stack_boundary alignment.  */
       stack_pointer_delta = saved_stack_pointer_delta;
+      suppress_reg_args_size = false;
 
 #ifdef STACK_GROWS_DOWNWARD
       emit_move_insn (target, virtual_stack_dynamic_rtx);
diff --git a/gcc/expr.c b/gcc/expr.c
index 0d88a21..81b1ad8 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -3514,12 +3514,166 @@ push_block (rtx size, int extra, int below)
   return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
 }
 
-#ifdef PUSH_ROUNDING
+/* A utility routine that returns the base of an auto-inc memory, or NULL.  */
+
+static rtx
+mem_autoinc_base (rtx mem)
+{
+  if (MEM_P (mem))
+    {
+      rtx addr = XEXP (mem, 0);
+      if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
+	return XEXP (addr, 0);
+    }
+  return NULL;
+}
+
+/* A utility routine used here, in reload, and in try_split.  The insns
+   after PREV up to and including LAST are known to adjust the stack,
+   with a final value of END_ARGS_SIZE.  Iterate backward from LAST
+   placing notes as appropriate.  PREV may be NULL, indicating the
+   entire insn sequence prior to LAST should be scanned.
+
+   The set of allowed stack pointer modifications is small:
+     (1) One or more auto-inc style memory references (aka pushes),
+     (2) One or more addition/subtraction with the SP as destination,
+     (3) A single move insn with the SP as destination,
+     (4) A call_pop insn.
+
+   Insns in the sequence that do not modify the SP are ignored.
+
+   The return value is the amount of adjustment that can be trivially
+   verified, via immediate operand or auto-inc.  If the adjustment
+   cannot be trivially extracted, the return value is INT_MIN.  */
+
+int
+fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
+{
+  int args_size = end_args_size;
+  bool saw_unknown = false;
+  rtx insn;
+
+  for (insn = last; insn != prev; insn = PREV_INSN (insn))
+    {
+      rtx dest, set, pat;
+      HOST_WIDE_INT this_delta = 0;
+      int i;
+
+      if (!NONDEBUG_INSN_P (insn))
+	continue;
+      pat = PATTERN (insn);
+      set = NULL;
+
+      /* Look for a call_pop pattern.  */
+      if (CALL_P (insn))
+	{
+	  /* We're not supposed to see non-pop call patterns here.  */
+	  gcc_assert (GET_CODE (pat) == PARALLEL);
 
+	  /* All call_pop have a stack pointer adjust in the parallel.
+	     The call itself is always first, and the stack adjust is
+	     usually last, so search from the end.  */
+	  for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
+	    {
+	      set = XVECEXP (pat, 0, i);
+	      if (GET_CODE (set) != SET)
+		continue;
+	      dest = SET_DEST (set);
+	      if (dest == stack_pointer_rtx)
+		break;
+	    }
+	  /* We'd better have found the stack pointer adjust.  */
+	  gcc_assert (i > 0);
+	  /* Fall through to process the extracted SET and DEST
+	     as if it was a standalone insn.  */
+	}
+      else if (GET_CODE (pat) == SET)
+	set = pat;
+      else if ((set = single_set (insn)) != NULL)
+	;
+      else
+	{
+	  /* ??? Some older ports use a parallel with a stack adjust
+	     and a store for a PUSH_ROUNDING pattern, rather than a
+	     PRE/POST_MODIFY rtx.  Don't force them to update yet...  */
+	  /* ??? See h8300 and m68k, pushqi1.  */
+	  for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
+	    {
+	      set = XVECEXP (pat, 0, i);
+	      if (GET_CODE (set) != SET)
+		continue;
+	      dest = SET_DEST (set);
+	      if (dest == stack_pointer_rtx)
+		break;
+
+	      /* We do not expect an auto-inc of the sp in the parallel.  */
+	      gcc_checking_assert (mem_autoinc_base (dest)
+				   != stack_pointer_rtx);
+	      gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
+				   != stack_pointer_rtx);
+	    }
+	  if (i < 0)
+	    continue;
+	}
+      dest = SET_DEST (set);
+
+      /* Look for direct modifications of the stack pointer.  */
+      if (dest == stack_pointer_rtx)
+	{
+	  gcc_assert (!saw_unknown);
+	  /* Look for a trivial adjustment, otherwise assume nothing.  */
+	  if (GET_CODE (SET_SRC (set)) == PLUS
+	      && XEXP (SET_SRC (set), 0) == stack_pointer_rtx
+	      && CONST_INT_P (XEXP (SET_SRC (set), 1)))
+	    this_delta = INTVAL (XEXP (SET_SRC (set), 1));
+	  else
+	    saw_unknown = true;
+	}
+      /* Otherwise only think about autoinc patterns.  */
+      else if (mem_autoinc_base (dest) == stack_pointer_rtx)
+	{
+	  rtx addr = XEXP (dest, 0);
+	  gcc_assert (!saw_unknown);
+	  switch (GET_CODE (addr))
+	    {
+	    case PRE_INC:
+	    case POST_INC:
+	      this_delta = GET_MODE_SIZE (GET_MODE (dest));
+	      break;
+	    case PRE_DEC:
+	    case POST_DEC:
+	      this_delta = -GET_MODE_SIZE (GET_MODE (dest));
+	      break;
+	    case PRE_MODIFY:
+	    case POST_MODIFY:
+	      addr = XEXP (addr, 1);
+	      gcc_assert (GET_CODE (addr) == PLUS);
+	      gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
+	      gcc_assert (CONST_INT_P (XEXP (addr, 1)));
+	      this_delta = INTVAL (XEXP (addr, 1));
+	      break;
+	    default:
+	      gcc_unreachable ();
+	    }
+	}
+      else
+	continue;
+
+      add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (args_size));
+#ifdef STACK_GROWS_DOWNWARD
+      this_delta = -this_delta;
+#endif
+      args_size -= this_delta;
+    }
+
+  return saw_unknown ? INT_MIN : args_size;
+}
+
+#ifdef PUSH_ROUNDING
 /* Emit single push insn.  */
 
 static void
-emit_single_push_insn (enum machine_mode mode, rtx x, tree type)
+emit_single_push_insn_1 (enum machine_mode mode, rtx x, tree type)
 {
   rtx dest_addr;
   unsigned rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
@@ -3603,6 +3757,30 @@ emit_single_push_insn (enum machine_mode mode, rtx x, tree type)
     }
   emit_move_insn (dest, x);
 }
+
+/* Emit and annotate a single push insn.  */
+
+static void
+emit_single_push_insn (enum machine_mode mode, rtx x, tree type)
+{
+  int delta, old_delta = stack_pointer_delta;
+  rtx prev = get_last_insn ();
+  rtx last;
+
+  emit_single_push_insn_1 (mode, x, type);
+
+  last = get_last_insn ();
+
+  /* Notice the common case where we emitted exactly one insn.  */
+  if (PREV_INSN (last) == prev)
+    {
+      add_reg_note (last, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+      return;
+    }
+
+  delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
+  gcc_assert (delta == INT_MIN || delta == old_delta);
+}
 #endif
 
 /* Generate code to push X onto the stack, assuming it has mode MODE and
diff --git a/gcc/recog.c b/gcc/recog.c
index 9331681..22a5402 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -3146,16 +3146,17 @@ static rtx
 peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
 {
   int i;
-  rtx last, note, before_try, x;
+  rtx last, eh_note, as_note, before_try, x;
   rtx old_insn, new_insn;
   bool was_call = false;
 
-  /* If we are splittind an RTX_FRAME_RELATED_P insn, do not allow it to
+  /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
      match more than one insn, or to be split into more than one insn.  */
   old_insn = peep2_insn_data[peep2_current].insn;
   if (RTX_FRAME_RELATED_P (old_insn))
     {
       bool any_note = false;
+      rtx note;
 
       if (match_len != 0)
 	return NULL;
@@ -3236,6 +3237,7 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
   for (i = 0; i <= match_len; ++i)
     {
       int j;
+      rtx note;
 
       j = peep2_buf_position (peep2_current + i);
       old_insn = peep2_insn_data[j].insn;
@@ -3281,9 +3283,21 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
       break;
     }
 
-  i = peep2_buf_position (peep2_current + match_len);
+  /* If we matched any instruction that had a REG_ARGS_SIZE, then
+     move those notes over to the new sequence.  */
+  as_note = NULL;
+  for (i = match_len; i >= 0; --i)
+    {
+      int j = peep2_buf_position (peep2_current + i);
+      old_insn = peep2_insn_data[j].insn;
+
+      as_note = find_reg_note (old_insn, REG_ARGS_SIZE, NULL);
+      if (as_note)
+	break;
+    }
 
-  note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
+  i = peep2_buf_position (peep2_current + match_len);
+  eh_note = find_reg_note (peep2_insn_data[i].insn, REG_EH_REGION, NULL_RTX);
 
   /* Replace the old sequence with the new.  */
   last = emit_insn_after_setloc (attempt,
@@ -3293,7 +3307,7 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
   delete_insn_chain (insn, peep2_insn_data[i].insn, false);
 
   /* Re-insert the EH_REGION notes.  */
-  if (note || (was_call && nonlocal_goto_handler_labels))
+  if (eh_note || (was_call && nonlocal_goto_handler_labels))
     {
       edge eh_edge;
       edge_iterator ei;
@@ -3302,8 +3316,8 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
 	if (eh_edge->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
 	  break;
 
-      if (note)
-	copy_reg_eh_region_note_backward (note, last, before_try);
+      if (eh_note)
+	copy_reg_eh_region_note_backward (eh_note, last, before_try);
 
       if (eh_edge)
 	for (x = last; x != before_try; x = PREV_INSN (x))
@@ -3336,6 +3350,10 @@ peep2_attempt (basic_block bb, rtx insn, int match_len, rtx attempt)
       peep2_do_cleanup_cfg |= purge_dead_edges (bb);
     }
 
+  /* Re-insert the ARGS_SIZE notes.  */
+  if (as_note)
+    fixup_args_size_notes (before_try, last, INTVAL (XEXP (as_note, 0)));
+
   /* If we generated a jump instruction, it won't have
      JUMP_LABEL set.  Recompute after we're done.  */
   for (x = last; x != before_try; x = PREV_INSN (x))
diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def
index eccac9e..8c8a99a 100644
--- a/gcc/reg-notes.def
+++ b/gcc/reg-notes.def
@@ -201,3 +201,8 @@ REG_NOTE (CROSSING_JUMP)
 /* This kind of note is generated at each to `setjmp', and similar
    functions that can return twice.  */
 REG_NOTE (SETJMP)
+
+/* Indicates the cumulative offset of the stack pointer accounting
+   for pushed arguments.  This will only be generated when
+   ACCUMULATE_OUTGOING_ARGS is false.  */
+REG_NOTE (ARGS_SIZE)
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 499412c..3233580 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -4653,6 +4653,15 @@ reload_as_needed (int live_known)
 	      if (cfun->can_throw_non_call_exceptions && !CALL_P (insn))
 		fixup_eh_region_note (insn, prev, next);
 
+	      /* Adjust the location of REG_ARGS_SIZE.  */
+	      p = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
+	      if (p)
+		{
+		  remove_note (insn, p);
+		  fixup_args_size_notes (prev, PREV_INSN (next),
+					 INTVAL (XEXP (p, 0)));
+		}
+
 	      /* If this was an ASM, make sure that all the reload insns
 		 we have generated are valid.  If not, give an error
 		 and delete them.  */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 3156006..d5d7b02 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2471,6 +2471,7 @@ extern void emit_jump (rtx);
 /* In expr.c */
 extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
 			   unsigned int, int);
+extern int fixup_args_size_notes (rtx, rtx, int);
 
 /* In cfgrtl.c */
 extern void print_rtl_with_bb (FILE *, const_rtx);

^ permalink raw reply	[flat|nested] 33+ messages in thread

end of thread, other threads:[~2011-12-21  4:31 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-20 15:52 [RFC] Cleanup DW_CFA_GNU_args_size handling Gerald Pfeifer
2011-08-22  6:42 ` Eric Botcazou
2011-08-23 22:20   ` Richard Henderson
2011-08-24  6:44     ` Gerald Pfeifer
2011-08-24  7:38       ` Richard Henderson
2011-08-24  8:46         ` Gerald Pfeifer
2011-08-24  8:48           ` H.J. Lu
2011-08-24 17:38     ` Eric Botcazou
2011-09-04 18:39       ` Gerald Pfeifer
2011-09-09 10:01         ` Eric Botcazou
2011-09-09 19:07           ` Eric Botcazou
2011-09-09 20:02             ` H.J. Lu
2011-09-10 14:08               ` Eric Botcazou
2011-09-10 19:03                 ` H.J. Lu
2011-09-11  2:35                   ` Gerald Pfeifer
  -- strict thread matches above, loose matches on Subject: below --
2011-08-01 17:40 Richard Henderson
2011-08-01 18:43 ` Georg-Johann Lay
2011-08-01 18:47   ` Richard Henderson
2011-08-01 19:53     ` Denis Chertykov
2011-08-03 12:16     ` Georg-Johann Lay
2011-08-03 14:08       ` Georg-Johann Lay
2011-08-03 15:13         ` Richard Henderson
2011-08-03 15:49           ` Georg-Johann Lay
2011-08-03 15:53             ` Richard Henderson
2011-08-03 16:24         ` Jeff Law
2011-08-02  2:00 ` Richard Henderson
2011-08-02 22:32 ` Richard Henderson
2011-08-03 14:31   ` H.J. Lu
2011-08-03 17:39     ` H.J. Lu
2011-12-21  5:20   ` Jie Zhang
2011-08-03 14:07 ` Ulrich Weigand
2011-08-03 15:15   ` Richard Henderson
2011-08-03 17:01     ` Ulrich Weigand

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).