public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFA] dwarf2out.c:eliminate_regs() bug
@ 2009-09-20  7:38 Maxim Kuvyrkov
  2009-09-20  9:03 ` Richard Guenther
  0 siblings, 1 reply; 5+ messages in thread
From: Maxim Kuvyrkov @ 2009-09-20  7:38 UTC (permalink / raw)
  To: GCC; +Cc: Jason Merrill

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.

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

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

end of thread, other threads:[~2009-10-08 11:21 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-20  7:38 [RFA] dwarf2out.c:eliminate_regs() bug Maxim Kuvyrkov
2009-09-20  9:03 ` Richard Guenther
2009-09-20 11:18   ` Maxim Kuvyrkov
2009-09-20 11:32     ` Richard Guenther
2009-10-08 11:51       ` Maxim Kuvyrkov

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