In this pr, during the initialization of the dwarf2 backend, we attempt to cache a translation from a local stack frame address to the CFA. We do this optimistically, hoping to cut down the work later for every local stack frame address that we find in the actual variables dumped.
Unfortunately, AVR has problems with the edge condition of no local stack frame allocated. In this case, the results of its register elimination are different from what dwarf2out expects. IMO, AVR is justified in this, because the combination that dwarf2out wants is invalid according to TARGET_CAN_ELIMINATE. That said, this really shouldn't matter since, for the edge condition in question, we won't actually use the translation to the CFA. The moment that we generate an actual reference to the stack frame, we'll actually generate a frame pointer, and everything else will DTRT. Thus we can avoid the explosion by deferring the sanity check until the translation is actually used. Committed to HEAD; testing for 4.6 is still going. r~
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 776066b..b33da64 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -6471,6 +6471,7 @@ static GTY(()) VEC(tree,gc) *generic_type_instances; /* Offset from the "steady-state frame pointer" to the frame base, within the current function. */ static HOST_WIDE_INT frame_pointer_fb_offset; +static bool frame_pointer_fb_offset_valid; static VEC (dw_die_ref, heap) *base_types; @@ -13613,6 +13614,7 @@ based_loc_descr (rtx reg, HOST_WIDE_INT offset, return new_reg_loc_descr (base_reg, offset); } + gcc_assert (frame_pointer_fb_offset_valid); offset += frame_pointer_fb_offset; return new_loc_descr (DW_OP_fbreg, offset, 0); } @@ -18336,14 +18338,20 @@ compute_frame_pointer_to_fb_displacement (HOST_WIDE_INT offset) elim = XEXP (elim, 0); } - gcc_assert ((SUPPORTS_STACK_ALIGNMENT - && (elim == hard_frame_pointer_rtx - || elim == stack_pointer_rtx)) - || elim == (frame_pointer_needed - ? hard_frame_pointer_rtx - : stack_pointer_rtx)); - frame_pointer_fb_offset = -offset; + + /* ??? AVR doesn't set up valid eliminations when there is no stack frame + in which to eliminate. This is because it's stack pointer isn't + directly accessible as a register within the ISA. To work around + this, assume that while we cannot provide a proper value for + frame_pointer_fb_offset, we won't need one either. */ + frame_pointer_fb_offset_valid + = ((SUPPORTS_STACK_ALIGNMENT + && (elim == hard_frame_pointer_rtx + || elim == stack_pointer_rtx)) + || elim == (frame_pointer_needed + ? hard_frame_pointer_rtx + : stack_pointer_rtx)); } /* Generate a DW_AT_name attribute given some string value to be included as