OSDN Git Service

2011-12-22 Bin Cheng <bin.cheng@arm.com>
authorjye2 <jye2@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Dec 2011 05:43:09 +0000 (05:43 +0000)
committerjye2 <jye2@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Dec 2011 05:43:09 +0000 (05:43 +0000)
Richard Guenther  <rguenther@suse.de>

PR tree-optimization/43491
* tree-ssa-pre.c (eliminate): Don't replace global register
variable when it is the RHS of a single assign.

testsuite:
* gcc.dg/tree-ssa/pr43491.c: New test.

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr43491.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index 8b6fc68..d739d2e 100644 (file)
@@ -1,3 +1,10 @@
+2011-12-22  Bin Cheng  <bin.cheng@arm.com>
+       Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/43491
+       * tree-ssa-pre.c (eliminate): Don't replace global register
+       variable when it is the RHS of a single assign.
+
 2011-12-22  Joey Ye  <joey.ye@arm.com>
 
        * toplev.c (process_options): Fix typo.
index 540d28b..0594a96 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-22  Bin Cheng  <bin.cheng@arm.com>
+
+       PR tree-optimization/43491
+       * gcc.dg/tree-ssa/pr43491.c: New test.
+
 2011-12-22  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR testsuite/50722
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr43491.c b/gcc/testsuite/gcc.dg/tree-ssa/pr43491.c
new file mode 100644 (file)
index 0000000..2473400
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+
+#define REGISTER register
+
+#if defined __arm__
+# define REG1 asm("r4")
+#elif defined __i386__
+# define REG1 asm("ebx")
+#elif defined __mips__
+# define REG1 asm("s0")
+#elif defined __x86_64__
+# define REG1 asm("rbp")
+#else
+# undef REGISTER
+# define REGISTER
+# define REG1
+#endif
+
+REGISTER long data_0 REG1;
+long data_3; 
+
+long foo(long data, long v)
+{
+       long i;
+       long t, u;
+
+       if (data)
+               i = data_0 + data_3;
+       else {
+               v = 2;
+               i = 5;
+       }
+       t = data_0 + data_3;
+       u = i;
+       return v * t * u;
+}
+/* We should not eliminate global register variable when it is the RHS of
+   a single assignment.  */
+/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre" { target { arm-*-* i?86-*-* mips*-*-* x86_64-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "pre" { target { ! { arm-*-* i?86-*-* mips*-*-* x86_64-*-* } } } } } */
+/* { dg-final { cleanup-tree-dump "pre" } } */
index 557b56a..6e86024 100644 (file)
@@ -4161,28 +4161,40 @@ eliminate (void)
     {
       for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi))
        {
+         tree lhs = NULL_TREE;
+         tree rhs = NULL_TREE;
+
          stmt = gsi_stmt (gsi);
 
+         if (gimple_has_lhs (stmt))
+           lhs = gimple_get_lhs (stmt);
+
+         if (gimple_assign_single_p (stmt))
+           rhs = gimple_assign_rhs1 (stmt);
+
          /* Lookup the RHS of the expression, see if we have an
             available computation for it.  If so, replace the RHS with
-            the available computation.  */
+            the available computation.
+
+            See PR43491.
+            We don't replace global register variable when it is a the RHS of
+            a single assign. We do replace local register variable since gcc
+            does not guarantee local variable will be allocated in register.  */
          if (gimple_has_lhs (stmt)
-             && TREE_CODE (gimple_get_lhs (stmt)) == SSA_NAME
+             && TREE_CODE (lhs) == SSA_NAME
              && !gimple_assign_ssa_name_copy_p (stmt)
              && (!gimple_assign_single_p (stmt)
-                 || !is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+                 || (!is_gimple_min_invariant (rhs)
+                      && (gimple_assign_rhs_code (stmt) != VAR_DECL
+                          || !is_global_var (rhs)
+                          || !DECL_HARD_REGISTER (rhs))))
              && !gimple_has_volatile_ops  (stmt)
-             && !has_zero_uses (gimple_get_lhs (stmt)))
+             && !has_zero_uses (lhs))
            {
-             tree lhs = gimple_get_lhs (stmt);
-             tree rhs = NULL_TREE;
              tree sprime = NULL;
              pre_expr lhsexpr = get_or_alloc_expr_for_name (lhs);
              pre_expr sprimeexpr;
 
-             if (gimple_assign_single_p (stmt))
-               rhs = gimple_assign_rhs1 (stmt);
-
              sprimeexpr = bitmap_find_leader (AVAIL_OUT (b),
                                               get_expr_value_id (lhsexpr),
                                               NULL);
@@ -4298,10 +4310,9 @@ eliminate (void)
             dead.  */
          else if (gimple_assign_single_p (stmt)
                   && !is_gimple_reg (gimple_assign_lhs (stmt))
-                  && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
-                      || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
+                  && (TREE_CODE (rhs) == SSA_NAME
+                      || is_gimple_min_invariant (rhs)))
            {
-             tree rhs = gimple_assign_rhs1 (stmt);
              tree val;
              val = vn_reference_lookup (gimple_assign_lhs (stmt),
                                         gimple_vuse (stmt), VN_WALK, NULL);