[RFA] dwarf2out.c:eliminate_regs() bug
Richard Guenther
richard.guenther@gmail.com
Sun Sep 20 09:03:00 GMT 2009
On Sun, Sep 20, 2009 at 9:38 AM, Maxim Kuvyrkov <maxim@codesourcery.com> wrote:
> I'm investigating an ICE on m68k architecture. I'm not quite sure what is
> the right way to fix the bug so I welcome any feedback on the below
> analysis.
>
> Compilation fails on the assert in dwarf2out.c:based_loc_descr():
> <cut>
> /* We only use "frame base" when we're sure we're talking about the
> post-prologue local stack frame. We do this by *not* running
> register elimination until this point, and recognizing the special
> argument pointer and soft frame pointer rtx's. */
> if (reg == arg_pointer_rtx || reg == frame_pointer_rtx)
> {
> rtx elim = eliminate_regs (reg, VOIDmode, NULL_RTX);
>
> if (elim != reg)
> {
> if (GET_CODE (elim) == PLUS)
> {
> offset += INTVAL (XEXP (elim, 1));
> 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));
> </cut>
>
> This code uses eliminate_regs(), which implicitly assumes reload_completed
> as it uses reg_eliminate[], which assumes that frame_pointer_needed is
> properly set, which happens in ira.c. However, in some cases this piece of
> based_loc_descr() can be reached during inlining pass (see backtrace below).
> When called before reload, eliminate_regs() may return an inconsistent
> result which is why the assert in based_loc_descr() fails. In the
> particular testcase I'm investigating, frame_pointer_needed is 0 (initial
> value), but eliminate_regs returns stack_pointer_rtx because it is guided by
> reg_eliminate information from the previous function which had
> frame_pointer_needed set to 1.
>
> Now, how do we fix this? For starters, it seems to be a good idea to assert
> (reload_in_progress | reload_completed) in eliminate_regs. Then, there are
> users of eliminate_regs in dbxout.c, dwarf2out.c, and sdbout.c not counting
> reload and machine-specific parts. From the 3 *out.c backends, only
> dwarf2out.c handles abstract functions, which is what causing it to be
> called before reload afaik, so the task seems to be in fixing the dwarf2out
> code.
>
> There are two references to eliminate_regs in dwarf2out. The first
> reference -- in based_loc_descr -- can *probably* be handled by adding
> reload_completed to the 'if' condition. The second is in
> compute_frame_pointer_to_fb_displacement. I'm no expert in dwarf2out.c
> code, but from the looks of it, it seems that compute_..._displacement is
> only called after reload, so a simple gcc_assert (reload_completed) may be
> enough there.
>
> One last note, I'm investigating this bug against 4.4 branch as it doesn't
> trigger on the mainline. Progression search on the mainline showed that
> failure became latent after this patch
> (http://gcc.gnu.org/viewcvs?view=revision&revision=147436) to inlining
> heuristics.
I think you should avoid calling eliminate_regs for DECL_ABSTRACT
current_function_decl. That should cover the inliner path.
Richard.
> --
> Maxim K.
> CodeSourcery
>
> The backtrace:
> #0 eliminate_regs_1 (x=0xf7d60280, mem_mode=VOIDmode, insn=0x0,
> may_use_invariant=0 '\0') at gcc/reload1.c:2481
> #1 0x0839e9b1 in eliminate_regs (x=0xf7d60280, mem_mode=VOIDmode, insn=0x0)
> at gcc/reload1.c:2870
> #2 0x0821cf66 in based_loc_descr (reg=0xf7d60280, offset=8,
> initialized=VAR_INIT_STATUS_INITIALIZED) at gcc/dwarf2out.c:9868
> #3 0x0821d7a7 in mem_loc_descriptor (rtl=0xf700bd98, mode=SImode,
> initialized=VAR_INIT_STATUS_INITIALIZED) at gcc/dwarf2out.c:10158
> #4 0x0821dd55 in loc_descriptor (rtl=0xf700bc90,
> initialized=VAR_INIT_STATUS_INITIALIZED) at gcc/dwarf2out.c:10330
> #5 0x0821ddde in loc_descriptor (rtl=0xf700d7a0,
> initialized=VAR_INIT_STATUS_INITIALIZED) at gcc/dwarf2out.c:10349
> #6 0x082205d6 in add_location_or_const_value_attribute (die=0xf702ad20,
> decl=0xf73922d0, attr=DW_AT_location) at gcc/dwarf2out.c:11841
> #7 0x08223412 in gen_formal_parameter_die (node=0x0, origin=0xf73922d0,
> context_die=0xf702ace8) at gcc/dwarf2out.c:13349
> #8 0x082273c6 in gen_decl_die (decl=0x0, origin=0xf73922d0,
> context_die=0xf702ace8) at gcc/dwarf2out.c:15388
> #9 0x082268aa in process_scope_var (stmt=0xf7163620, decl=0x0,
> origin=0xf73922d0, context_die=0xf702ace8) at gcc/dwarf2out.c:14969
> #10 0x0822698d in decls_for_scope (stmt=0xf7163620, context_die=0xf702ace8,
> depth=5) at gcc/dwarf2out.c:14993
> #11 0x08225192 in gen_lexical_block_die (stmt=0xf7163620,
> context_die=0xf702a498, depth=5) at gcc/dwarf2out.c:14266
> #12 0x082253b5 in gen_inlined_subroutine_die (stmt=0xf7163620,
> context_die=0xf702a498, depth=5) at gcc/dwarf2out.c:14308
> #13 0x08226711 in gen_block_die (stmt=0xf7163620, context_die=0xf702a498,
> depth=5) at gcc/dwarf2out.c:14935
> #14 0x082269ee in decls_for_scope (stmt=0xf7163038, context_die=0xf702a498,
> depth=4) at gcc/dwarf2out.c:15005
> #15 0x08225192 in gen_lexical_block_die (stmt=0xf7163038,
> context_die=0xf7026f18, depth=4) at gcc/dwarf2out.c:14266
> #16 0x0822672c in gen_block_die (stmt=0xf7163038, context_die=0xf7026f18,
> depth=4) at gcc/dwarf2out.c:14937
> #17 0x082269ee in decls_for_scope (stmt=0xf715fbd0, context_die=0xf7026f18,
> depth=3) at gcc/dwarf2out.c:15005
> #18 0x08225192 in gen_lexical_block_die (stmt=0xf715fbd0,
> context_die=0xf7026e70, depth=3) at gcc/dwarf2out.c:14266
> #19 0x0822672c in gen_block_die (stmt=0xf715fbd0, context_die=0xf7026e70,
> depth=3) at gcc/dwarf2out.c:14937
> #20 0x082269ee in decls_for_scope (stmt=0xf715fb28, context_die=0xf7026e70,
> depth=2) at gcc/dwarf2out.c:15005
> #21 0x08225192 in gen_lexical_block_die (stmt=0xf715fb28,
> context_die=0xf7026738, depth=2) at gcc/dwarf2out.c:14266
> #22 0x082253b5 in gen_inlined_subroutine_die (stmt=0xf715fb28,
> context_die=0xf7026738, depth=2) at gcc/dwarf2out.c:14308
> #23 0x08226711 in gen_block_die (stmt=0xf715fb28, context_die=0xf7026738,
> depth=2) at gcc/dwarf2out.c:14935
> #24 0x082269ee in decls_for_scope (stmt=0xf73daaf0, context_die=0xf7026738,
> depth=1) at gcc/dwarf2out.c:15005
> #25 0x08225192 in gen_lexical_block_die (stmt=0xf73daaf0,
> context_die=0xf70265e8, depth=1) at gcc/dwarf2out.c:14266
> #26 0x0822672c in gen_block_die (stmt=0xf73daaf0, context_die=0xf70265e8,
> depth=1) at gcc/dwarf2out.c:14937
> #27 0x082269ee in decls_for_scope (stmt=0xf73dab28, context_die=0xf70265e8,
> depth=0) at gcc/dwarf2out.c:15005
> #28 0x08224276 in gen_subprogram_die (decl=0xf7500700,
> context_die=0xf7dfa498) at gcc/dwarf2out.c:13859
> #29 0x08227126 in gen_decl_die (decl=0xf7500700, origin=0xf747af08,
> context_die=0xf7dfa498) at gcc/dwarf2out.c:15302
> #30 0x08227b0b in dwarf2out_decl (decl=0xf7500700) at gcc/dwarf2out.c:15674
> #31 0x08223928 in dwarf2out_abstract_function (decl=0xf7500700) at
> gcc/dwarf2out.c:13510
> #32 0x08176fd4 in expand_call_inline (bb=0xf724e654, stmt=0xf73782d0,
> id=0xffffd644) at gcc/tree-inline.c:3476
> #33 0x081770a5 in gimple_expand_calls_inline (bb=0xf724e654, id=0xffffd644)
> at gcc/tree-inline.c:3504
> #34 0x081773e6 in optimize_inline_calls (fn=0xf7311e80) at
> gcc/tree-inline.c:3616
> #35 0x085ae970 in inline_transform (node=0xf7362c80) at
> gcc/ipa-inline.c:1747
> #36 0x08357b98 in execute_one_ipa_transform_pass (node=0xf7362c80,
> ipa_pass=0x8a889e0) at gcc/passes.c:1203
>
>
More information about the Gcc
mailing list