[PATCH] PR opt/12280: Avoid RTL sharing in noce_emit_cmove

Jan Hubicka jh@suse.cz
Tue Nov 11 17:54:00 GMT 2003


> > I am currently testing modified patch that allows sharing of CONSTs
> > everywhere.
> 
> Maybe.  I'm thinking that we probably only shared CONSTs at all 
> to make sharing of constant MEMs possible.  Perhaps we shouldn't
> bother sharing them at all.

I an give this approach a try and return back on how many bugs it finds.
Any good reasons for unsharing them?  (it looks quite wastefull for me).
I think the only reason why CONSTs containing labels are shared is to
get redirect_jump working on architectures that mangle destination label
into CONST sequences.
I was not able to come with any different case where sharing them might
be harmfull and perhaps we may want to update it on the other side (make
redirect_jump to always produce new CONST) that would harm just those
interesting architectures.  (any example of these?)
> 
> Clearly all of this is going to require extensive testing on many
> ports.  Your checker is going to find *lots* of latent bugs.

Yes.  I can find lots of latent bugs on i386 as well.
Lets get the code into final form and not enable the checking until I
get it bootstrapping at least on few main architectures.  Here is
updated patch.  I finally got what you were shooting for with copy_rtx.
Sorry for being so dense these days...

Honza
> 
> 
> r~


2003-11-09  Jan Hubicka  <jh@suse.cz>
	* emit-rtl.c (set_used_flags): New.
	(copy_rtx_if_shared, reset_used_flags): use rtx_can_be_shared_p.
	(check_rtx_sharing, check_rtl_sharing): New.
	(unshare_all_rtl_1): Rename to....
	(unshare_all_rtl_in_chain): ... this one; make static.
	(copy_rtx_if_shared): LABEL_REF chan be shared.
	* rtl.c (rtx_can_be_shared_p): Break out of ....
	(copy_rtx): ... here.
	* ifcvt.c (unshare_ifcvt_sequence): New.
	(noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
	noce_try_addcc, noce_try_addcc, noce_try_store_flag_mask,
	noce_try_cmove, noce_try_store_flag_mask, noce_try_minmax,
	noce_try_abs, noce_process_if_block, find_cond_trap
	* rtl.h (check_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain):
	Declare.
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.352
diff -c -3 -p -r1.352 emit-rtl.c
*** emit-rtl.c	4 Nov 2003 09:14:18 -0000	1.352
--- emit-rtl.c	11 Nov 2003 17:28:09 -0000
*************** static rtx make_jump_insn_raw (rtx);
*** 180,186 ****
  static rtx make_call_insn_raw (rtx);
  static rtx find_line_note (rtx);
  static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
- static void unshare_all_rtl_1 (rtx);
  static void unshare_all_decls (tree);
  static void reset_used_decls (tree);
  static void mark_label_nuses (rtx);
--- 180,185 ----
*************** unshare_all_rtl (tree fndecl, rtx insn)
*** 2448,2454 ****
    unshare_all_decls (DECL_INITIAL (fndecl));
  
    /* Unshare just about everything else.  */
!   unshare_all_rtl_1 (insn);
  
    /* Make sure the addresses of stack slots found outside the insn chain
       (such as, in DECL_RTL of a variable) are not shared
--- 2447,2453 ----
    unshare_all_decls (DECL_INITIAL (fndecl));
  
    /* Unshare just about everything else.  */
!   unshare_all_rtl_in_chain (insn);
  
    /* Make sure the addresses of stack slots found outside the insn chain
       (such as, in DECL_RTL of a variable) are not shared
*************** unshare_all_rtl_again (rtx insn)
*** 2489,2500 ****
  
    unshare_all_rtl (cfun->decl, insn);
  }
  
  /* Go through all the RTL insn bodies and copy any invalid shared structure.
     Assumes the mark bits are cleared at entry.  */
  
! static void
! unshare_all_rtl_1 (rtx insn)
  {
    for (; insn; insn = NEXT_INSN (insn))
      if (INSN_P (insn))
--- 2488,2593 ----
  
    unshare_all_rtl (cfun->decl, insn);
  }
+ /* Check that ORIG is not marked when it should not be and mark ORIG as in use,
+    Recursively does the same for subexpressions.  */
+ 
+ static void
+ check_rtx_sharing (rtx orig, rtx insn)
+ {
+   rtx x = orig;
+   int i;
+   enum rtx_code code;
+   const char *format_ptr;
+ 
+   if (x == 0)
+     return;
+ 
+   if (rtx_can_be_shared_p (x))
+     return;
+ 
+   code = GET_CODE (x);
+ 
+   /* The chain of insns is not being checked.  */
+   if (INSN_P (x) || code == BARRIER || code == NOTE || code == CODE_LABEL)
+     return;
+ 
+   /* This rtx may not be shared.  If it has already been seen,
+      replace it with a copy of itself.  */
+ 
+   if (RTX_FLAG (x, used))
+     {
+       error ("Invalid rtl sharing found in the insn");
+       debug_rtx (insn);
+       error ("Shared rtx");
+       debug_rtx (x);
+       abort ();
+     }
+   RTX_FLAG (x, used) = 1;
+ 
+   /* Now scan the subexpressions recursively. */
+ 
+   format_ptr = GET_RTX_FORMAT (code);
+ 
+   for (i = 0; i < GET_RTX_LENGTH (code); i++)
+     {
+       switch (*format_ptr++)
+ 	{
+ 	case 'e':
+ 	  check_rtx_sharing (XEXP (x, i), insn);
+ 	  break;
+ 
+ 	case 'E':
+ 	  if (XVEC (x, i) != NULL)
+ 	    {
+ 	      int j;
+ 	      int len = XVECLEN (x, i);
+ 
+ 	      for (j = 0; j < len; j++)
+ 		{
+ 		  /* We allow sharing of ASM_OPERANDS inside single instruction.  */
+ 		  if (j && GET_CODE (XVECEXP (x, i, j)) == SET
+ 		      && GET_CODE (SET_SRC (XVECEXP (x, i, j))) == ASM_OPERANDS)
+ 		    check_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
+ 		  else
+ 		    check_rtx_sharing (XVECEXP (x, i, j), insn);
+ 		}
+ 	    }
+ 	  break;
+ 	}
+     }
+   return;
+ }
+ 
+ /* Go through all the RTL insn bodies and chec that there is no inexpected
+    sharing in between the subexpressions.  */
+ 
+ void
+ check_rtl_sharing (void)
+ {
+   rtx p;
+ 
+   for (p = get_insns (); p; p = NEXT_INSN (p))
+     if (INSN_P (p))
+       {
+ 	reset_used_flags (PATTERN (p));
+ 	reset_used_flags (REG_NOTES (p));
+ 	reset_used_flags (LOG_LINKS (p));
+       }
+ 
+   for (p = get_insns (); p; p = NEXT_INSN (p))
+     if (INSN_P (p))
+       {
+ 	check_rtx_sharing (PATTERN (p), p);
+ 	check_rtx_sharing (REG_NOTES (p), p);
+ 	check_rtx_sharing (LOG_LINKS (p), p);
+       }
+ }
  
  /* Go through all the RTL insn bodies and copy any invalid shared structure.
     Assumes the mark bits are cleared at entry.  */
  
! void
! unshare_all_rtl_in_chain (rtx insn)
  {
    for (; insn; insn = NEXT_INSN (insn))
      if (INSN_P (insn))
*************** copy_rtx_if_shared (rtx orig)
*** 2654,2698 ****
    if (x == 0)
      return 0;
  
!   code = GET_CODE (x);
! 
!   /* These types may be freely shared.  */
! 
!   switch (code)
!     {
!     case REG:
!     case QUEUED:
!     case CONST_INT:
!     case CONST_DOUBLE:
!     case CONST_VECTOR:
!     case SYMBOL_REF:
!     case CODE_LABEL:
!     case PC:
!     case CC0:
!     case SCRATCH:
!       /* SCRATCH must be shared because they represent distinct values.  */
!       return x;
! 
!     case CONST:
!       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
! 	 a LABEL_REF, it isn't sharable.  */
!       if (GET_CODE (XEXP (x, 0)) == PLUS
! 	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
! 	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
! 	return x;
!       break;
  
!     case INSN:
!     case JUMP_INSN:
!     case CALL_INSN:
!     case NOTE:
!     case BARRIER:
!       /* The chain of insns is not being copied.  */
!       return x;
  
!     default:
!       break;
!     }
  
    /* This rtx may not be shared.  If it has already been seen,
       replace it with a copy of itself.  */
--- 2747,2760 ----
    if (x == 0)
      return 0;
  
!   if (rtx_can_be_shared_p (x))
!     return x;
  
!   code = GET_CODE (x);
  
!   /* The chain of insns is not being checked.  */
!   if (INSN_P (x) || code == BARRIER || code == NOTE || code == CODE_LABEL)
!     return x;
  
    /* This rtx may not be shared.  If it has already been seen,
       replace it with a copy of itself.  */
*************** reset_used_flags (rtx x)
*** 2753,2790 ****
    if (x == 0)
      return;
  
    code = GET_CODE (x);
  
!   /* These types may be freely shared so we needn't do any resetting
!      for them.  */
  
!   switch (code)
!     {
!     case REG:
!     case QUEUED:
!     case CONST_INT:
!     case CONST_DOUBLE:
!     case CONST_VECTOR:
!     case SYMBOL_REF:
!     case CODE_LABEL:
!     case PC:
!     case CC0:
!       return;
  
!     case INSN:
!     case JUMP_INSN:
!     case CALL_INSN:
!     case NOTE:
!     case LABEL_REF:
!     case BARRIER:
!       /* The chain of insns is not being copied.  */
!       return;
  
!     default:
!       break;
      }
  
!   RTX_FLAG (x, used) = 0;
  
    format_ptr = GET_RTX_FORMAT (code);
    for (i = 0; i < GET_RTX_LENGTH (code); i++)
--- 2815,2868 ----
    if (x == 0)
      return;
  
+   if (rtx_can_be_shared_p (x))
+     return;
+ 
    code = GET_CODE (x);
  
!   /* The chain of insns is not being processed.  */
!   if (INSN_P (x) || code == BARRIER || code == NOTE || code == CODE_LABEL)
!     return;
  
!   RTX_FLAG (x, used) = 0;
  
!   format_ptr = GET_RTX_FORMAT (code);
!   for (i = 0; i < GET_RTX_LENGTH (code); i++)
!     {
!       switch (*format_ptr++)
! 	{
! 	case 'e':
! 	  reset_used_flags (XEXP (x, i));
! 	  break;
  
! 	case 'E':
! 	  for (j = 0; j < XVECLEN (x, i); j++)
! 	    reset_used_flags (XVECEXP (x, i, j));
! 	  break;
! 	}
      }
+ }
  
! /* Set all the USED bits in X to allow copy_rtx_if_shared to be used
!    to look for shared sub-parts.  */
! 
! void
! set_used_flags (rtx x)
! {
!   int i, j;
!   enum rtx_code code;
!   const char *format_ptr;
! 
!   if (rtx_can_be_shared_p (x))
!     return;
! 
!   code = GET_CODE (x);
! 
!   /* The chain of insns is not being processed.  */
!   if (INSN_P (x) || code == BARRIER || code == NOTE || code == CODE_LABEL)
!     return;
! 
!   RTX_FLAG (x, used) = 1;
  
    format_ptr = GET_RTX_FORMAT (code);
    for (i = 0; i < GET_RTX_LENGTH (code); i++)
*************** reset_used_flags (rtx x)
*** 2792,2803 ****
        switch (*format_ptr++)
  	{
  	case 'e':
! 	  reset_used_flags (XEXP (x, i));
  	  break;
  
  	case 'E':
  	  for (j = 0; j < XVECLEN (x, i); j++)
! 	    reset_used_flags (XVECEXP (x, i, j));
  	  break;
  	}
      }
--- 2870,2881 ----
        switch (*format_ptr++)
  	{
  	case 'e':
! 	  set_used_flags (XEXP (x, i));
  	  break;
  
  	case 'E':
  	  for (j = 0; j < XVECLEN (x, i); j++)
! 	    set_used_flags (XVECEXP (x, i, j));
  	  break;
  	}
      }
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.129
diff -c -3 -p -r1.129 ifcvt.c
*** ifcvt.c	2 Nov 2003 13:56:40 -0000	1.129
--- ifcvt.c	11 Nov 2003 17:28:09 -0000
*************** noce_emit_move_insn (rtx x, rtx y)
*** 700,705 ****
--- 700,715 ----
  		   GET_MODE_BITSIZE (inmode));
  }
  
+ /* Unshare sequence SEQ produced by if conversion.  We care to mark
+    all arguments that may be shared with outer instruction stream.  */
+ static void
+ unshare_ifcvt_sequence (struct noce_if_info *if_info, rtx seq)
+ {
+   set_used_flags (if_info->x);
+   set_used_flags (if_info->cond);
+   unshare_all_rtl_in_chain (seq);
+ }
+ 
  /* Convert "if (a != b) x = a; else x = b" into "x = a" and
     "if (a == b) x = a; else x = b" into "x = b".  */
  
*************** noce_try_move (struct noce_if_info *if_i
*** 734,739 ****
--- 744,750 ----
  	  start_sequence ();
  	  noce_emit_move_insn (if_info->x, y);
  	  seq = get_insns ();
+ 	  unshare_ifcvt_sequence (if_info, seq);
  	  end_sequence ();
  	  emit_insn_before_setloc (seq, if_info->jump,
  				   INSN_LOCATOR (if_info->insn_a));
*************** noce_try_store_flag (struct noce_if_info
*** 777,782 ****
--- 788,794 ----
  	noce_emit_move_insn (if_info->x, target);
  
        seq = get_insns ();
+       unshare_ifcvt_sequence (if_info, seq);
        end_sequence ();
        emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
  
*************** noce_try_store_flag_constants (struct no
*** 907,912 ****
--- 919,925 ----
  	noce_emit_move_insn (if_info->x, target);
  
        seq = get_insns ();
+       unshare_ifcvt_sequence (if_info, seq);
        end_sequence ();
  
        if (seq_contains_jump (seq))
*************** noce_try_addcc (struct noce_if_info *if_
*** 956,961 ****
--- 969,975 ----
  		noce_emit_move_insn (if_info->x, target);
  
  	      seq = get_insns ();
+ 	      unshare_ifcvt_sequence (if_info, seq);
  	      end_sequence ();
  	      emit_insn_before_setloc (seq, if_info->jump,
  				      INSN_LOCATOR (if_info->insn_a));
*************** noce_try_addcc (struct noce_if_info *if_
*** 994,999 ****
--- 1008,1014 ----
  		noce_emit_move_insn (if_info->x, target);
  
  	      seq = get_insns ();
+ 	      unshare_ifcvt_sequence (if_info, seq);
  	      end_sequence ();
  
  	      if (seq_contains_jump (seq))
*************** noce_try_store_flag_mask (struct noce_if
*** 1046,1051 ****
--- 1061,1067 ----
  	    noce_emit_move_insn (if_info->x, target);
  
  	  seq = get_insns ();
+ 	  unshare_ifcvt_sequence (if_info, seq);
  	  end_sequence ();
  
  	  if (seq_contains_jump (seq))
*************** noce_try_cmove (struct noce_if_info *if_
*** 1143,1148 ****
--- 1159,1165 ----
  	    noce_emit_move_insn (if_info->x, target);
  
  	  seq = get_insns ();
+ 	  unshare_ifcvt_sequence (if_info, seq);
  	  end_sequence ();
  	  emit_insn_before_setloc (seq, if_info->jump,
  				  INSN_LOCATOR (if_info->insn_a));
*************** noce_try_cmove_arith (struct noce_if_inf
*** 1305,1310 ****
--- 1322,1328 ----
      noce_emit_move_insn (x, target);
  
    tmp = get_insns ();
+   unshare_ifcvt_sequence (if_info, tmp);
    end_sequence ();
    emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
    return TRUE;
*************** noce_try_minmax (struct noce_if_info *if
*** 1550,1555 ****
--- 1568,1574 ----
      noce_emit_move_insn (if_info->x, target);
  
    seq = get_insns ();
+   unshare_ifcvt_sequence (if_info, seq);
    end_sequence ();
  
    if (seq_contains_jump (seq))
*************** noce_try_abs (struct noce_if_info *if_in
*** 1667,1672 ****
--- 1686,1692 ----
      noce_emit_move_insn (if_info->x, target);
  
    seq = get_insns ();
+   unshare_ifcvt_sequence (if_info, seq);
    end_sequence ();
  
    if (seq_contains_jump (seq))
*************** noce_process_if_block (struct ce_if_bloc
*** 1988,1995 ****
    if (orig_x != x)
      {
        start_sequence ();
!       noce_emit_move_insn (copy_rtx (orig_x), x);
        insn_b = get_insns ();
        end_sequence ();
  
        emit_insn_after_setloc (insn_b, test_bb->end, INSN_LOCATOR (insn_a));
--- 2008,2017 ----
    if (orig_x != x)
      {
        start_sequence ();
!       noce_emit_move_insn (orig_x, x);
        insn_b = get_insns ();
+       set_used_flags (orig_x);
+       unshare_all_rtl_in_chain (insn_b);
        end_sequence ();
  
        emit_insn_after_setloc (insn_b, test_bb->end, INSN_LOCATOR (insn_a));
Index: rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.c,v
retrieving revision 1.128
diff -c -3 -p -r1.128 rtl.c
*** rtl.c	18 Oct 2003 18:45:15 -0000	1.128
--- rtl.c	11 Nov 2003 17:28:09 -0000
*************** rtx_alloc (RTX_CODE code)
*** 173,195 ****
    PUT_CODE (rt, code);
    return rt;
  }
- 
  
! /* Create a new copy of an rtx.
!    Recursively copies the operands of the rtx,
!    except for those few rtx codes that are sharable.  */
! 
! rtx
! copy_rtx (rtx orig)
  {
!   rtx copy;
!   int i, j;
!   RTX_CODE code;
!   const char *format_ptr;
! 
!   code = GET_CODE (orig);
! 
!   switch (code)
      {
      case REG:
      case QUEUED:
--- 173,184 ----
    PUT_CODE (rt, code);
    return rt;
  }
  
! /* Return true when X can be shared.  */
! bool
! rtx_can_be_shared_p (rtx x)
  {
!   switch (GET_CODE (x))
      {
      case REG:
      case QUEUED:
*************** copy_rtx (rtx orig)
*** 197,227 ****
      case CONST_DOUBLE:
      case CONST_VECTOR:
      case SYMBOL_REF:
      case CODE_LABEL:
      case PC:
      case CC0:
      case SCRATCH:
        /* SCRATCH must be shared because they represent distinct values.  */
      case ADDRESSOF:
!       return orig;
  
      case CONST:
        /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
  	 a LABEL_REF, it isn't sharable.  */
!       if (GET_CODE (XEXP (orig, 0)) == PLUS
! 	  && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
! 	  && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
! 	return orig;
        break;
  
-       /* A MEM with a constant address is not sharable.  The problem is that
- 	 the constant address may need to be reloaded.  If the mem is shared,
- 	 then reloading one copy of this mem will cause all copies to appear
- 	 to have been reloaded.  */
- 
      default:
        break;
      }
  
    copy = rtx_alloc (code);
  
--- 186,232 ----
      case CONST_DOUBLE:
      case CONST_VECTOR:
      case SYMBOL_REF:
+     case LABEL_REF:
      case CODE_LABEL:
      case PC:
      case CC0:
      case SCRATCH:
        /* SCRATCH must be shared because they represent distinct values.  */
      case ADDRESSOF:
!       return true;
  
      case CONST:
        /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
  	 a LABEL_REF, it isn't sharable.  */
!       if (GET_CODE (XEXP (x, 0)) == PLUS
! 	  && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
! 	  && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
! 	return true;
        break;
  
      default:
        break;
      }
+   return false;
+ }
+ 
+ 
+ /* Create a new copy of an rtx.
+    Recursively copies the operands of the rtx,
+    except for those few rtx codes that are sharable.  */
+ 
+ rtx
+ copy_rtx (rtx orig)
+ {
+   rtx copy;
+   int i, j;
+   RTX_CODE code;
+   const char *format_ptr;
+ 
+   code = GET_CODE (orig);
+ 
+   if (rtx_can_be_shared_p (orig))
+     return orig;
  
    copy = rtx_alloc (code);
  
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.437
diff -c -3 -p -r1.437 rtl.h
*** rtl.h	18 Oct 2003 18:45:15 -0000	1.437
--- rtl.h	11 Nov 2003 17:28:09 -0000
*************** extern void set_reg_attrs_for_parm (rtx,
*** 1457,1462 ****
--- 1457,1463 ----
  extern rtx rtx_alloc (RTX_CODE);
  extern rtvec rtvec_alloc (int);
  extern rtx copy_rtx (rtx);
+ extern bool rtx_can_be_shared_p (rtx);
  
  /* In emit-rtl.c */
  extern rtx copy_rtx_if_shared (rtx);
*************** extern void delete_insns_since (rtx);
*** 2036,2041 ****
--- 2037,2043 ----
  extern void mark_reg_pointer (rtx, int);
  extern void mark_user_reg (rtx);
  extern void reset_used_flags (rtx);
+ extern void set_used_flags (rtx);
  extern void reorder_insns (rtx, rtx, rtx);
  extern void reorder_insns_nobb (rtx, rtx, rtx);
  extern int get_max_uid (void);
*************** extern void set_new_first_and_last_insn 
*** 2051,2056 ****
--- 2053,2060 ----
  extern void set_new_first_and_last_label_num (int, int);
  extern void set_new_last_label_num (int);
  extern void unshare_all_rtl_again (rtx);
+ extern void unshare_all_rtl_in_chain (rtx);
+ extern void check_rtl_sharing (void);
  extern void set_first_insn (rtx);
  extern void set_last_insn (rtx);
  extern void link_cc0_insns (rtx);
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.843
diff -c -3 -p -r1.843 toplev.c
*** toplev.c	1 Nov 2003 02:23:44 -0000	1.843
--- toplev.c	11 Nov 2003 17:28:09 -0000
*************** rest_of_compilation (tree decl)
*** 3416,3421 ****
--- 3416,3426 ----
    if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
      rest_of_handle_regmove (decl, insns);
  
+ #ifdef ENABLE_CHECKING
+   /* Last point where memories should be unique.  */
+   check_rtl_sharing ();
+ #endif
+ 
    /* Do unconditional splitting before register allocation to allow machine
       description to add extra information not needed previously.  */
    split_all_insns (1);
*************** rest_of_compilation (tree decl)
*** 3613,3618 ****
--- 3618,3628 ----
  
    /* CFG is no longer maintained up-to-date.  */
    free_bb_for_insn ();
+ 
+ #ifdef ENABLE_CHECKING
+   check_rtl_sharing ();
+ #endif
+ 
  
    if (targetm.machine_dependent_reorg != 0)
      rest_of_handle_machine_reorg (decl, insns);
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.618
diff -c -3 -p -r1.618 i386.c
*** config/i386/i386.c	7 Nov 2003 09:26:06 -0000	1.618
--- config/i386/i386.c	11 Nov 2003 17:28:12 -0000
*************** put_condition_code (enum rtx_code code, 
*** 6998,7007 ****
  void
  print_reg (rtx x, int code, FILE *file)
  {
    /* Code -1 indicates we are called from print_rtx, and it is not
       an error for a virtual register to appear here.  */
    if (code == -1)
!     code = 0;
    else if (REGNO (x) == ARG_POINTER_REGNUM
  	   || REGNO (x) == FRAME_POINTER_REGNUM
  	   || REGNO (x) == FLAGS_REG
--- 6998,7008 ----
  void
  print_reg (rtx x, int code, FILE *file)
  {
+   bool noerror = false;
    /* Code -1 indicates we are called from print_rtx, and it is not
       an error for a virtual register to appear here.  */
    if (code == -1)
!     code = 0, noerror = 1;
    else if (REGNO (x) == ARG_POINTER_REGNUM
  	   || REGNO (x) == FRAME_POINTER_REGNUM
  	   || REGNO (x) == FLAGS_REG
*************** print_reg (rtx x, int code, FILE *file)
*** 7035,7041 ****
        switch (code)
  	{
  	  case 0:
! 	    error ("extended registers have no high halves");
  	    break;
  	  case 1:
  	    fprintf (file, "r%ib", REGNO (x) - FIRST_REX_INT_REG + 8);
--- 7036,7043 ----
        switch (code)
  	{
  	  case 0:
! 	    if (!noerror)
! 	      error ("extended registers have no high halves");
  	    break;
  	  case 1:
  	    fprintf (file, "r%ib", REGNO (x) - FIRST_REX_INT_REG + 8);
*************** print_reg (rtx x, int code, FILE *file)
*** 7050,7056 ****
  	    fprintf (file, "r%i", REGNO (x) - FIRST_REX_INT_REG + 8);
  	    break;
  	  default:
! 	    error ("unsupported operand size for extended register");
  	    break;
  	}
        return;
--- 7052,7059 ----
  	    fprintf (file, "r%i", REGNO (x) - FIRST_REX_INT_REG + 8);
  	    break;
  	  default:
! 	    if (!noerror)
! 	      error ("unsupported operand size for extended register");
  	    break;
  	}
        return;
*************** print_reg (rtx x, int code, FILE *file)
*** 7072,7087 ****
        /* FALLTHRU */
      case 16:
      case 2:
!       fputs (hi_reg_name[REGNO (x)], file);
        break;
      case 1:
!       fputs (qi_reg_name[REGNO (x)], file);
        break;
      case 0:
!       fputs (qi_high_reg_name[REGNO (x)], file);
        break;
      default:
!       abort ();
      }
  }
  
--- 7075,7100 ----
        /* FALLTHRU */
      case 16:
      case 2:
!       if (REGNO (x) < sizeof (hi_reg_name) / sizeof (char *))
!         fputs (hi_reg_name[REGNO (x)], file);
!       else if (!noerror)
!         error ("unsupported 16-bit register");
        break;
      case 1:
!       if (REGNO (x) < sizeof (qi_reg_name) / sizeof (char *))
!         fputs (qi_reg_name[REGNO (x)], file);
!       else if (!noerror)
!         error ("unsupported 8-bit register");
        break;
      case 0:
!       if (REGNO (x) < sizeof (qi_high_reg_name) / sizeof (char *))
!         fputs (qi_high_reg_name[REGNO (x)], file);
!       else if (!noerror)
!         error ("unsupported 8-bit register");
        break;
      default:
!       if (!noerror)
!         abort ();
      }
  }
  



More information about the Gcc-patches mailing list