tree-dfa.c (add_referenced_var): Only global variables are call-clobbered.
authorDiego Novillo <dnovillo@redhat.com>
Wed, 18 Aug 2004 18:21:23 +0000 (18:21 +0000)
committerDiego Novillo <dnovillo@gcc.gnu.org>
Wed, 18 Aug 2004 18:21:23 +0000 (14:21 -0400)
* tree-dfa.c (add_referenced_var): Only global variables are
call-clobbered.
* tree-flow.h (struct ptr_info_def): Add field pt_global_mem.
* tree-ssa-alias.c (compute_points_to_and_addr_escape): Mark
all pointers dereferenced if the statement dereferences them.
(create_name_tags): Do not create memory tags for pointers
that have PT_ANYTHING set.
Also check if PT_VARS is not empty before creating a name tag.
(compute_flow_sensitive_aliasing): Don't mark call-clobbered
variables that share the same alias set with a pointer that
may point anywhere.
(add_may_alias): Add FIXME comment to remove clobbering
aliased variables and tags.
(replace_may_alias): Likewise.
(set_pt_anything): Do not clear PT_VARS nor IS_DEREFERENCED.
(merge_pointed_to_info): If the original variable has not
points-to information, call set_pt_anything.
(add_pointed_to_var): Do not prevent adding a pointed-to
variable if the pointers is PT_ANYTHING.
If the variable is a global, set PT_GLOBAL_MEM.
(collect_points_to_info_r): Don't assume that PLUS_EXPRs of
pointer type only come in PTR+OFFSET flavours.
Always call merge_pointed_to_info on PHI arguments that are
SSA_NAMEs.
(get_nmt_for): Mark call-clobbered tags whose pointer points
to global memory.
* tree-ssa-operands.c (opf_kill_def, opf_no_vops): Switch
values.
(get_indirect_ref_operands): Always clear OPF_KILL_DEF from
FLAGS.
(add_stmt_operand): Abort if the caller tried to add a killing
definition for a memory tag.
* tree-ssa.c (verify_flow_sensitive_alias_info): Remove
unnecessary checks.

From-SVN: r86198

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

index 6dc33062d4a32d0e30fea1c3aa405ebd2264a26d..d4e6bc38b7ce7f640535bedc5cdd5eb0deedb951 100644 (file)
@@ -1,3 +1,40 @@
+2004-08-18  Diego Novillo  <dnovillo@redhat.com>
+
+       * tree-dfa.c (add_referenced_var): Only global variables are
+       call-clobbered.
+       * tree-flow.h (struct ptr_info_def): Add field pt_global_mem.
+       * tree-ssa-alias.c (compute_points_to_and_addr_escape): Mark
+       all pointers dereferenced if the statement dereferences them.
+       (create_name_tags): Do not create memory tags for pointers
+       that have PT_ANYTHING set.
+       Also check if PT_VARS is not empty before creating a name tag.
+       (compute_flow_sensitive_aliasing): Don't mark call-clobbered
+       variables that share the same alias set with a pointer that
+       may point anywhere.
+       (add_may_alias): Add FIXME comment to remove clobbering
+       aliased variables and tags.
+       (replace_may_alias): Likewise.
+       (set_pt_anything): Do not clear PT_VARS nor IS_DEREFERENCED.
+       (merge_pointed_to_info): If the original variable has not
+       points-to information, call set_pt_anything.
+       (add_pointed_to_var): Do not prevent adding a pointed-to
+       variable if the pointers is PT_ANYTHING.
+       If the variable is a global, set PT_GLOBAL_MEM.
+       (collect_points_to_info_r): Don't assume that PLUS_EXPRs of
+       pointer type only come in PTR+OFFSET flavours.
+       Always call merge_pointed_to_info on PHI arguments that are
+       SSA_NAMEs.
+       (get_nmt_for): Mark call-clobbered tags whose pointer points
+       to global memory.
+       * tree-ssa-operands.c (opf_kill_def, opf_no_vops): Switch
+       values.
+       (get_indirect_ref_operands): Always clear OPF_KILL_DEF from
+       FLAGS.
+       (add_stmt_operand): Abort if the caller tried to add a killing
+       definition for a memory tag.
+       * tree-ssa.c (verify_flow_sensitive_alias_info): Remove
+       unnecessary checks.
+
 2004-08-18  J"orn Rennecke <joern.rennecke@superh.com>
 
        * sh.h (CONDITIONAL_REGISTER_USAGE): Don't exclude fixed registers
index 0273406df844016110a1886be92ec0f161e018e4..b8a9b03324f7f0265124539a95a92357cbc34f9f 100644 (file)
@@ -903,10 +903,8 @@ add_referenced_var (tree var, struct walk_state *walk_state)
       v_ann->uid = num_referenced_vars;
       VARRAY_PUSH_TREE (referenced_vars, var);
 
-      /* Initially assume that all memory variables are
-        call-clobbered.  This will be refined later by the alias
-        analyzer.  */
-      if (needs_to_live_in_memory (var))
+      /* Global variables are always call-clobbered.  */
+      if (is_global_var (var))
        mark_call_clobbered (var);
 
       /* If an initialized global variable then register the initializer
index 0e60e411e2813fd2d8a48588c152ae5ec68951ad..ca5897afa49ae6a592add31a3e51aa5495003c59 100644 (file)
@@ -62,6 +62,9 @@ struct ptr_info_def GTY(())
   /* Nonzero if this pointer is dereferenced.  */
   unsigned int is_dereferenced : 1;
 
+  /* Nonzero if this pointer points to a global variable.  */
+  unsigned int pt_global_mem : 1;
+
   /* Set of variables that this pointer may point to.  */
   bitmap pt_vars;
 
index a344384b42656a247c1b210723397130f15e14b8..8cfc65ad35fc93ba804eb47f8f13e8951398fe0b 100644 (file)
@@ -653,16 +653,14 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
 
              collect_points_to_info_for (ai, op);
 
-             pi =  SSA_NAME_PTR_INFO (op);
+             pi = SSA_NAME_PTR_INFO (op);
              if (ptr_is_dereferenced_by (op, stmt, &is_store))
                {
-                 /* If we found OP to point to a set of variables or
-                    malloc, then mark it as being dereferenced.  In a
-                    subsequent pass, dereferenced pointers that point
-                    to a set of variables will be assigned a name tag
-                    to alias all the variables OP points to.  */
-                 if (pi->pt_malloc || pi->pt_vars)
-                   pi->is_dereferenced = 1;
+                 /* Mark OP as dereferenced.  In a subsequent pass,
+                    dereferenced pointers that point to a set of
+                    variables will be assigned a name tag to alias
+                    all the variables OP points to.  */
+                 pi->is_dereferenced = 1;
 
                  /* Keep track of how many time we've dereferenced each
                     pointer.  Again, we don't need to grow
@@ -762,15 +760,16 @@ create_name_tags (struct alias_info *ai)
       tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
 
-      if (!pi->is_dereferenced)
+      if (pi->pt_anything || !pi->is_dereferenced)
        {
          /* No name tags for pointers that have not been
-            dereferenced.  */
+            dereferenced or point to an arbitrary location.  */
          pi->name_mem_tag = NULL_TREE;
          continue;
        }
 
-      if (pi->pt_vars)
+      if (pi->pt_vars
+         && bitmap_first_set_bit (pi->pt_vars) >= 0)
        {
          size_t j;
          tree old_name_tag = pi->name_mem_tag;
@@ -859,38 +858,14 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
       if (pi->value_escapes_p || pi->pt_anything)
        {
          /* If PTR escapes or may point to anything, then its associated
-            memory tags are call-clobbered.  */
+            memory tags and pointed-to variables are call-clobbered.  */
          if (pi->name_mem_tag)
            mark_call_clobbered (pi->name_mem_tag);
 
          if (v_ann->type_mem_tag)
            mark_call_clobbered (v_ann->type_mem_tag);
 
-         /* If PTR may point to anything, mark call-clobbered all the
-            addressables with the same alias set as the type pointed-to by
-            PTR.  */
-         if (pi->pt_anything)
-           {
-             HOST_WIDE_INT ptr_set;
-             ptr_set = get_alias_set (TREE_TYPE (TREE_TYPE (ptr)));
-             for (j = 0; j < ai->num_addressable_vars; j++)
-               {
-                 struct alias_map_d *alias_map = ai->addressable_vars[j];
-                 if (alias_map->set == ptr_set)
-                   mark_call_clobbered (alias_map->var);
-               }
-           }
-
-         /* If PTR's value may escape and PTR is never dereferenced, we
-            need to mark all the variables PTR points-to as
-            call-clobbered.  Note that we only need do this it PTR is
-            never dereferenced.  If PTR is dereferenced, it will have a
-            name memory tag, which will have been marked call-clobbered.
-            This will in turn mark the pointed-to variables as
-            call-clobbered when we call add_may_alias below.  */
-         if (pi->value_escapes_p
-             && pi->name_mem_tag == NULL_TREE
-             && pi->pt_vars)
+         if (pi->pt_vars)
            EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j,
                mark_call_clobbered (referenced_var (j)));
        }
@@ -1684,7 +1659,9 @@ add_may_alias (tree var, tree alias)
     if (alias == VARRAY_TREE (v_ann->may_aliases, i))
       return;
 
-  /* If VAR is a call-clobbered variable, so is its new ALIAS.  */
+  /* If VAR is a call-clobbered variable, so is its new ALIAS.
+     FIXME, call-clobbering should only depend on whether an address
+     escapes.  It should be independent of aliasing.  */
   if (is_call_clobbered (var))
     mark_call_clobbered (alias);
 
@@ -1705,7 +1682,9 @@ replace_may_alias (tree var, size_t i, tree new_alias)
   var_ann_t v_ann = var_ann (var);
   VARRAY_TREE (v_ann->may_aliases, i) = new_alias;
 
-  /* If VAR is a call-clobbered variable, so is NEW_ALIAS.  */
+  /* If VAR is a call-clobbered variable, so is NEW_ALIAS.
+     FIXME, call-clobbering should only depend on whether an address
+     escapes.  It should be independent of aliasing.  */
   if (is_call_clobbered (var))
     mark_call_clobbered (new_alias);
 
@@ -1724,8 +1703,6 @@ set_pt_anything (tree ptr)
 
   pi->pt_anything = 1;
   pi->pt_malloc = 0;
-  pi->pt_vars = NULL;
-  pi->is_dereferenced = 0;
 
   /* The pointer used to have a name tag, but we now found it pointing
      to an arbitrary location.  The name tag needs to be renamed and
@@ -1812,6 +1789,8 @@ merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig)
                           orig_pi->pt_vars);
        }
     }
+  else
+    set_pt_anything (dest);
 }
 
 
@@ -1882,14 +1861,14 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value)
       uid = var_ann (pt_var)->uid;
       bitmap_set_bit (ai->addresses_needed, uid);
 
-      /* If PTR has already been found to point anywhere, don't
-        add the variable to PTR's points-to set.  */
-      if (!pi->pt_anything)
-       {
-         if (pi->pt_vars == NULL)
-           pi->pt_vars = BITMAP_GGC_ALLOC ();
-         bitmap_set_bit (pi->pt_vars, uid);
-       }
+      if (pi->pt_vars == NULL)
+       pi->pt_vars = BITMAP_GGC_ALLOC ();
+      bitmap_set_bit (pi->pt_vars, uid);
+
+      /* If the variable is a global, mark the pointer as pointing to
+        global memory (which will make its tag a global variable).  */
+      if (is_global_var (pt_var))
+       pi->pt_global_mem = 1;
     }
 }
 
@@ -1937,17 +1916,33 @@ collect_points_to_info_r (tree var, tree stmt, void *data)
          tree op0 = TREE_OPERAND (rhs, 0);
          tree op1 = TREE_OPERAND (rhs, 1);
 
-         if (TREE_CODE (op0) == SSA_NAME
-             && POINTER_TYPE_P (TREE_TYPE (op0)))
-           merge_pointed_to_info (ai, var, op0);
-         else if (TREE_CODE (op1) == SSA_NAME
-                  && POINTER_TYPE_P (TREE_TYPE (op1)))
-           merge_pointed_to_info (ai, var, op1);
-         else if (TREE_CODE (op0) == ADDR_EXPR)
-           add_pointed_to_var (ai, var, op0);
-         else if (TREE_CODE (op1) == ADDR_EXPR)
-           add_pointed_to_var (ai, var, op1);
-         else
+         /* Both operands may be of pointer type.  FIXME: Shouldn't
+            we just expect PTR + OFFSET always?  */
+         if (POINTER_TYPE_P (TREE_TYPE (op0)))
+           {
+             if (TREE_CODE (op0) == SSA_NAME)
+               merge_pointed_to_info (ai, var, op0);
+             else if (TREE_CODE (op0) == ADDR_EXPR)
+               add_pointed_to_var (ai, var, op0);
+             else
+               add_pointed_to_expr (var, op0);
+           }
+
+         if (POINTER_TYPE_P (TREE_TYPE (op1)))
+           {
+             if (TREE_CODE (op1) == SSA_NAME)
+               merge_pointed_to_info (ai, var, op1);
+             else if (TREE_CODE (op1) == ADDR_EXPR)
+               add_pointed_to_var (ai, var, op1);
+             else
+               add_pointed_to_expr (var, op1);
+           }
+
+         /* Neither operand is a pointer?  VAR can be pointing
+            anywhere.   FIXME: Is this right?  If we get here, we
+            found PTR = INT_CST + INT_CST.  */
+         if (!POINTER_TYPE_P (TREE_TYPE (op0))
+             && !POINTER_TYPE_P (TREE_TYPE (op1)))
            add_pointed_to_expr (var, rhs);
        }
 
@@ -1980,12 +1975,7 @@ collect_points_to_info_r (tree var, tree stmt, void *data)
       if (TREE_CODE (var) == ADDR_EXPR)
        add_pointed_to_var (ai, lhs, var);
       else if (TREE_CODE (var) == SSA_NAME)
-       {
-         if (bitmap_bit_p (ai->ssa_names_visited, SSA_NAME_VERSION (var)))
-           merge_pointed_to_info (ai, lhs, var);
-         else
-           set_pt_anything (lhs);
-       }
+       merge_pointed_to_info (ai, lhs, var);
       else if (is_gimple_min_invariant (var))
        add_pointed_to_expr (lhs, var);
       else
@@ -2106,13 +2096,11 @@ get_nmt_for (tree ptr)
   if (tag == NULL_TREE)
     tag = create_memory_tag (TREE_TYPE (TREE_TYPE (ptr)), false);
 
-  /* If PTR is a PARM_DECL, its memory tag should be considered a global
-     variable.  */
-  if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL)
-    mark_call_clobbered (tag);
-
-  /* Similarly, if PTR points to malloc, then TAG is a global.  */
-  if (pi->pt_malloc)
+  /* If PTR is a PARM_DECL, it points to a global variable or malloc,
+     then its name tag should be considered a global variable.  */
+  if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
+      || pi->pt_malloc
+      || pi->pt_global_mem)
     mark_call_clobbered (tag);
 
   return tag;
index 4b899eec5262d9fc01ce3c4b4649c92c396a9b15..230167f84e94f8476f97498f5047aa8c172a56b0 100644 (file)
@@ -89,7 +89,7 @@ Boston, MA 02111-1307, USA.  */
 #define opf_is_def     (1 << 0)
 
 /* Operand is the target of an assignment expression.  */
-#define opf_kill_def   (1 << 2)
+#define opf_kill_def   (1 << 1)
 
 /* No virtual operands should be created in the expression.  This is used
    when traversing ADDR_EXPR nodes which have different semantics than
@@ -97,7 +97,7 @@ Boston, MA 02111-1307, USA.  */
    need to consider are indices into arrays.  For instance, &a.b[i] should
    generate a USE of 'i' but it should not generate a VUSE for 'a' nor a
    VUSE for 'b'.  */
-#define opf_no_vops    (1 << 1)
+#define opf_no_vops    (1 << 2)
 
 /* Array for building all the def operands.  */
 static GTY (()) varray_type build_defs;
@@ -1273,6 +1273,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
   tree ptr = *pptr;
   stmt_ann_t ann = stmt_ann (stmt);
 
+  /* Stores into INDIRECT_REF operands are never killing definitions.  */
+  flags &= ~opf_kill_def;
 
   if (SSA_VAR_P (ptr))
     {
@@ -1456,20 +1458,31 @@ add_stmt_operand (tree *var_p, tree stmt, int flags)
            {
              if (v_ann->is_alias_tag)
                {
-                 /* Alias tagged vars get regular V_MAY_DEF  */
+                 /* Alias tagged vars get V_MAY_DEF to avoid breaking
+                    def-def chains with the other variables in their
+                    alias sets.  */
                  if (s_ann)
                    s_ann->makes_aliased_stores = 1;
                  append_v_may_def (var);
                }
-             else if ((flags & opf_kill_def) 
-                       && v_ann->mem_tag_kind == NOT_A_TAG)
-               /* V_MUST_DEF for non-aliased non-GIMPLE register 
-                  variable definitions. Avoid memory tags.  */
-               append_v_must_def (var);
+             else if (flags & opf_kill_def)
+               {
+#if defined ENABLE_CHECKING
+                 /* Only regular variables may get a V_MUST_DEF
+                    operand.  */
+                 if (v_ann->mem_tag_kind != NOT_A_TAG)
+                   abort ();
+#endif
+                 /* V_MUST_DEF for non-aliased, non-GIMPLE register 
+                   variable definitions.  */
+                 append_v_must_def (var);
+               }
              else
-               /* Call-clobbered variables & memory tags get 
-                  V_MAY_DEF  */
-               append_v_may_def (var);
+               {
+                 /* Add a V_MAY_DEF for call-clobbered variables and
+                    memory tags.  */
+                 append_v_may_def (var);
+               }
            }
          else
            {
@@ -1506,6 +1519,8 @@ add_stmt_operand (tree *var_p, tree stmt, int flags)
            }
          else
            {
+             /* Similarly, append a virtual uses for VAR itself, when
+                it is an alias tag.  */
              if (v_ann->is_alias_tag)
                append_vuse (var);
 
index eb6f9676617370d7ae1222f0c426b94d93dbda7b..743c08433668b130839f7af06c5a7e8dac08bad3 100644 (file)
@@ -433,18 +433,6 @@ verify_flow_sensitive_alias_info (void)
          goto err;
        }
 
-      if (pi->pt_anything && (pi->pt_malloc || pi->pt_vars))
-       {
-         error ("Pointers that point to anything should not point to malloc or other vars");
-         goto err;
-       }
-      
-      if (pi->pt_malloc && pi->pt_vars)
-       {
-         error ("Pointers pointing to malloc get a unique tag and cannot point to other vars");
-         goto err;
-       }
-
       if (pi->name_mem_tag
          && !pi->pt_malloc
          && (pi->pt_vars == NULL