Commit 50dc9a88 by Diego Novillo Committed by Diego Novillo

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
parent bb0452b1
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> 2004-08-18 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (CONDITIONAL_REGISTER_USAGE): Don't exclude fixed registers * sh.h (CONDITIONAL_REGISTER_USAGE): Don't exclude fixed registers
......
...@@ -903,10 +903,8 @@ add_referenced_var (tree var, struct walk_state *walk_state) ...@@ -903,10 +903,8 @@ add_referenced_var (tree var, struct walk_state *walk_state)
v_ann->uid = num_referenced_vars; v_ann->uid = num_referenced_vars;
VARRAY_PUSH_TREE (referenced_vars, var); VARRAY_PUSH_TREE (referenced_vars, var);
/* Initially assume that all memory variables are /* Global variables are always call-clobbered. */
call-clobbered. This will be refined later by the alias if (is_global_var (var))
analyzer. */
if (needs_to_live_in_memory (var))
mark_call_clobbered (var); mark_call_clobbered (var);
/* If an initialized global variable then register the initializer /* If an initialized global variable then register the initializer
......
...@@ -62,6 +62,9 @@ struct ptr_info_def GTY(()) ...@@ -62,6 +62,9 @@ struct ptr_info_def GTY(())
/* Nonzero if this pointer is dereferenced. */ /* Nonzero if this pointer is dereferenced. */
unsigned int is_dereferenced : 1; 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. */ /* Set of variables that this pointer may point to. */
bitmap pt_vars; bitmap pt_vars;
......
...@@ -653,16 +653,14 @@ compute_points_to_and_addr_escape (struct alias_info *ai) ...@@ -653,16 +653,14 @@ compute_points_to_and_addr_escape (struct alias_info *ai)
collect_points_to_info_for (ai, op); 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 (ptr_is_dereferenced_by (op, stmt, &is_store))
{ {
/* If we found OP to point to a set of variables or /* Mark OP as dereferenced. In a subsequent pass,
malloc, then mark it as being dereferenced. In a dereferenced pointers that point to a set of
subsequent pass, dereferenced pointers that point variables will be assigned a name tag to alias
to a set of variables will be assigned a name tag all the variables OP points to. */
to alias all the variables OP points to. */ pi->is_dereferenced = 1;
if (pi->pt_malloc || pi->pt_vars)
pi->is_dereferenced = 1;
/* Keep track of how many time we've dereferenced each /* Keep track of how many time we've dereferenced each
pointer. Again, we don't need to grow pointer. Again, we don't need to grow
...@@ -762,15 +760,16 @@ create_name_tags (struct alias_info *ai) ...@@ -762,15 +760,16 @@ create_name_tags (struct alias_info *ai)
tree ptr = VARRAY_TREE (ai->processed_ptrs, i); tree ptr = VARRAY_TREE (ai->processed_ptrs, i);
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr); 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 /* No name tags for pointers that have not been
dereferenced. */ dereferenced or point to an arbitrary location. */
pi->name_mem_tag = NULL_TREE; pi->name_mem_tag = NULL_TREE;
continue; continue;
} }
if (pi->pt_vars) if (pi->pt_vars
&& bitmap_first_set_bit (pi->pt_vars) >= 0)
{ {
size_t j; size_t j;
tree old_name_tag = pi->name_mem_tag; tree old_name_tag = pi->name_mem_tag;
...@@ -859,38 +858,14 @@ compute_flow_sensitive_aliasing (struct alias_info *ai) ...@@ -859,38 +858,14 @@ compute_flow_sensitive_aliasing (struct alias_info *ai)
if (pi->value_escapes_p || pi->pt_anything) if (pi->value_escapes_p || pi->pt_anything)
{ {
/* If PTR escapes or may point to anything, then its associated /* 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) if (pi->name_mem_tag)
mark_call_clobbered (pi->name_mem_tag); mark_call_clobbered (pi->name_mem_tag);
if (v_ann->type_mem_tag) if (v_ann->type_mem_tag)
mark_call_clobbered (v_ann->type_mem_tag); mark_call_clobbered (v_ann->type_mem_tag);
/* If PTR may point to anything, mark call-clobbered all the if (pi->pt_vars)
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)
EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j,
mark_call_clobbered (referenced_var (j))); mark_call_clobbered (referenced_var (j)));
} }
...@@ -1684,7 +1659,9 @@ add_may_alias (tree var, tree alias) ...@@ -1684,7 +1659,9 @@ add_may_alias (tree var, tree alias)
if (alias == VARRAY_TREE (v_ann->may_aliases, i)) if (alias == VARRAY_TREE (v_ann->may_aliases, i))
return; 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)) if (is_call_clobbered (var))
mark_call_clobbered (alias); mark_call_clobbered (alias);
...@@ -1705,7 +1682,9 @@ replace_may_alias (tree var, size_t i, tree new_alias) ...@@ -1705,7 +1682,9 @@ replace_may_alias (tree var, size_t i, tree new_alias)
var_ann_t v_ann = var_ann (var); var_ann_t v_ann = var_ann (var);
VARRAY_TREE (v_ann->may_aliases, i) = new_alias; 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)) if (is_call_clobbered (var))
mark_call_clobbered (new_alias); mark_call_clobbered (new_alias);
...@@ -1724,8 +1703,6 @@ set_pt_anything (tree ptr) ...@@ -1724,8 +1703,6 @@ set_pt_anything (tree ptr)
pi->pt_anything = 1; pi->pt_anything = 1;
pi->pt_malloc = 0; 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 /* 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 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) ...@@ -1812,6 +1789,8 @@ merge_pointed_to_info (struct alias_info *ai, tree dest, tree orig)
orig_pi->pt_vars); 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) ...@@ -1882,14 +1861,14 @@ add_pointed_to_var (struct alias_info *ai, tree ptr, tree value)
uid = var_ann (pt_var)->uid; uid = var_ann (pt_var)->uid;
bitmap_set_bit (ai->addresses_needed, uid); bitmap_set_bit (ai->addresses_needed, uid);
/* If PTR has already been found to point anywhere, don't if (pi->pt_vars == NULL)
add the variable to PTR's points-to set. */ pi->pt_vars = BITMAP_GGC_ALLOC ();
if (!pi->pt_anything) bitmap_set_bit (pi->pt_vars, uid);
{
if (pi->pt_vars == NULL) /* If the variable is a global, mark the pointer as pointing to
pi->pt_vars = BITMAP_GGC_ALLOC (); global memory (which will make its tag a global variable). */
bitmap_set_bit (pi->pt_vars, uid); 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) ...@@ -1937,17 +1916,33 @@ collect_points_to_info_r (tree var, tree stmt, void *data)
tree op0 = TREE_OPERAND (rhs, 0); tree op0 = TREE_OPERAND (rhs, 0);
tree op1 = TREE_OPERAND (rhs, 1); tree op1 = TREE_OPERAND (rhs, 1);
if (TREE_CODE (op0) == SSA_NAME /* Both operands may be of pointer type. FIXME: Shouldn't
&& POINTER_TYPE_P (TREE_TYPE (op0))) we just expect PTR + OFFSET always? */
merge_pointed_to_info (ai, var, op0); if (POINTER_TYPE_P (TREE_TYPE (op0)))
else if (TREE_CODE (op1) == SSA_NAME {
&& POINTER_TYPE_P (TREE_TYPE (op1))) if (TREE_CODE (op0) == SSA_NAME)
merge_pointed_to_info (ai, var, op1); merge_pointed_to_info (ai, var, op0);
else if (TREE_CODE (op0) == ADDR_EXPR) else if (TREE_CODE (op0) == ADDR_EXPR)
add_pointed_to_var (ai, var, op0); add_pointed_to_var (ai, var, op0);
else if (TREE_CODE (op1) == ADDR_EXPR) else
add_pointed_to_var (ai, var, op1); add_pointed_to_expr (var, op0);
else }
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); add_pointed_to_expr (var, rhs);
} }
...@@ -1980,12 +1975,7 @@ collect_points_to_info_r (tree var, tree stmt, void *data) ...@@ -1980,12 +1975,7 @@ collect_points_to_info_r (tree var, tree stmt, void *data)
if (TREE_CODE (var) == ADDR_EXPR) if (TREE_CODE (var) == ADDR_EXPR)
add_pointed_to_var (ai, lhs, var); add_pointed_to_var (ai, lhs, var);
else if (TREE_CODE (var) == SSA_NAME) else if (TREE_CODE (var) == SSA_NAME)
{ merge_pointed_to_info (ai, lhs, var);
if (bitmap_bit_p (ai->ssa_names_visited, SSA_NAME_VERSION (var)))
merge_pointed_to_info (ai, lhs, var);
else
set_pt_anything (lhs);
}
else if (is_gimple_min_invariant (var)) else if (is_gimple_min_invariant (var))
add_pointed_to_expr (lhs, var); add_pointed_to_expr (lhs, var);
else else
...@@ -2106,13 +2096,11 @@ get_nmt_for (tree ptr) ...@@ -2106,13 +2096,11 @@ get_nmt_for (tree ptr)
if (tag == NULL_TREE) if (tag == NULL_TREE)
tag = create_memory_tag (TREE_TYPE (TREE_TYPE (ptr)), false); tag = create_memory_tag (TREE_TYPE (TREE_TYPE (ptr)), false);
/* If PTR is a PARM_DECL, its memory tag should be considered a global /* If PTR is a PARM_DECL, it points to a global variable or malloc,
variable. */ then its name tag should be considered a global variable. */
if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL) if (TREE_CODE (SSA_NAME_VAR (ptr)) == PARM_DECL
mark_call_clobbered (tag); || pi->pt_malloc
|| pi->pt_global_mem)
/* Similarly, if PTR points to malloc, then TAG is a global. */
if (pi->pt_malloc)
mark_call_clobbered (tag); mark_call_clobbered (tag);
return tag; return tag;
......
...@@ -89,7 +89,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -89,7 +89,7 @@ Boston, MA 02111-1307, USA. */
#define opf_is_def (1 << 0) #define opf_is_def (1 << 0)
/* Operand is the target of an assignment expression. */ /* 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 /* No virtual operands should be created in the expression. This is used
when traversing ADDR_EXPR nodes which have different semantics than when traversing ADDR_EXPR nodes which have different semantics than
...@@ -97,7 +97,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -97,7 +97,7 @@ Boston, MA 02111-1307, USA. */
need to consider are indices into arrays. For instance, &a.b[i] should 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 generate a USE of 'i' but it should not generate a VUSE for 'a' nor a
VUSE for 'b'. */ VUSE for 'b'. */
#define opf_no_vops (1 << 1) #define opf_no_vops (1 << 2)
/* Array for building all the def operands. */ /* Array for building all the def operands. */
static GTY (()) varray_type build_defs; static GTY (()) varray_type build_defs;
...@@ -1273,6 +1273,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags) ...@@ -1273,6 +1273,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
tree ptr = *pptr; tree ptr = *pptr;
stmt_ann_t ann = stmt_ann (stmt); 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)) if (SSA_VAR_P (ptr))
{ {
...@@ -1456,20 +1458,31 @@ add_stmt_operand (tree *var_p, tree stmt, int flags) ...@@ -1456,20 +1458,31 @@ add_stmt_operand (tree *var_p, tree stmt, int flags)
{ {
if (v_ann->is_alias_tag) 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) if (s_ann)
s_ann->makes_aliased_stores = 1; s_ann->makes_aliased_stores = 1;
append_v_may_def (var); append_v_may_def (var);
} }
else if ((flags & opf_kill_def) else if (flags & opf_kill_def)
&& v_ann->mem_tag_kind == NOT_A_TAG) {
/* V_MUST_DEF for non-aliased non-GIMPLE register #if defined ENABLE_CHECKING
variable definitions. Avoid memory tags. */ /* Only regular variables may get a V_MUST_DEF
append_v_must_def (var); 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 else
/* Call-clobbered variables & memory tags get {
V_MAY_DEF */ /* Add a V_MAY_DEF for call-clobbered variables and
append_v_may_def (var); memory tags. */
append_v_may_def (var);
}
} }
else else
{ {
...@@ -1506,6 +1519,8 @@ add_stmt_operand (tree *var_p, tree stmt, int flags) ...@@ -1506,6 +1519,8 @@ add_stmt_operand (tree *var_p, tree stmt, int flags)
} }
else else
{ {
/* Similarly, append a virtual uses for VAR itself, when
it is an alias tag. */
if (v_ann->is_alias_tag) if (v_ann->is_alias_tag)
append_vuse (var); append_vuse (var);
......
...@@ -433,18 +433,6 @@ verify_flow_sensitive_alias_info (void) ...@@ -433,18 +433,6 @@ verify_flow_sensitive_alias_info (void)
goto err; 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 if (pi->name_mem_tag
&& !pi->pt_malloc && !pi->pt_malloc
&& (pi->pt_vars == NULL && (pi->pt_vars == NULL
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment