On Sun, Sep 20, 2009 at 9:38 AM, Maxim Kuvyrkov <ma...@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
>
>

Reply via email to