rtl.def (COND_EXEC): New.
authorRichard Henderson <rth@cygnus.com>
Fri, 7 Apr 2000 09:24:45 +0000 (02:24 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 7 Apr 2000 09:24:45 +0000 (02:24 -0700)
        * rtl.def (COND_EXEC): New.
        * rtl.h (COND_EXEC_TEST, COND_EXEC_CODE): New.
        * tm.texi (MAX_CONDITIONAL_EXECUTE): Document.

        * genconfig.c (have_cond_arith_flag): Remove.
        (have_cond_exec_flag): New.
        (walk_insn_part): Detect COND_EXEC, not arithmetic in IF_THEN_ELSE.
        (main): Print HAVE_conditional_execution.

        * haifa-sched.c (haifa_classify_insn): Recognize COND_EXEC.
        (sched_analyze_insn, print_pattern): Likewise.
        * reload.c (find_equiv_reg): Likewise.
        * rtlanal.c (reg_referenced_p): Likewise.
        (note_stores, dead_or_set_regno_p): Likewise.
        (reg_overlap_mentioned_p): Rewrite to use a switch.

From-SVN: r32997

gcc/ChangeLog
gcc/genconfig.c
gcc/haifa-sched.c
gcc/reload.c
gcc/rtl.def
gcc/rtl.h
gcc/rtlanal.c
gcc/tm.texi

index c28a597..75360a0 100644 (file)
@@ -1,5 +1,21 @@
 2000-04-07  Richard Henderson  <rth@cygnus.com>
 
+       * rtl.def (COND_EXEC): New.
+       * rtl.h (COND_EXEC_TEST, COND_EXEC_CODE): New.
+       * tm.texi (MAX_CONDITIONAL_EXECUTE): Document.
+
+       * genconfig.c (have_cond_arith_flag): Remove.
+       (have_cond_exec_flag): New.
+       (walk_insn_part): Detect COND_EXEC, not arithmetic in IF_THEN_ELSE.
+       (main): Print HAVE_conditional_execution.
+
+       * haifa-sched.c (haifa_classify_insn): Recognize COND_EXEC.
+       (sched_analyze_insn, print_pattern): Likewise.
+       * reload.c (find_equiv_reg): Likewise.
+       * rtlanal.c (reg_referenced_p): Likewise.
+       (note_stores, dead_or_set_regno_p): Likewise.
+       (reg_overlap_mentioned_p): Rewrite to use a switch.
+
        * ggc.h (struct rtx_def): Forward declare.
 
        * print-rtl.c (debug_rtx_range): New.
index 8c8ee9d..65c8701 100644 (file)
@@ -39,7 +39,7 @@ static int max_dup_operands;    /* Largest number of match_dup in any insn.  */
 static int max_clobbers_per_insn;
 static int have_cc0_flag;
 static int have_cmove_flag;
-static int have_cond_arith_flag;
+static int have_cond_exec_flag;
 static int have_lo_sum_flag;
 static int have_peephole_flag;
 static int have_peephole2_flag;
@@ -131,21 +131,17 @@ walk_insn_part (part, recog_p, non_pc_set_src)
         two arms of the IF_THEN_ELSE are both MATCH_OPERAND.  Otherwise,
         we have some specific IF_THEN_ELSE construct (like the doz
         instruction on the RS/6000) that can't be used in the general
-        context we want it for.  If the first operand is an arithmetic
-        operation and the second is a MATCH_OPERNAND, show we have
-        conditional arithmetic.  */
+        context we want it for.  */
 
       if (recog_p && non_pc_set_src
          && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
          && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
        have_cmove_flag = 1;
-      else if (recog_p && non_pc_set_src
-              && (GET_RTX_CLASS (GET_CODE (XEXP (part, 1))) == '1'
-                  || GET_RTX_CLASS (GET_CODE (XEXP (part, 1))) == '2'
-                  || GET_RTX_CLASS (GET_CODE (XEXP (part, 1))) == 'c')
-              && GET_CODE (XEXP (XEXP (part, 1), 0)) == MATCH_OPERAND
-              && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
-       have_cond_arith_flag = 1;
+      break;
+
+    case COND_EXEC:
+      if (recog_p)
+       have_cond_exec_flag = 1;
       break;
 
     case REG: case CONST_INT: case SYMBOL_REF:
@@ -341,8 +337,9 @@ from the machine description file `md'.  */\n\n");
 
   /* This is conditionally defined, in case the user writes code which emits
      more splits than we can readily see (and knows s/he does it).  */
-  printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n",
-         max_insns_per_split);
+  printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
+  printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);
+  printf ("#endif\n");
 
   if (have_cc0_flag)
     printf ("#define HAVE_cc0\n");
@@ -350,11 +347,8 @@ from the machine description file `md'.  */\n\n");
   if (have_cmove_flag)
     printf ("#define HAVE_conditional_move\n");
 
-#if 0
-  /* Disabled.  See the discussion in jump.c.  */
-  if (have_cond_arith_flag)
-    printf ("#define HAVE_conditional_arithmetic\n");
-#endif
+  if (have_cond_exec_flag)
+    printf ("#define HAVE_conditional_execution\n");
 
   if (have_lo_sum_flag)
     printf ("#define HAVE_lo_sum\n");
index eb6f121..36a4cc8 100644 (file)
@@ -2588,6 +2588,7 @@ haifa_classify_insn (insn)
                WORST_CLASS (tmp_class,
                           may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)), 0));
              break;
+           case COND_EXEC:
            case TRAP_IF:
              tmp_class = TRAP_RISKY;
              break;
@@ -2617,6 +2618,7 @@ haifa_classify_insn (insn)
            WORST_CLASS (tmp_class,
                         may_trap_exp (SET_SRC (pat), 0));
          break;
+       case COND_EXEC:
        case TRAP_IF:
          tmp_class = TRAP_RISKY;
          break;
@@ -3649,6 +3651,15 @@ sched_analyze_insn (deps, x, insn, loop_notes)
   int maxreg = max_reg_num ();
   int i;
 
+  if (code == COND_EXEC)
+    {
+      sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);
+
+      /* ??? Should be recording conditions so we reduce the number of
+        false dependancies.  */
+      x = COND_EXEC_CODE (x);
+      code = GET_CODE (x);
+    }
   if (code == SET || code == CLOBBER)
     sched_analyze_1 (deps, x, insn);
   else if (code == PARALLEL)
@@ -3656,11 +3667,19 @@ sched_analyze_insn (deps, x, insn, loop_notes)
       register int i;
       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
        {
-         code = GET_CODE (XVECEXP (x, 0, i));
+         rtx sub = XVECEXP (x, 0, i);
+         code = GET_CODE (sub);
+
+         if (code == COND_EXEC)
+           {
+             sched_analyze_2 (deps, COND_EXEC_TEST (sub), insn);
+             sub = COND_EXEC_CODE (sub);
+             code = GET_CODE (sub);
+           }
          if (code == SET || code == CLOBBER)
-           sched_analyze_1 (deps, XVECEXP (x, 0, i), insn);
+           sched_analyze_1 (deps, sub, insn);
          else
-           sched_analyze_2 (deps, XVECEXP (x, 0, i), insn);
+           sched_analyze_2 (deps, sub, insn);
        }
     }
   else
@@ -5313,6 +5332,11 @@ print_pattern (buf, x, verbose)
       print_value (t1, XEXP (x, 0), verbose);
       sprintf (buf, "use %s", t1);
       break;
+    case COND_EXEC:
+      print_value (t1, COND_EXEC_CODE (x), verbose);
+      print_value (t2, COND_EXEC_TEST (x), verbose);
+      sprintf (buf, "cond_exec %s %s", t1, t2);
+      break;
     case PARALLEL:
       {
        int i;
index 3e5d277..128af48 100644 (file)
@@ -6190,6 +6190,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
             If GOAL is a memory ref and its address is not constant,
             and this insn P changes a register used in GOAL, return 0.  */
 
+         if (GET_CODE (pat) == COND_EXEC)
+           pat = COND_EXEC_CODE (pat);
          if (GET_CODE (pat) == SET || GET_CODE (pat) == CLOBBER)
            {
              register rtx dest = SET_DEST (pat);
@@ -6232,6 +6234,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
              for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
                {
                  register rtx v1 = XVECEXP (pat, 0, i);
+                 if (GET_CODE (v1) == COND_EXEC)
+                   v1 = COND_EXEC_CODE (v1);
                  if (GET_CODE (v1) == SET || GET_CODE (v1) == CLOBBER)
                    {
                      register rtx dest = SET_DEST (v1);
index 570abdc..69c14e0 100644 (file)
@@ -900,6 +900,13 @@ DEF_RTL_EXPR(CALL_PLACEHOLDER, "call_placeholder", "uuuu", 'x')
    of canonical RTL.  It is, however, easier to manipulate this way.  */
 DEF_RTL_EXPR(PHI, "phi", "E", 'x')
 
+/* Conditionally execute code.
+   Operand 0 is the condition that if true, the code is executed.
+   Operand 1 is the code to be executed (typically a SET). 
+
+   Semantics are that there are no side effects if the condition
+   is false.  */
+DEF_RTL_EXPR(COND_EXEC, "cond_exec", "ee", 'x')
 
 /*
 Local variables:
index 517a0db..124c6bf 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -807,6 +807,12 @@ extern const char * const note_insn_name[];
 #define TRAP_CONDITION(RTX) XCEXP(RTX, 0, TRAP_IF)
 #define TRAP_CODE(RTX) XCEXP(RTX, 1, TRAP_IF)
 
+/* For a COND_EXEC rtx, COND_EXEC_TEST is the condition to base
+   conditionally executing the code on, COND_EXEC_CODE is the code
+   to execute if the condition is true.  */
+#define COND_EXEC_TEST(RTX) XCEXP(RTX, 0, COND_EXEC)
+#define COND_EXEC_CODE(RTX) XCEXP(RTX, 1, COND_EXEC)
+
 /* 1 in a SYMBOL_REF if it addresses this function's constants pool.  */
 #define CONSTANT_POOL_ADDRESS_P(RTX) ((RTX)->unchanging)
 
index b44b992..d9087cd 100644 (file)
@@ -429,6 +429,11 @@ reg_referenced_p (x, body)
          return 1;
       return 0;
 
+    case COND_EXEC:
+      if (reg_overlap_mentioned_p (x, COND_EXEC_TEST (body)))
+       return 1;
+      return reg_referenced_p (x, COND_EXEC_CODE (body));
+
     default:
       return 0;
     }
@@ -949,52 +954,61 @@ reg_overlap_mentioned_p (x, in)
   /* If either argument is a constant, then modifying X can not affect IN.  */
   if (CONSTANT_P (x) || CONSTANT_P (in))
     return 0;
-  else if (GET_CODE (x) == SUBREG)
+
+  switch (GET_CODE (x))
     {
+    case SUBREG:
       regno = REGNO (SUBREG_REG (x));
       if (regno < FIRST_PSEUDO_REGISTER)
        regno += SUBREG_WORD (x);
-    }
-  else if (GET_CODE (x) == REG)
-    regno = REGNO (x);
-  else if (GET_CODE (x) == MEM)
-    {
-      const char *fmt;
-      int i;
+      goto do_reg;
 
-      if (GET_CODE (in) == MEM)
-       return 1;
+    case REG:
+      regno = REGNO (x);
+    do_reg:
+      endregno = regno + (regno < FIRST_PSEUDO_REGISTER
+                         ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+      return refers_to_regno_p (regno, endregno, in, NULL_PTR);
 
-      fmt = GET_RTX_FORMAT (GET_CODE (in));
+    case MEM:
+      {
+       const char *fmt;
+       int i;
 
-      for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
-       if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
+       if (GET_CODE (in) == MEM)
          return 1;
 
-      return 0;
-    }
-  else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
-          || GET_CODE (x) == CC0)
-    return reg_mentioned_p (x, in);
-  else if (GET_CODE (x) == PARALLEL
-          && GET_MODE (x) == BLKmode)
-    {
-      register int i;
+       fmt = GET_RTX_FORMAT (GET_CODE (in));
+       for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
+         if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
+           return 1;
 
-      /* If any register in here refers to it
-        we return true.  */
-      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
-       if (reg_overlap_mentioned_p (SET_DEST (XVECEXP (x, 0, i)), in))
-         return 1;
-      return 0;
-    }
-  else
-    abort ();
+       return 0;
+      }
+
+    case SCRATCH:
+    case PC:
+    case CC0:
+      return reg_mentioned_p (x, in);
 
-  endregno = regno + (regno < FIRST_PSEUDO_REGISTER
-                     ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+    case PARALLEL:
+      if (GET_MODE (x) == BLKmode)
+       {
+         register int i;
 
-  return refers_to_regno_p (regno, endregno, in, NULL_PTR);
+         /* If any register in here refers to it we return true.  */
+         for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+           if (reg_overlap_mentioned_p (SET_DEST (XVECEXP (x, 0, i)), in))
+             return 1;
+         return 0;
+       }
+      break;
+
+    default:
+      break;
+    }
+
+  abort ();
 }
 \f
 /* Used for communications between the next few functions.  */
@@ -1108,7 +1122,9 @@ note_stores (x, fun, data)
      void (*fun) PARAMS ((rtx, rtx, void *));
      void *data;
 {
-  if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
+  if (GET_CODE (x) == COND_EXEC)
+    x = COND_EXEC_CODE (x);
+  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
     {
       register rtx dest = SET_DEST (x);
       while ((GET_CODE (dest) == SUBREG
@@ -1135,6 +1151,8 @@ note_stores (x, fun, data)
       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
        {
          register rtx y = XVECEXP (x, 0, i);
+         if (GET_CODE (y) == COND_EXEC)
+           y = COND_EXEC_CODE (y);
          if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
            {
              register rtx dest = SET_DEST (y);
@@ -1213,7 +1231,7 @@ dead_or_set_regno_p (insn, test_regno)
      unsigned int test_regno;
 {
   unsigned int regno, endregno;
-  rtx link;
+  rtx link, pattern;
 
   /* See if there is a death note for something that includes
      TEST_REGNO.  */
@@ -1236,7 +1254,12 @@ dead_or_set_regno_p (insn, test_regno)
       && find_regno_fusage (insn, CLOBBER, test_regno))
     return 1;
 
-  if (GET_CODE (PATTERN (insn)) == SET)
+  pattern = PATTERN (insn);
+
+  if (GET_CODE (pattern) == COND_EXEC)
+    pattern = COND_EXEC_CODE (pattern);
+
+  if (GET_CODE (pattern) == SET)
     {
       rtx dest = SET_DEST (PATTERN (insn));
  
@@ -1259,13 +1282,16 @@ dead_or_set_regno_p (insn, test_regno)
 
       return (test_regno >= regno && test_regno < endregno);
     }
-  else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+  else if (GET_CODE (pattern) == PARALLEL)
     {
       register int i;
 
-      for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+      for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
        {
-         rtx body = XVECEXP (PATTERN (insn), 0, i);
+         rtx body = XVECEXP (pattern, 0, i);
+
+         if (GET_CODE (body) == COND_EXEC)
+           body = COND_EXEC_CODE (body);
 
          if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
            {
index dac8911..7d9610c 100644 (file)
@@ -7942,4 +7942,12 @@ Note that this functionality is part of POSIX.
 Defining @code{TARGET_HAS_F_SETLKW} will enable the test coverage code
 to use file locking when exiting a program, which avoids race conditions
 if the program has forked.
+
+@findex MAX_CONDITIONAL_EXECUTE
+@item MAX_CONDITIONAL_EXECUTE
+
+A C expression for the maximum number of instructions to execute via
+conditional execution instructions instead of a branch.  A value of
+@code{BRANCH_COST}+1 is the default if the machine does not use cc0, and
+1 if it does use cc0.
 @end table