re PR rtl-optimization/8423 (CSE1 not propagating __builtin_constant_p enough)
authorRoger Sayle <roger@eyesopen.com>
Thu, 23 Jan 2003 02:57:26 +0000 (02:57 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Thu, 23 Jan 2003 02:57:26 +0000 (02:57 +0000)
PR optimization/8423
* cse.c (fold_rtx): Only eliminate a CONSTANT_P_RTX to 1 when
its argument is constant, or 0 if !flag_gcse.
* simplify-rtx.c (simplify_rtx): Convert CONSTANT_P_RTX to 1
if it's argument is constant.
* gcse.c (want_to_gcse_p): Ignore CONSTANT_P_RTX nodes.
(hash_scan_set): Don't record CONSTANT_P_RTX expressions.
(do_local_cprop): Don't propagate CONSTANT_P_RTX constants.
* builtins.c (purge_builtin_constant_p): New function to force
instantiation of any remaining CONSTANT_P_RTX nodes.
* rtl.h (purge_builtin_constant_p): Prototype here.
* toplev.c (rest_of_compilation): Invoke purge_builtin_constant_p
pass after GCSE and before loop.
(flag_gcse): No longer static.
* flags.h (flag_gcse): Prototype here.

From-SVN: r61642

gcc/ChangeLog
gcc/builtins.c
gcc/cse.c
gcc/flags.h
gcc/gcse.c
gcc/rtl.h
gcc/simplify-rtx.c
gcc/toplev.c

index dc6c69b..e5830c9 100644 (file)
@@ -1,3 +1,21 @@
+2003-01-22  Roger Sayle  <roger@eyesopen.com>
+
+       PR optimization/8423
+       * cse.c (fold_rtx): Only eliminate a CONSTANT_P_RTX to 1 when
+       its argument is constant, or 0 if !flag_gcse.
+       * simplify-rtx.c (simplify_rtx): Convert CONSTANT_P_RTX to 1
+       if it's argument is constant.
+       * gcse.c (want_to_gcse_p): Ignore CONSTANT_P_RTX nodes.
+       (hash_scan_set): Don't record CONSTANT_P_RTX expressions.
+       (do_local_cprop): Don't propagate CONSTANT_P_RTX constants.
+       * builtins.c (purge_builtin_constant_p): New function to force
+       instantiation of any remaining CONSTANT_P_RTX nodes.
+       * rtl.h (purge_builtin_constant_p): Prototype here.
+       * toplev.c (rest_of_compilation): Invoke purge_builtin_constant_p
+       pass after GCSE and before loop.
+       (flag_gcse): No longer static.
+       * flags.h (flag_gcse): Prototype here.
+
 2003-01-22  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * config/s390/s390.h (HARD_REGNO_MODE_OK): Fix warning regression
index ffa09f9..5e72df6 100644 (file)
@@ -1461,8 +1461,8 @@ expand_builtin_constant_p (exp)
   arglist = TREE_VALUE (arglist);
 
   /* We have taken care of the easy cases during constant folding.  This
-     case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
-     chance to see if it can deduce whether ARGLIST is constant.  */
+     case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
+     get a chance to see if it can deduce whether ARGLIST is constant.  */
 
   tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
   tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
@@ -4496,3 +4496,32 @@ default_expand_builtin (exp, target, subtarget, mode, ignore)
 {
   return NULL_RTX;
 }
+
+/* Instantiate all remaining CONSTANT_P_RTX nodes.  */
+
+void
+purge_builtin_constant_p ()
+{
+  rtx insn, done, set;
+  rtx arg, new, note;
+  basic_block bb;
+
+  FOR_EACH_BB (bb)
+    {
+      done = NEXT_INSN (bb->end);
+      for (insn = bb->head; insn != done; insn = NEXT_INSN (insn))
+       if (INSN_P (insn)
+           && (set = single_set (insn)) != NULL_RTX
+           && GET_CODE (SET_SRC (set)) == CONSTANT_P_RTX)
+         {
+           arg = XEXP (SET_SRC (set), 0);
+           new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
+           validate_change (insn, &SET_SRC (set), new, 0);
+
+           /* Remove the REG_EQUAL note from the insn.  */
+           if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
+             remove_note (insn, note);
+         }
+    }
+}
+
index 1a4ca2e..8f9ac33 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1,6 +1,6 @@
 /* Common subexpression elimination for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -4332,9 +4332,14 @@ fold_rtx (x, insn)
       break;
 
     case 'x':
-      /* Always eliminate CONSTANT_P_RTX at this stage.  */
+      /* Eliminate CONSTANT_P_RTX if its constant.  */
       if (code == CONSTANT_P_RTX)
-       return (const_arg0 ? const1_rtx : const0_rtx);
+       {
+         if (const_arg0)
+           return const1_rtx;
+         if (!flag_gcse)
+           return const0_rtx;
+       }
       break;
     }
 
index e7923e8..7ba3f75 100644 (file)
@@ -633,6 +633,10 @@ extern enum graph_dump_types graph_dump_format;
 
 extern int flag_no_ident;
 
+/* Nonzero means perform global CSE.  */
+
+extern int flag_gcse;
+
 /* Nonzero if we want to perform enhanced load motion during gcse.  */
 
 extern int flag_gcse_lm;
index 3fdf47e..2171994 100644 (file)
@@ -1305,6 +1305,7 @@ want_to_gcse_p (x)
     case CONST_DOUBLE:
     case CONST_VECTOR:
     case CALL:
+    case CONSTANT_P_RTX:
       return 0;
 
     default:
@@ -2216,7 +2217,8 @@ hash_scan_set (pat, insn, table)
                    && REGNO (src) >= FIRST_PSEUDO_REGISTER
                    && can_copy_p [GET_MODE (dest)]
                    && REGNO (src) != regno)
-                  || CONSTANT_P (src))
+                  || (CONSTANT_P (src)
+                      && GET_CODE (src) != CONSTANT_P_RTX))
               /* A copy is not available if its src or dest is subsequently
                  modified.  Here we want to search from INSN+1 on, but
                  oprs_available_p searches from INSN on.  */
@@ -4277,7 +4279,8 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
          if (l->in_libcall)
            continue;
 
-         if (CONSTANT_P (this_rtx))
+         if (CONSTANT_P (this_rtx)
+             && GET_CODE (this_rtx) != CONSTANT_P_RTX)
            newcnst = this_rtx;
          if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER
              /* Don't copy propagate if it has attached REG_EQUIV note.
index 2066b77..ec44830 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1346,6 +1346,7 @@ extern int ceil_log2                      PARAMS ((unsigned HOST_WIDE_INT));
 
 /* In builtins.c */
 extern rtx expand_builtin_expect_jump  PARAMS ((tree, rtx, rtx));
+extern void purge_builtin_constant_p   PARAMS ((void));
 
 /* In explow.c */
 extern void set_stack_check_libfunc PARAMS ((rtx));
index 1949f24..b0ddb65 100644 (file)
@@ -1,6 +1,6 @@
 /* RTL simplification functions for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -2729,11 +2729,15 @@ simplify_rtx (x)
                                             : GET_MODE (XEXP (x, 1))),
                                            XEXP (x, 0), XEXP (x, 1));
     case 'x':
-      /* The only case we try to handle is a SUBREG.  */
       if (code == SUBREG)
        return simplify_gen_subreg (mode, SUBREG_REG (x),
                                    GET_MODE (SUBREG_REG (x)),
                                    SUBREG_BYTE (x));
+      if (code == CONSTANT_P_RTX)
+       {
+         if (CONSTANT_P (XEXP (x,0)))
+           return const1_rtx;
+       }
       return NULL;
     default:
       return NULL;
index 80ddd8e..b24da96 100644 (file)
@@ -621,10 +621,6 @@ int flag_volatile_static;
 
 int flag_syntax_only = 0;
 
-/* Nonzero means perform global cse.  */
-
-static int flag_gcse;
-
 /* Nonzero means perform loop optimizer.  */
 
 static int flag_loop_optimize;
@@ -646,6 +642,10 @@ static int flag_if_conversion2;
 
 static int flag_delete_null_pointer_checks;
 
+/* Nonzero means perform global CSE.  */
+
+int flag_gcse = 0;
+
 /* Nonzero means to do the enhanced load motion during gcse, which trys
    to hoist loads by not killing them when a store to the same location
    is seen.  */
@@ -2921,6 +2921,9 @@ rest_of_compilation (decl)
 #endif
     }
 
+  /* Instantiate any remaining CONSTANT_P_RTX nodes.  */
+  purge_builtin_constant_p ();
+
   /* Move constant computations out of loops.  */
 
   if (optimize > 0 && flag_loop_optimize)