tree-flow.h (addressable_vars): Declare.
authorDiego Novillo <dnovillo@redhat.com>
Thu, 8 Jul 2004 06:34:23 +0000 (06:34 +0000)
committerDiego Novillo <dnovillo@gcc.gnu.org>
Thu, 8 Jul 2004 06:34:23 +0000 (02:34 -0400)
* tree-flow.h (addressable_vars): Declare.
* tree-ssa-alias.c (addressable_vars): Define.
(setup_pointers_and_addressables): Add addressable variables
to addressable_vars.
* tree-ssa-operands.c (get_stmt_operands): Move
handling of ASM_EXPRs ...
(get_asm_expr_operands): ... here.
When the ASM_EXPR clobbers memory, also clobber addressable
variables.
* tree-ssa.c (init_tree_ssa): Initialize addressable_vars.
(delete_tree_ssa): Reset addressable_vars.

From-SVN: r84272

gcc/ChangeLog
gcc/tree-flow.h
gcc/tree-ssa-alias.c
gcc/tree-ssa-operands.c
gcc/tree-ssa.c

index 66b707546d79dbbbcac077763f9480c3b4f498b8..8e5f51936e9b48682e77bc73ff16b923138711e2 100644 (file)
@@ -1,3 +1,17 @@
+2004-07-08  Diego Novillo  <dnovillo@redhat.com>
+
+       * tree-flow.h (addressable_vars): Declare.
+       * tree-ssa-alias.c (addressable_vars): Define.
+       (setup_pointers_and_addressables): Add addressable variables
+       to addressable_vars.
+       * tree-ssa-operands.c (get_stmt_operands): Move
+       handling of ASM_EXPRs ...
+       (get_asm_expr_operands): ... here.
+       When the ASM_EXPR clobbers memory, also clobber addressable
+       variables.
+       * tree-ssa.c (init_tree_ssa): Initialize addressable_vars.
+       (delete_tree_ssa): Reset addressable_vars.
+
 2004-07-07  Jan Beulich  <jbeulich@novell.com>
            Richard Henderson  <rth@redhat.com>
 
index dc4ddb2d7a4fc7367b9a5886b89ffd4291d0facc..f9f8115328c854b8168dc5881c198935b793f9a4 100644 (file)
@@ -395,6 +395,10 @@ extern GTY(()) tree global_var;
    REFERENCED_VARS (I) is call-clobbered.  */
 extern bitmap call_clobbered_vars;
 
+/* Addressable variables in the function.  If bit I is set, then
+   REFERENCED_VARS (I) has had its address taken.  */
+extern bitmap addressable_vars;
+
 /* 'true' after aliases have been computed (see compute_may_aliases).  */
 extern bool aliases_computed_p;
 
index 75c98e12d3d7a7f500187c81b8ebb7c013aa2348..3cf27ae6a6b8373e59735ed919358f82c6cd0d3c 100644 (file)
@@ -163,6 +163,10 @@ static struct ptr_info_def *get_ptr_info (tree t);
    REFERENCED_VARS (I) is call-clobbered.  */
 bitmap call_clobbered_vars;
 
+/* Addressable variables in the function.  If bit I is set, then
+   REFERENCED_VARS (I) has had its address taken.  */
+bitmap addressable_vars;
+
 /* 'true' after aliases have been computed (see compute_may_aliases).  This
    is used by get_stmt_operands and its helpers to determine what to do
    when scanning an operand for a variable that may be aliased.  If
@@ -1196,6 +1200,14 @@ setup_pointers_and_addressables (struct alias_info *ai)
                 to rename VAR into SSA afterwards.  */
              bitmap_set_bit (vars_to_rename, v_ann->uid);
            }
+         else
+           {
+             /* Add the variable to the set of addressables.  Mostly
+                used when scanning operands for ASM_EXPRs that
+                clobber memory.  In those cases, we need to clobber
+                all call-clobbered variables and all addressables.  */
+             bitmap_set_bit (addressable_vars, v_ann->uid);
+           }
        }
 
       /* Global variables and addressable locals may be aliased.  Create an
index c44189f0a9fc7820be3f87a125adf1d1e9bda759..46f9f59ac0458068ca6cf9ece33382d2599f0ce5 100644 (file)
@@ -80,6 +80,7 @@ typedef struct voperands_d
 
 static void note_addressable (tree, stmt_ann_t);
 static void get_expr_operands (tree, tree *, int, voperands_t);
+static void get_asm_expr_operands (tree, voperands_t);
 static inline void append_def (tree *, tree);
 static inline void append_use (tree *, tree);
 static void append_v_may_def (tree, tree, voperands_t);
@@ -777,59 +778,7 @@ get_stmt_operands (tree stmt)
       break;
 
     case ASM_EXPR:
-      {
-       int noutputs = list_length (ASM_OUTPUTS (stmt));
-       const char **oconstraints
-         = (const char **) alloca ((noutputs) * sizeof (const char *));
-       int i;
-       tree link;
-       const char *constraint;
-       bool allows_mem, allows_reg, is_inout;
-
-       for (i=0, link = ASM_OUTPUTS (stmt); link;
-            ++i, link = TREE_CHAIN (link))
-         {
-           oconstraints[i] = constraint
-             = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
-           parse_output_constraint (&constraint, i, 0, 0,
-                                    &allows_mem, &allows_reg, &is_inout);
-           if (allows_reg && is_inout)
-             /* This should have been split in gimplify_asm_expr.  */
-             abort ();
-
-           if (!allows_reg && allows_mem)
-             {
-               tree t = get_base_address (TREE_VALUE (link));
-               if (t && DECL_P (t))
-                 mark_call_clobbered (t);
-             }
-
-           get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def,
-                              &prev_vops);
-         }
-
-       for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
-         {
-           constraint
-             = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
-           parse_input_constraint (&constraint, 0, 0, noutputs, 0,
-                                   oconstraints, &allows_mem, &allows_reg);
-
-           if (!allows_reg && allows_mem)
-             {
-               tree t = get_base_address (TREE_VALUE (link));
-               if (t && DECL_P (t))
-                 mark_call_clobbered (t);
-             }
-
-           get_expr_operands (stmt, &TREE_VALUE (link), 0, &prev_vops);
-         }
-
-       /* Clobber memory for asm ("" : : : "memory");  */
-       for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
-         if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory"))
-           add_call_clobber_ops (stmt, &prev_vops);
-      }
+      get_asm_expr_operands (stmt, &prev_vops);
       break;
 
     case RETURN_EXPR:
@@ -1215,6 +1164,108 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
   abort ();
 }
 
+/* Scan operands in ASM_EXPR STMT.  PREV_VOPS is as in
+   append_v_may_def and append_vuse.  */
+
+static void
+get_asm_expr_operands (tree stmt, voperands_t prev_vops)
+{
+  int noutputs = list_length (ASM_OUTPUTS (stmt));
+  const char **oconstraints
+    = (const char **) alloca ((noutputs) * sizeof (const char *));
+  int i;
+  tree link;
+  const char *constraint;
+  bool allows_mem, allows_reg, is_inout;
+  stmt_ann_t s_ann = stmt_ann (stmt);
+
+  for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link))
+    {
+      oconstraints[i] = constraint
+       = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+      parse_output_constraint (&constraint, i, 0, 0,
+         &allows_mem, &allows_reg, &is_inout);
+
+#if defined ENABLE_CHECKING
+      /* This should have been split in gimplify_asm_expr.  */
+      if (allows_reg && is_inout)
+       abort ();
+#endif
+
+      /* Memory operands are addressable.  Note that STMT needs the
+        address of this operand.  */
+      if (!allows_reg && allows_mem)
+       {
+         tree t = get_base_address (TREE_VALUE (link));
+         if (t && DECL_P (t))
+           note_addressable (t, s_ann);
+       }
+
+      get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def, prev_vops);
+    }
+
+  for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
+    {
+      constraint
+       = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
+      parse_input_constraint (&constraint, 0, 0, noutputs, 0,
+         oconstraints, &allows_mem, &allows_reg);
+
+      /* Memory operands are addressable.  Note that STMT needs the
+        address of this operand.  */
+      if (!allows_reg && allows_mem)
+       {
+         tree t = get_base_address (TREE_VALUE (link));
+         if (t && DECL_P (t))
+           note_addressable (t, s_ann);
+       }
+
+      get_expr_operands (stmt, &TREE_VALUE (link), 0, prev_vops);
+    }
+
+  /* Clobber memory for asm ("" : : : "memory");  */
+  if (!aliases_computed_p)
+    {
+      /* If we still have not computed aliasing information,
+        mark the statement as having volatile operands to avoid
+        optimizations from messing around with it.  */
+      stmt_ann (stmt)->has_volatile_ops = true;
+    }
+  else
+    {
+      /* Otherwise, if this ASM_EXPR clobbers memory, clobber
+        all the call-clobbered variables and the addressable
+        variables found by the alias analyzer.  */
+      for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link))
+       if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory"))
+         {
+           /* If we had created .GLOBAL_VAR earlier, use it.
+              Otherwise, add a V_MAY_DEF operand for every
+              call-clobbered and addressable variable.  See
+              compute_may_aliases for the heuristic used to decide
+              whether to create .GLOBAL_VAR or not.  */
+           if (global_var)
+             add_stmt_operand (&global_var, stmt, opf_is_def, prev_vops);
+           else
+             {
+               size_t i;
+
+               EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i,
+                   {
+                     tree var = referenced_var (i);
+                     add_stmt_operand (&var, stmt, opf_is_def, prev_vops);
+                   });
+
+               EXECUTE_IF_SET_IN_BITMAP (addressable_vars, 0, i,
+                   {
+                     tree var = referenced_var (i);
+                     add_stmt_operand (&var, stmt, opf_is_def, prev_vops);
+                   });
+             }
+         }
+    }
+}
+
 
 /* Add *VAR_P to the appropriate operand array of STMT.  FLAGS is as in
    get_expr_operands.  If *VAR_P is a GIMPLE register, it will be added to
index 4cdfd3ddf22902002a76d44313d16d99dc540dac..3ab7ac206bbf9cba7dfda1120f69f281c73a870f 100644 (file)
@@ -494,6 +494,7 @@ init_tree_ssa (void)
 {
   VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
   call_clobbered_vars = BITMAP_XMALLOC ();
+  addressable_vars = BITMAP_XMALLOC ();
   init_ssa_operands ();
   init_ssanames ();
   init_phinodes ();
@@ -532,6 +533,8 @@ delete_tree_ssa (void)
   BITMAP_XFREE (call_clobbered_vars);
   call_clobbered_vars = NULL;
   aliases_computed_p = false;
+  BITMAP_XFREE (addressable_vars);
+  addressable_vars = NULL;
 }