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]

[patch RFC] Fix bogus RTL sharing error


Hi,

I've looked at the errors for invalid RTL sharing for Mips and
SH with the RTL sharing verifier.
A typical mips example of the insn causing the error is

(insn 68 24 31 (sequence [
            (jump_insn 29 24 26 (set (pc)
                    (if_then_else (ne (reg:SI 4 $4 [199])
                            (const_int 0 [0x0]))
                        (label_ref:SI 19)
                        (pc))) 274 {*branch_equalitysi} (nil)
                (expr_list:REG_BR_PRED (const_int 6 [0x6])
                    (expr_list:REG_DEAD (reg:SI 4 $4 [199])
                        (expr_list:REG_BR_PROB (const_int 8900 [0x22c4])
                            (nil)))))
            (insn 26 29 31 (set (reg/v:SI 16 $16 [orig:193 value ] [193])
                    (plus:SI (reg:SI 2 $2 [197])
                        (reg:SI 3 $3 [198]))) 6 {*addsi3} (nil)
                (nil))
        ]) -1 (nil)
    (nil))

and the verifier complains that the subexpression

	(set (reg/v:SI 16 $16 [orig:193 value ] [193])
             (plus:SI (reg:SI 2 $2 [197])
                 (reg:SI 3 $3 [198]))

is shared invalidly.  But it seems that this error is bogus,
though I could be wrong about that.
During verification, verify_rtl_sharing clears the used flags
of all insn bodies and then checks them with marking the flag:

  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);
      }

In the above rtl which causes the error, verify_rtx_sharing
marked all used flags of the subexpressions of sequence.
However, since reset_used_flags doesn't go through the insn,
the used flag of the above set subexpression is never cleared.
Then if verify_rtl_sharing was invoked multiple times, that
subexpression causes a bogus error.  The appended patch adds
a boolean argument to make reset_used_flags go through
the insns recursively.
Bootstrapped and regtested with the top level "make -k check"
on i686-pc-linux-gnu.

Regards,
	kaz
--
2006-11-27  Kaz Kojima  <kkojima@gcc.gnu.org>

	* emit-rtl.c (reset_used_flags_1): New.
	(verify_rtl_sharing): Use reset_used_flags_1 instead of
	reset_used_flags for pattern of the insn.
	(reset_used_flags): Use reset_used_flags_1.

--- ORIG/trunk/gcc/emit-rtl.c	2006-11-12 20:14:34.000000000 +0900
+++ LOCAL/trunk/gcc/emit-rtl.c	2006-11-25 22:50:16.000000000 +0900
@@ -185,6 +185,7 @@ static reg_attrs *get_reg_attrs (tree, i
 static tree component_ref_for_mem_expr (tree);
 static rtx gen_const_vector (enum machine_mode, int);
 static void copy_rtx_if_shared_1 (rtx *orig);
+static void reset_used_flags_1 (rtx, bool);
 
 /* Probability of the conditional branch currently proceeded by try_split.
    Set to -1 otherwise.  */
@@ -2289,7 +2290,7 @@ verify_rtl_sharing (void)
   for (p = get_insns (); p; p = NEXT_INSN (p))
     if (INSN_P (p))
       {
-	reset_used_flags (PATTERN (p));
+	reset_used_flags_1 (PATTERN (p), true);
 	reset_used_flags (REG_NOTES (p));
 	reset_used_flags (LOG_LINKS (p));
       }
@@ -2494,6 +2495,12 @@ repeat:
 void
 reset_used_flags (rtx x)
 {
+  reset_used_flags_1 (x, false); 
+}
+
+static void
+reset_used_flags_1 (rtx x, bool handle_insn)
+{
   int i, j;
   enum rtx_code code;
   const char *format_ptr;
@@ -2524,6 +2531,8 @@ repeat:
     case INSN:
     case JUMP_INSN:
     case CALL_INSN:
+      if (handle_insn)
+	break;
     case NOTE:
     case LABEL_REF:
     case BARRIER:
@@ -2549,12 +2558,12 @@ repeat:
               x = XEXP (x, i);
 	      goto repeat;
             }
-	  reset_used_flags (XEXP (x, i));
+	  reset_used_flags_1 (XEXP (x, i), handle_insn);
 	  break;
 
 	case 'E':
 	  for (j = 0; j < XVECLEN (x, i); j++)
-	    reset_used_flags (XVECEXP (x, i, j));
+	    reset_used_flags_1 (XVECEXP (x, i, j), handle_insn);
 	  break;
 	}
     }


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