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 > >