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]

Re: [development-gcc] ICE while bootstrapping


>  /usr/src/packages/BUILD/gcc-3.3-hammer-20030430/obj-i586-suse-linux/gcc/cc1plus -fpreprocessed verify.ii -quiet -dumpbase verify.cc -march=i486 -mcpu=i686 -auxbase-strip .libs/verify.o -g -O1 -Wswitch-enum -W -Wall -version -fno-rtti -fnon-call-exceptions -fdollars-in-identifiers -ffloat-store -fPIC -o verify.s
> GNU C++ version 3.3 (SuSE Linux) (i586-suse-linux)
>         compiled by GNU C version 3.3 (SuSE Linux).
> GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
> ../../../libjava/verify.cc: In function `void debug_print(const char*, ...)':
> ../../../libjava/verify.cc:40: warning: unused parameter `const char*fmt'
> ../../../libjava/verify.cc: In member function `void 
>    _Jv_BytecodeVerifier::state::copy(const _Jv_BytecodeVerifier::state*, int, 
>    int, bool)':
> ../../../libjava/verify.cc:955: error: unrecognizable insn:
> (insn 532 143 533 5 0x411f2370 (set (reg:CC 17 flags)
>         (compare:CC (mem:QI (plus:SI (mem/s/j:SI (plus:SI (reg/v/f:SI 59)
>                             (const_int 16 [0x10])) [0 <variable>.local_changed+0 S4 A32])
>                     (reg/v:SI 84)) [0 S1 A8])
>             (const_int 1 [0x1]))) -1 (nil)
>     (expr_list:REG_DEAD (reg:SI 94)
>         (nil)))
> ../../../libjava/verify.cc:955: internal compiler error: in extract_insn, at 
>    recog.c:2175
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <URL:http://gcc.gnu.org/bugs.html> for instructions.

Uhm, this is ugly!
The actual problem is that instruction 532 is created by the if
conversion.  It has memory operand that is taken from the original
compare instruction (142) that is kept in the stream.  It is still alive
and thus it is kept in place until combiner and combiner realizes that
it's value is used for no good reason and elliminates it.  During the
process it modifices the memory operand to invalid address but because
the compare is killed, the instruction is matched and modification is
not undone.  Because of RTL sharing the change appears in the insn 532
too.

In the past I faced similar RTL sharing issues with ifcvt and solved it by
adding tons of copy_rtx calls into i386 expanders.  This does not apepar to
work.  Richard, what do you think about this approach?

I am still testing the patch and will commit it to the hammer branch if
it passes.

Honza

Wed May 21 23:04:58 CEST 2003  Jan Hubicka  <jh@suse.cz>
	* ifcvt.c (unshare_insns):  New static function.
	(noce_try_store_flag, noce_try_store_flag_inc,
	 noce_try_store_flag_mask, noce_try_cmove,
	 noce_try_cmove_arith, noce_try_minmax, noce_try_abs,
	 noce_process_if_block): Use it.
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.105.2.4
diff -c -3 -p -r1.105.2.4 ifcvt.c
*** ifcvt.c	28 Mar 2003 11:42:52 -0000	1.105.2.4
--- ifcvt.c	21 May 2003 21:04:39 -0000
*************** static rtx noce_get_alt_condition	PARAMS
*** 592,597 ****
--- 592,616 ----
  						 rtx, rtx *));
  static int noce_try_minmax		PARAMS ((struct noce_if_info *));
  static int noce_try_abs			PARAMS ((struct noce_if_info *));
+ static void unshare_insns		PARAMS ((rtx));
+ 
+ /* Passing nontrivial arguments taken from instruction stream to the expanders
+    creates various sorts of inexpected RTL sharing.  Avoid that by simply
+    creating of duplicate of each insn emit into the stream.  */
+ static void
+ unshare_insns (insn)
+     rtx insn;
+ {
+   while (insn)
+    {
+      if (INSN_P (insn))
+ 	{
+ 	  emit_copy_of_insn_after (insn, insn);
+           insn = delete_insn (insn);
+ 	}
+      insn = NEXT_INSN (insn);
+    }
+ }
  
  /* Helper function for noce_try_store_flag*.  */
  
*************** noce_try_store_flag (if_info)
*** 713,718 ****
--- 732,738 ----
        if (target != if_info->x)
  	noce_emit_move_insn (if_info->x, target);
  
+       unshare_insns (get_insns ());
        seq = get_insns ();
        end_sequence ();
        emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));
*************** noce_try_store_flag_constants (if_info)
*** 844,849 ****
--- 864,870 ----
        if (target != if_info->x)
  	noce_emit_move_insn (if_info->x, target);
  
+       unshare_insns (get_insns ());
        seq = get_insns ();
        end_sequence ();
  
*************** noce_try_store_flag_inc (if_info)
*** 904,909 ****
--- 925,931 ----
  	  if (target != if_info->x)
  	    noce_emit_move_insn (if_info->x, target);
  
+ 	  unshare_insns (get_insns ());
  	  seq = get_insns ();
  	  end_sequence ();
  
*************** noce_try_store_flag_mask (if_info)
*** 957,962 ****
--- 979,985 ----
  	  if (target != if_info->x)
  	    noce_emit_move_insn (if_info->x, target);
  
+ 	  unshare_insns (get_insns ());
  	  seq = get_insns ();
  	  end_sequence ();
  
*************** noce_try_cmove (if_info)
*** 1057,1062 ****
--- 1080,1086 ----
  	  if (target != if_info->x)
  	    noce_emit_move_insn (if_info->x, target);
  
+ 	  unshare_insns (get_insns ());
  	  seq = get_insns ();
  	  end_sequence ();
  	  emit_insn_before_scope (seq, if_info->jump,
*************** noce_try_cmove_arith (if_info)
*** 1229,1234 ****
--- 1253,1259 ----
    else if (target != x)
      noce_emit_move_insn (x, target);
  
+   unshare_insns (get_insns ());
    tmp = get_insns ();
    end_sequence ();
    emit_insn_before_scope (tmp, if_info->jump, INSN_SCOPE (if_info->insn_a));
*************** noce_try_minmax (if_info)
*** 1477,1482 ****
--- 1502,1508 ----
    if (target != if_info->x)
      noce_emit_move_insn (if_info->x, target);
  
+   unshare_insns (get_insns ());
    seq = get_insns ();
    end_sequence ();  
  
*************** noce_try_abs (if_info)
*** 1595,1600 ****
--- 1621,1627 ----
    if (target != if_info->x)
      noce_emit_move_insn (if_info->x, target);
  
+   unshare_insns (get_insns ());
    seq = get_insns ();
    end_sequence ();  
  
*************** noce_process_if_block (ce_info)
*** 1909,1914 ****
--- 1936,1942 ----
      {
        start_sequence ();
        noce_emit_move_insn (copy_rtx (orig_x), x);
+       unshare_insns (get_insns ());
        insn_b = get_insns ();
        end_sequence ();
  


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