OSDN Git Service

PR target/39139
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Feb 2009 16:22:29 +0000 (16:22 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Feb 2009 16:22:29 +0000 (16:22 +0000)
* function.h (struct function): Add has_local_explicit_reg_vars
bit.
* gimplify.c (gimplify_bind_expr): Set it if local DECL_HARD_REGISTER
VAR_DECLs were seen.
* tree-ssa-live.c (remove_unused_locals): Recompute
cfun->has_local_explicit_reg_vars.
* tree-ssa-sink.c (statement_sink_location): Don't sink BLKmode
copies or clearings if cfun->has_local_explicit_reg_vars.

* gcc.target/i386/pr39139.c: New test.

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

gcc/ChangeLog
gcc/function.h
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr39139.c [new file with mode: 0644]
gcc/tree-ssa-live.c
gcc/tree-ssa-sink.c

index c85a256..c5e00ed 100644 (file)
@@ -1,3 +1,15 @@
+2009-02-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/39139
+       * function.h (struct function): Add has_local_explicit_reg_vars
+       bit.
+       * gimplify.c (gimplify_bind_expr): Set it if local DECL_HARD_REGISTER
+       VAR_DECLs were seen.
+       * tree-ssa-live.c (remove_unused_locals): Recompute
+       cfun->has_local_explicit_reg_vars.
+       * tree-ssa-sink.c (statement_sink_location): Don't sink BLKmode
+       copies or clearings if cfun->has_local_explicit_reg_vars.
+
 2009-02-10  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/39118
 2009-02-10  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/39118
index f78d737..3f03727 100644 (file)
@@ -1,6 +1,6 @@
 /* Structure for saving state for a nested function.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
 /* Structure for saving state for a nested function.
    Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008
+   1999, 2000, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
 
 This file is part of GCC.
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -596,6 +596,10 @@ struct function GTY(())
 
   /* Nonzero if pass_tree_profile was run on this function.  */
   unsigned int after_tree_profile : 1;
 
   /* Nonzero if pass_tree_profile was run on this function.  */
   unsigned int after_tree_profile : 1;
+
+  /* Nonzero if this function has local DECL_HARD_REGISTER variables.
+     In this case code motion has to be done more carefully.  */
+  unsigned int has_local_explicit_reg_vars : 1;
 };
 
 /* If va_list_[gf]pr_size is set to this, it means we don't know how
 };
 
 /* If va_list_[gf]pr_size is set to this, it means we don't know how
index 6f88ec5..4af5029 100644 (file)
@@ -1,6 +1,6 @@
 /* Tree lowering pass.  This pass converts the GENERIC functions-as-trees
    tree representation into the GIMPLE form.
 /* Tree lowering pass.  This pass converts the GENERIC functions-as-trees
    tree representation into the GIMPLE form.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Major work done by Sebastian Pop <s.pop@laposte.net>,
    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
    Free Software Foundation, Inc.
    Major work done by Sebastian Pop <s.pop@laposte.net>,
    Diego Novillo <dnovillo@redhat.com> and Jason Merrill <jason@redhat.com>.
@@ -1240,6 +1240,9 @@ gimplify_bind_expr (tree *expr_p, gimple_seq *pre_p)
            omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN);
 
          DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
            omp_add_variable (gimplify_omp_ctxp, t, GOVD_LOCAL | GOVD_SEEN);
 
          DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
+
+         if (DECL_HARD_REGISTER (t) && !is_global_var (t) && cfun)
+           cfun->has_local_explicit_reg_vars = true;
        }
 
       /* Preliminarily mark non-addressed complex variables as eligible
        }
 
       /* Preliminarily mark non-addressed complex variables as eligible
index 02a65b9..e5d166e 100644 (file)
@@ -1,3 +1,8 @@
+2009-02-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/39139
+       * gcc.target/i386/pr39139.c: New test.
+
 2009-02-10  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/39132
 2009-02-10  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/39132
diff --git a/gcc/testsuite/gcc.target/i386/pr39139.c b/gcc/testsuite/gcc.target/i386/pr39139.c
new file mode 100644 (file)
index 0000000..95ea7fd
--- /dev/null
@@ -0,0 +1,39 @@
+/* PR target/39139 */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+#ifdef __x86_64__
+# define AX_REG asm ("rax")
+# define DI_REG asm ("rdi")
+# define SI_REG asm ("rsi")
+#else
+# define AX_REG asm ("eax")
+# define DI_REG asm ("edi")
+# define SI_REG asm ("esi")
+#endif
+
+static inline int
+foo (unsigned int x, void *y)
+{
+  register unsigned long r AX_REG;
+  register unsigned long a1 DI_REG;
+  register unsigned long a2 SI_REG;
+  a1 = (unsigned long) x;
+  a2 = (unsigned long) y;
+  asm volatile ("" : "=r" (r), "+r" (a1), "+r" (a2) : : "memory");
+  return (int) r;
+}
+
+struct T { unsigned long t1, t2; unsigned int t3, t4, t5; };
+
+int
+bar (unsigned long x, unsigned int y, unsigned long u, unsigned int v)
+{
+  long r;
+  struct T e = { .t1 = x, .t2 = u };
+
+  if (x << y != u << v)
+    return 5;
+  r = foo (11, &e);
+  return e.t3 == x;
+}
index 4731518..8ebf30e 100644 (file)
@@ -1,5 +1,5 @@
 /* Liveness for SSA trees.
 /* Liveness for SSA trees.
-   Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation,
+   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
    Inc.
    Contributed by Andrew MacLeod <amacleod@redhat.com>
 
    Inc.
    Contributed by Andrew MacLeod <amacleod@redhat.com>
 
@@ -642,6 +642,8 @@ remove_unused_locals (void)
          TREE_USED (e->goto_block) = true;
     }
 
          TREE_USED (e->goto_block) = true;
     }
 
+  cfun->has_local_explicit_reg_vars = false;
+
   /* Remove unmarked local vars from local_decls.  */
   for (cell = &cfun->local_decls; *cell; )
     {
   /* Remove unmarked local vars from local_decls.  */
   for (cell = &cfun->local_decls; *cell; )
     {
@@ -663,6 +665,10 @@ remove_unused_locals (void)
              continue;
            }
        }
              continue;
            }
        }
+      else if (TREE_CODE (var) == VAR_DECL
+              && DECL_HARD_REGISTER (var)
+              && !is_global_var (var))
+       cfun->has_local_explicit_reg_vars = true;
       cell = &TREE_CHAIN (*cell);
     }
 
       cell = &TREE_CHAIN (*cell);
     }
 
index e56cce0..82a027d 100644 (file)
@@ -1,5 +1,6 @@
 /* Code sinking for trees
 /* Code sinking for trees
-   Copyright (C) 2001, 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2007, 2009
+   Free Software Foundation, Inc.
    Contributed by Daniel Berlin <dan@dberlin.org>
 
 This file is part of GCC.
    Contributed by Daniel Berlin <dan@dberlin.org>
 
 This file is part of GCC.
@@ -301,7 +302,12 @@ statement_sink_location (gimple stmt, basic_block frombb,
      We can't sink statements that have volatile operands.  
 
      We don't want to sink dead code, so anything with 0 immediate uses is not
      We can't sink statements that have volatile operands.  
 
      We don't want to sink dead code, so anything with 0 immediate uses is not
-     sunk.  
+     sunk.
+
+     Don't sink BLKmode assignments if current function has any local explicit
+     register variables, as BLKmode assignments may involve memcpy or memset
+     calls or, on some targets, inline expansion thereof that sometimes need
+     to use specific hard registers.
 
   */
   code = gimple_assign_rhs_code (stmt);
 
   */
   code = gimple_assign_rhs_code (stmt);
@@ -311,7 +317,9 @@ statement_sink_location (gimple stmt, basic_block frombb,
       || code == FILTER_EXPR
       || is_hidden_global_store (stmt)
       || gimple_has_volatile_ops (stmt)
       || code == FILTER_EXPR
       || is_hidden_global_store (stmt)
       || gimple_has_volatile_ops (stmt)
-      || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
+      || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE)
+      || (cfun->has_local_explicit_reg_vars
+         && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode))
     return false;
   
   FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
     return false;
   
   FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)