* emit-rtl.c (set_used_flags): New.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 29 Nov 2003 01:13:43 +0000 (01:13 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 29 Nov 2003 01:13:43 +0000 (01:13 +0000)
(verify_rtx_sharing, verify_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.
* 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 (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain):
Declare.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74030 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/emit-rtl.c
gcc/ifcvt.c
gcc/rtl.h

index 1fecf91..920f03b 100644 (file)
@@ -1,3 +1,18 @@
+2003-11-28  Jan Hubicka  <jh@suse.cz>
+
+       * emit-rtl.c (set_used_flags): New.
+       (verify_rtx_sharing, verify_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.
+       * 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 (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain):
+       Declare.
+
 2003-11-28  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/h8300/h8300.md: Fix a comment typo.
 
 2003-11-24  Jan Hubicka  <jh@suse.cz>
 
-       * fold-const.c (fold):  Do not return early when optimizing COMPONENT_REF
-       and constant.
+       * fold-const.c (fold):  Do not return early when optimizing
+       COMPONENT_REF and constant.
 
 2003-11-24  Kazu Hirata  <kazu@cs.umass.edu>
 
index a528641..0f7e677 100644 (file)
@@ -180,7 +180,6 @@ static rtx make_jump_insn_raw (rtx);
 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);
@@ -2450,7 +2449,7 @@ unshare_all_rtl (tree fndecl, rtx insn)
   unshare_all_decls (DECL_INITIAL (fndecl));
 
   /* Unshare just about everything else.  */
-  unshare_all_rtl_1 (insn);
+  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
@@ -2492,11 +2491,138 @@ unshare_all_rtl_again (rtx insn)
   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
+verify_rtx_sharing (rtx orig, rtx insn)
+{
+  rtx x = orig;
+  int i;
+  enum rtx_code code;
+  const char *format_ptr;
+
+  if (x == 0)
+    return;
+
+  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 LABEL_REF:
+    case CODE_LABEL:
+    case PC:
+    case CC0:
+    case SCRATCH:
+      /* SCRATCH must be shared because they represent distinct values.  */
+      return;
+
+    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;
+      break;
+
+    case MEM:
+      /* A MEM is allowed to be shared if its address is constant.  */
+      if (CONSTANT_ADDRESS_P (XEXP (x, 0))
+         || reload_completed || reload_in_progress)
+       return;
+
+      break;
+
+    default:
+      break;
+    }
+
+  /* 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':
+         verify_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)
+                   verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
+                 else
+                   verify_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
+verify_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))
+      {
+       verify_rtx_sharing (PATTERN (p), p);
+       verify_rtx_sharing (REG_NOTES (p), p);
+       verify_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.  */
 
-static void
-unshare_all_rtl_1 (rtx insn)
+void
+unshare_all_rtl_in_chain (rtx insn)
 {
   for (; insn; insn = NEXT_INSN (insn))
     if (INSN_P (insn))
@@ -2668,6 +2794,7 @@ copy_rtx_if_shared (rtx orig)
     case CONST_DOUBLE:
     case CONST_VECTOR:
     case SYMBOL_REF:
+    case LABEL_REF:
     case CODE_LABEL:
     case PC:
     case CC0:
@@ -2804,6 +2931,69 @@ reset_used_flags (rtx x)
        }
     }
 }
+
+/* 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 (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) = 1;
+
+  format_ptr = GET_RTX_FORMAT (code);
+  for (i = 0; i < GET_RTX_LENGTH (code); i++)
+    {
+      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;
+       }
+    }
+}
 \f
 /* Copy X if necessary so that it won't be altered by changes in OTHER.
    Return X or the rtx for the pseudo reg the value of X was copied into.
index f7fddf9..29f3f00 100644 (file)
@@ -700,6 +700,16 @@ noce_emit_move_insn (rtx x, rtx y)
                   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".  */
 
@@ -734,6 +744,7 @@ noce_try_move (struct noce_if_info *if_info)
          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));
@@ -777,6 +788,7 @@ noce_try_store_flag (struct noce_if_info *if_info)
        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));
 
@@ -907,6 +919,7 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
        noce_emit_move_insn (if_info->x, target);
 
       seq = get_insns ();
+      unshare_ifcvt_sequence (if_info, seq);
       end_sequence ();
 
       if (seq_contains_jump (seq))
@@ -944,9 +957,11 @@ noce_try_addcc (struct noce_if_info *if_info)
        {
          start_sequence ();
          target = emit_conditional_add (if_info->x, code,
-                                        XEXP (cond, 0), XEXP (cond, 1),
+                                        XEXP (cond, 0),
+                                        XEXP (cond, 1),
                                         VOIDmode,
-                                        if_info->b, XEXP (if_info->a, 1),
+                                        if_info->b,
+                                        XEXP (if_info->a, 1),
                                         GET_MODE (if_info->x),
                                         (code == LTU || code == GEU
                                          || code == LEU || code == GTU));
@@ -956,6 +971,7 @@ noce_try_addcc (struct noce_if_info *if_info)
                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));
@@ -994,6 +1010,7 @@ noce_try_addcc (struct noce_if_info *if_info)
                noce_emit_move_insn (if_info->x, target);
 
              seq = get_insns ();
+             unshare_ifcvt_sequence (if_info, seq);
              end_sequence ();
 
              if (seq_contains_jump (seq))
@@ -1037,7 +1054,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
                                     reversep, -1);
       if (target)
         target = expand_simple_binop (GET_MODE (if_info->x), AND,
-                                     if_info->x, target, if_info->x, 0,
+                                     if_info->x,
+                                     target, if_info->x, 0,
                                      OPTAB_WIDEN);
 
       if (target)
@@ -1046,6 +1064,7 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
            noce_emit_move_insn (if_info->x, target);
 
          seq = get_insns ();
+         unshare_ifcvt_sequence (if_info, seq);
          end_sequence ();
 
          if (seq_contains_jump (seq))
@@ -1143,6 +1162,7 @@ noce_try_cmove (struct noce_if_info *if_info)
            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));
@@ -1260,7 +1280,9 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
       if (is_mem)
        {
           tmp = gen_reg_rtx (GET_MODE (b));
-         tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, b));
+         tmp = emit_insn (gen_rtx_SET (VOIDmode,
+                                       tmp,
+                                       b));
        }
       else if (! insn_b)
        goto end_seq_and_fail;
@@ -1305,6 +1327,7 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
     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;
@@ -1550,6 +1573,7 @@ noce_try_minmax (struct noce_if_info *if_info)
     noce_emit_move_insn (if_info->x, target);
 
   seq = get_insns ();
+  unshare_ifcvt_sequence (if_info, seq);
   end_sequence ();
 
   if (seq_contains_jump (seq))
@@ -1667,6 +1691,7 @@ noce_try_abs (struct noce_if_info *if_info)
     noce_emit_move_insn (if_info->x, target);
 
   seq = get_insns ();
+  unshare_ifcvt_sequence (if_info, seq);
   end_sequence ();
 
   if (seq_contains_jump (seq))
@@ -1988,8 +2013,10 @@ noce_process_if_block (struct ce_if_block * ce_info)
   if (orig_x != x)
     {
       start_sequence ();
-      noce_emit_move_insn (copy_rtx (orig_x), x);
+      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));
@@ -2585,7 +2612,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
     }
 
   /* Attempt to generate the conditional trap.  */
-  seq = gen_cond_trap (code, XEXP (cond, 0), XEXP (cond, 1),
+  seq = gen_cond_trap (code, XEXP (cond, 0),
+                      XEXP (cond, 1),
                       TRAP_CODE (PATTERN (trap)));
   if (seq == NULL)
     return FALSE;
index 33027e6..44fd965 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2036,6 +2036,7 @@ extern void delete_insns_since (rtx);
 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);
@@ -2051,6 +2052,8 @@ extern void set_new_first_and_last_insn (rtx, rtx);
 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 verify_rtl_sharing (void);
 extern void set_first_insn (rtx);
 extern void set_last_insn (rtx);
 extern void link_cc0_insns (rtx);