aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@redhat.com>2004-08-18 18:21:23 +0000
committerDiego Novillo <dnovillo@gcc.gnu.org>2004-08-18 14:21:23 -0400
commit50dc9a88c1edf862816c804f8ea93443d257180c (patch)
tree44097e1b0caa8eb28b72d009d6ad0158ac4c06a9
parentbb0452b18763a8aa8e082a289ae5848a1753ba3e (diff)
downloadgcc-50dc9a88c1edf862816c804f8ea93443d257180c.zip
gcc-50dc9a88c1edf862816c804f8ea93443d257180c.tar.gz
gcc-50dc9a88c1edf862816c804f8ea93443d257180c.tar.bz2
tree-dfa.c (add_referenced_var): Only global variables are call-clobbered.
* 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
-rw-r--r--gcc/ChangeLog37
-rw-r--r--gcc/tree-dfa.c6
-rw-r--r--gcc/tree-flow.h3
-rw-r--r--gcc/tree-ssa-alias.c134
-rw-r--r--gcc/tree-ssa-operands.c37
-rw-r--r--gcc/tree-ssa.c12
6 files changed, 129 insertions, 100 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6dc3306..d4e6bc3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 0273406..b8a9b033 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -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
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 0e60e41..ca5897a 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -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;
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index a344384..8cfc65a 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -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;
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 4b899ee..230167f 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -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);
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index eb6f967..743c084 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -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