This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA:] Fix MMIX breakage in except.c:connect_post_landing_pads:handle insns after actual call insn


mmix-knuth-mmixware worked with trunk of "Tue Feb 17 01:55:55
GMT 2004" was broken with "Fri Feb 27 06:23:16 GMT 2004".

The breakage is that cc1plus crashes in libstdc++-v3 at configure
time, at the point of the "configure:5006: checking for exception
model to use" with the dying-gasp-message
internal compiler error: in connect_post_landing_pads, at except.c:1828

The problem is that except.c:1.259 introduced an assumption that
any "call" expansion doesn't have any more insns after the
actual call insn, which is an incorrect assumption (and not
documented in 1.259) for MMIX: in the MMIX port, there's an insn
after the actual call insn. See the added comment for more.  To
simplify review, I made the diff -10 to make the abort visible
that is hit, introduced with 1.259.

This patch isn't obvious.  For example, alternative solutions
would be to pass on the noreturn information to the "call"
pattern or to introduce a noreturn call pattern and use that for
noreturn calls.  Also, the requirement on "call" to not emit
insns after the actual call insn would need to be documented.
All in all, removing the assumption on the call expansion seems
simpler.

Built and tested cross to mn10300-elf powerpc-eabisim m32r-elf frv-elf
sh-elf v850-elf and native on i686-pc-linux-gnu.

Ok to commit?

	* except.c (connect_post_landing_pads): Delete insns after the
	barrier when generating a unwind_resume_libfunc call.

Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.261
diff -p -c -1 -0 -r1.261 except.c
*** except.c	7 Mar 2004 22:29:28 -0000	1.261
--- except.c	12 Mar 2004 05:24:06 -0000
*************** connect_post_landing_pads (void)
*** 1810,1831 ****
  	  emit_jump (outer->post_landing_pad);
  	  src = BLOCK_FOR_INSN (region->resume);
  	  dest = BLOCK_FOR_INSN (outer->post_landing_pad);
  	  while (src->succ)
  	    remove_edge (src->succ);
  	  e = make_edge (src, dest, 0);
  	  e->probability = REG_BR_PROB_BASE;
  	  e->count = src->count;
  	}
        else
! 	emit_library_call (unwind_resume_libfunc, LCT_THROW,
! 			   VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);

        seq = get_insns ();
        end_sequence ();
        barrier = emit_insn_before (seq, region->resume);
        /* Avoid duplicate barrier.  */
        if (GET_CODE (barrier) != BARRIER)
  	abort ();
        delete_insn (barrier);
        delete_insn (region->resume);
      }
--- 1810,1844 ----
  	  emit_jump (outer->post_landing_pad);
  	  src = BLOCK_FOR_INSN (region->resume);
  	  dest = BLOCK_FOR_INSN (outer->post_landing_pad);
  	  while (src->succ)
  	    remove_edge (src->succ);
  	  e = make_edge (src, dest, 0);
  	  e->probability = REG_BR_PROB_BASE;
  	  e->count = src->count;
  	}
        else
! 	{
! 	  emit_library_call (unwind_resume_libfunc, LCT_THROW,
! 			     VOIDmode, 1, cfun->eh->exc_ptr, ptr_mode);
!
! 	  /* What we just emitted was a throwing libcall, so it got a
! 	     barrier automatically added after it.  If the last insn in
! 	     the libcall sequence isn't the barrier, it's because the
! 	     target emits multiple insns for a call, and there are insns
! 	     after the actual call insn (which are redundant and would be
! 	     optimized away).  The barrier is inserted exactly after the
! 	     call insn, so let's go get that and delete the insns after
! 	     it, because below we need the barrier to be the last insn in
! 	     the sequence.  */
! 	  delete_insns_since (NEXT_INSN (last_call_insn ()));
! 	}

        seq = get_insns ();
        end_sequence ();
        barrier = emit_insn_before (seq, region->resume);
        /* Avoid duplicate barrier.  */
        if (GET_CODE (barrier) != BARRIER)
  	abort ();
        delete_insn (barrier);
        delete_insn (region->resume);
      }

brgds, H-P


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]