This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa]: Get PTA bootstrapping again
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 10 Aug 2003 22:32:40 -0400 (EDT)
- Subject: [tree-ssa]: Get PTA bootstrapping again
Commited.
Bootstrapped on x86.
2003-08-10 Daniel Berlin <dberlin@dberlin.org>
* tree-dfa.c (compute_may_aliases): Move points-to initialization from
here.
(find_referenced_vars): To here.
(get_memory_tag_for): Use new same_points_to_set function.
* tree-alias-common.h (struct tree_alias_ops): Remove doxygen markers.
Add same_points_to_set function to struct.
(same_points_to_set): New function.
* tree-alias-common.c (we_created_global_var): A bit of magic to ignore
global var aliasing when we didn't create global var. This will go
away soon
(same_points_to_set): New function.
* tree-alias-andersen.c (struct andersen_alias_ops): Add
andersen_same_points_to_set.
(andersen_same_points_to_set): New function. Return true if the two
variables have the same points-to set.
* opts.c (common_handle_option): Add "none" as a points-to option.
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.143
diff -u -3 -p -r1.1.4.143 tree-dfa.c
--- tree-dfa.c 8 Aug 2003 00:27:10 -0000 1.1.4.143
+++ tree-dfa.c 11 Aug 2003 02:14:39 -0000
@@ -1716,12 +1716,6 @@ compute_may_aliases (tree fndecl ATTRIBU
{
timevar_push (TV_TREE_MAY_ALIAS);
- if (flag_tree_points_to != PTA_NONE)
- {
- timevar_push (TV_TREE_PTA);
- create_alias_vars (fndecl);
- timevar_pop (TV_TREE_PTA);
- }
/* Compute alias sets. */
compute_alias_sets ();
@@ -1762,6 +1756,13 @@ find_referenced_vars (tree fndecl)
VARRAY_GENERIC_PTR_INIT (addressable_vars, 20, "addressable_vars");
VARRAY_GENERIC_PTR_INIT (pointers, 20, "pointers");
+
+ if (flag_tree_points_to != PTA_NONE)
+ {
+ timevar_push (TV_TREE_PTA);
+ create_alias_vars (fndecl);
+ timevar_pop (TV_TREE_PTA);
+ }
/* Walk the lexical blocks in the function looking for variables that may
have been used to declare VLAs and for nested functions. Both
@@ -2520,7 +2521,7 @@ get_memory_tag_for (tree ptr)
struct alias_map_d *curr = VARRAY_GENERIC_PTR (pointers, i);
if (alias_sets_conflict_p (curr->set, tag_set)
&& (flag_tree_points_to == PTA_NONE
- || ptr_may_alias_var (ptr, curr->var)))
+ || same_points_to_set (ptr, curr->var)))
{
tag = var_ann (curr->var)->mem_tag;
break;
Index: tree-alias-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-alias-common.h,v
retrieving revision 1.1.2.9
diff -u -3 -p -r1.1.2.9 tree-alias-common.h
--- tree-alias-common.h 21 Jul 2003 13:51:05 -0000 1.1.2.9
+++ tree-alias-common.h 11 Aug 2003 02:14:39 -0000
@@ -9,68 +9,46 @@
*/
struct tree_alias_ops
{
- /**
- @brief Initialization
-
- Called right before we start using the other functions.
- */
+ /* Initialization.
+ Called right before we start using the other functions. */
void (*init) (struct tree_alias_ops *);
- /**
- @brief Cleanup
-
- Called when we are finished with the alias analyzer.
- */
+ /* Cleanup.
+ Called when we are finished with the alias analyzer. */
void (*cleanup) (struct tree_alias_ops *);
- /**
- @brief Add variable
-
+ /* Add variable.
Called when we want to inform the alias analyzer about a new
- variable we've found.
- */
+ variable we've found. */
alias_typevar (*add_var) (struct tree_alias_ops *, tree);
- /**
- @brief Add variable equivalent to existing one.
-
+ /* Add variable equivalent to existing one.
Called when we want to inform the alias analyzer about a new
- variable that has the same points-to set as an existing variable.
- */
+ variable that has the same points-to set as an existing
+ variable. */
alias_typevar (*add_var_same) (struct tree_alias_ops *, tree,
- alias_typevar);
- /**
- @brief Process a simple assignment (<tt>a = b</tt>)
-
- Called to process simple assignment statements of the form <tt>a =
- b</tt>, where a and b are both variables.
- */
+ alias_typevar);
+
+ /* Process a simple assignment (a = b).
+ Called to process simple assignment statements of the form a = b,
+ where a and b are both variables. */
void (*simple_assign) (struct tree_alias_ops *, alias_typevar,
alias_typevar);
- /**
- @brief Process an address assignment (<tt>a = &b</tt>)
-
- Called to process address assignment statements of the form <tt>a =
- &b</tt>, where a and b are both variables.
- */
+ /* Process an address assignment (a = &b).
+ Called to process address assignment statements of the form a =
+ &b, where a and b are both variables. */
void (*addr_assign) (struct tree_alias_ops *, alias_typevar, alias_typevar);
- /**
- @brief Process a pointer assignment (<tt>a = *b</tt>)
-
- Called to process pointer assignment statements of the form <tt>a =
- *b</tt>, where a and b are both variables.
- */
+ /* Process a pointer assignment (a = *b).
+ Called to process pointer assignment statements of the form a =
+ *b, where a and b are both variables. */
void (*ptr_assign) (struct tree_alias_ops *, alias_typevar, alias_typevar);
- /**
- @brief Process an operator assignment (<tt>a = op (...)</tt>)
-
- Called to process operators of the form <tt>a = op(....)</tt>, where a is
- a variable.
- */
- void (*op_assign) (struct tree_alias_ops *, alias_typevar, varray_type, tree);
-
+ /* Process an operator assignment (a = op (...))
+ Called to process operators of the form a = op(...), where a is a
+ variable. */
+ void (*op_assign) (struct tree_alias_ops *, alias_typevar, varray_type,
+ tree);
/**
@brief Process a heap assignment (<tt>a = alloc (...)</tt>)
@@ -110,6 +88,11 @@ struct tree_alias_ops
*/
bool (*may_alias) (struct tree_alias_ops *, alias_typevar, alias_typevar);
+ /*
+ Determine if two typevars have the same points-to set.
+ */
+ bool (*same_points_to_set) (struct tree_alias_ops *, alias_typevar, alias_typevar);
+
/**
@brief Private data
*/
@@ -125,6 +108,7 @@ extern void create_alias_vars (tree);
extern void delete_alias_vars (void);
extern void init_alias_vars (void);
extern bool ptr_may_alias_var (tree, tree);
+extern bool same_points_to_set (tree, tree);
extern const char *alias_get_name (tree);
#endif
Index: tree-alias-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-alias-common.c,v
retrieving revision 1.1.2.33
diff -u -3 -p -r1.1.2.33 tree-alias-common.c
--- tree-alias-common.c 29 Jul 2003 15:19:49 -0000 1.1.2.33
+++ tree-alias-common.c 11 Aug 2003 02:14:39 -0000
@@ -89,6 +89,7 @@ static hashval_t annot_hash (const PTR);
static int annot_eq (const PTR, const PTR);
static void get_values_from_constructor (tree, varray_type *);
static bool call_may_clobber (tree);
+bool we_created_global_var = false;
static bool
call_may_clobber (tree expr)
@@ -320,11 +321,14 @@ intra_function_call (varray_type args)
alias_typevar tempvar;
tree temp = create_tmp_alias_var (void_type_node, "aliastmp");
tempvar = current_alias_ops->add_var (current_alias_ops, temp);
- /* Arguments can alias globals, and whatever they point to
- can point to a global as well. */
- current_alias_ops->addr_assign (current_alias_ops, argav, av);
- current_alias_ops->addr_assign (current_alias_ops, tempvar, av);
- current_alias_ops->assign_ptr (current_alias_ops, argav, tempvar);
+ if (!we_created_global_var)
+ {
+ /* Arguments can alias globals, and whatever they point to
+ can point to a global as well. */
+ current_alias_ops->addr_assign (current_alias_ops, argav, av);
+ current_alias_ops->addr_assign (current_alias_ops, tempvar, av);
+ current_alias_ops->assign_ptr (current_alias_ops, argav, tempvar);
+ }
}
}
/* We assume assignments among the actual parameters. */
@@ -419,14 +423,13 @@ find_func_aliases (tree *tp, int *walk_s
}
if (is_gimple_modify_expr (stp)
- || (TREE_CODE (stp) == VAR_DECL
- && DECL_INITIAL (stp) != NULL_TREE ))
+ || (DECL_P (stp) && DECL_INITIAL (stp) != NULL_TREE ))
{
tree op0, op1;
alias_typevar lhsAV = NULL;
alias_typevar rhsAV = NULL;
- if (TREE_CODE (stp) == VAR_DECL)
+ if (DECL_P (stp))
{
op0 = stp;
op1 = DECL_INITIAL (stp);
@@ -441,6 +444,16 @@ find_func_aliases (tree *tp, int *walk_s
/* rhsAV might not have one, c.f. c = 5 */
rhsAV = get_alias_var (op1);
+ if (we_created_global_var)
+ {
+ rhsAV = rhsAV == get_alias_var (global_var) ? NULL : rhsAV;
+ if (lhsAV == get_alias_var (global_var))
+ {
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ }
+ }
+
/* You would think we could test rhsAV at the top, rather than
50 separate times, but we can't, because it can be NULL for
operator assignments, where we'd still collect the individual
@@ -734,7 +747,7 @@ create_fun_alias_var (tree decl, int for
/* FIXME: Need to let analyzer decide in partial case. */
&& (!current_alias_ops->ip_partial
|| !TREE_STATIC (decl)
- || TREE_PUBLIC (decl)))
+ || TREE_PUBLIC (decl)) && !we_created_global_var)
current_alias_ops->addr_assign (current_alias_ops, tvar,
get_alias_var (global_var));
}
@@ -918,7 +931,6 @@ create_alias_var (tree decl)
return avar;
}
-
/**
@brief Create points-to sets for a function.
@param fndecl Function we are creating alias variables for.
@@ -929,12 +941,12 @@ create_alias_var (tree decl)
void
create_alias_vars (tree fndecl)
{
- bool we_created_global_var = false;
#if 0
tree currdecl = getdecls ();
tree fnbody;
#endif
size_t i;
+ we_created_global_var = false;
currptadecl = fndecl;
if (!global_var)
{
@@ -1032,7 +1044,87 @@ init_alias_vars (void)
alias_annot = htab_create_ggc (7, annot_hash, annot_eq, NULL);
}
+bool
+same_points_to_set (tree ptr, tree var)
+{
+ struct alias_annot_entry entry, *result;
+ alias_typevar ptrtv, vartv;
+ tree ptrcontext;
+ tree varcontext;
+#if !FIELD_BASED
+#else
+ if (TREE_CODE (ptr) == COMPONENT_REF)
+ ptr = TREE_OPERAND (ptr, 1);
+ if (TREE_CODE (var) == COMPONENT_REF)
+ var = TREE_OPERAND (var, 1);
+#endif
+
+ ptrcontext = DECL_CONTEXT (ptr);
+ varcontext = DECL_CONTEXT (var);
+ if (TREE_PUBLIC (ptr))
+ ptr = global_var;
+ else
+ {
+ if (ptrcontext != NULL && TREE_CODE (ptrcontext) != FUNCTION_DECL)
+ ptrcontext = decl_function_context (ptr);
+ if (ptrcontext == NULL)
+ ptr = global_var;
+ }
+ if (TREE_PUBLIC (var))
+ var = global_var;
+ else
+ {
+ if (varcontext != NULL && TREE_CODE (varcontext) != FUNCTION_DECL)
+ varcontext = decl_function_context (var);
+ if (varcontext == NULL)
+ var = global_var;
+ }
+ if (ptr == var || (ptrcontext == NULL && varcontext == NULL)
+ || (ptr == global_var))
+ return true;
+
+ if (DECL_P (ptr))
+ {
+ ptrtv = DECL_PTA_TYPEVAR (ptr);
+ if (!ptrtv && !current_alias_ops->ip && ptr != global_var)
+ abort ();
+ else if (!ptrtv)
+ return false;
+ }
+ else
+ {
+ entry.key = ptr;
+ result = htab_find (alias_annot, &entry);
+ if (!result && !current_alias_ops->ip && ptr != global_var)
+ abort ();
+ else if (!result)
+ return false;
+ ptrtv = result->value;
+ }
+ if (var == global_var && global_var == NULL)
+ return false;
+ if (DECL_P (var))
+ {
+ vartv = DECL_PTA_TYPEVAR (var);
+ if (!vartv && !current_alias_ops->ip && var != global_var)
+ abort ();
+ else if (!vartv)
+ return false;
+ }
+ else
+ {
+ entry.key = var;
+ result = htab_find (alias_annot, &entry);
+ if (!result && !current_alias_ops->ip && var != global_var)
+ abort ();
+ else if (!result)
+ return false;
+
+ vartv = result->value;
+ }
+ return current_alias_ops->same_points_to_set (current_alias_ops, vartv, ptrtv);
+}
/**
@brief Determine whether two variables may-alias.
@@ -1121,7 +1213,6 @@ ptr_may_alias_var (tree ptr, tree var)
}
return current_alias_ops->may_alias (current_alias_ops, ptrtv, vartv);
-
}
#define MASK_POINTER(P) ((unsigned)((unsigned long)(P) & 0xffff))
Index: tree-alias-ander.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-alias-ander.c,v
retrieving revision 1.1.2.13
diff -u -3 -p -r1.1.2.13 tree-alias-ander.c
--- tree-alias-ander.c 15 Jul 2003 05:53:16 -0000 1.1.2.13
+++ tree-alias-ander.c 11 Aug 2003 02:14:40 -0000
@@ -82,6 +82,8 @@ static int print_out_result (splay_tree_
static void andersen_cleanup (struct tree_alias_ops *);
static bool andersen_may_alias (struct tree_alias_ops *, alias_typevar,
alias_typevar);
+static bool andersen_same_points_to_set (struct tree_alias_ops *, alias_typevar,
+ alias_typevar);
static alias_typevar andersen_add_var (struct tree_alias_ops *, tree);
static alias_typevar andersen_add_var_same (struct tree_alias_ops *,
tree, alias_typevar);
@@ -104,6 +106,7 @@ static struct tree_alias_ops andersen_op
andersen_function_def,
andersen_function_call,
andersen_may_alias,
+ andersen_same_points_to_set,
0, /* data */
0, /* Currently non-interprocedural */
1 /* Can do IP on all statics without help. */
@@ -699,7 +702,55 @@ eq_to_var (const aterm term)
{
return stupid_hack == term;
}
+static int simple_eq (const aterm a, const aterm b)
+{
+ return (int *)a - (int *)b;
+}
+extern bool we_created_global_var;
+static bool
+andersen_same_points_to_set (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
+ alias_typevar ptrtv, alias_typevar vartv)
+{
+ aterm_list ptset1, ptset2;
+ aterm_list_scanner scan1, scan2;
+ void *data1, *data2;
+ size_t length1, length2;
+ region scratch_rgn = newregion ();
+ ptset1 = ALIAS_TVAR_PTSET (ptrtv);
+ ptset2 = ALIAS_TVAR_PTSET (vartv);
+ if (!ptset1)
+ {
+ ptset1 = aterm_tlb (pta_get_contents (ALIAS_TVAR_ATERM (ptrtv)));
+ ALIAS_TVAR_PTSET (ptrtv) = ptset1;
+ }
+ if (!ptset2)
+ {
+ ptset2 = aterm_tlb (pta_get_contents (ALIAS_TVAR_ATERM (vartv)));
+ ALIAS_TVAR_PTSET (vartv) = ptset2;
+ }
+ if (aterm_list_length (ptset1) != aterm_list_length (ptset2))
+ return false;
+ if (ptset1 == ptset2)
+ return true;
+ length1 = aterm_list_length (ptset1);
+ length2 = aterm_list_length (ptset2);
+ ptset1 = aterm_list_copy (scratch_rgn, ptset1);
+ ptset2 = aterm_list_copy (scratch_rgn, ptset2);
+
+ ptset1 = aterm_list_sort (ptset1, simple_eq);
+ ptset2 = aterm_list_sort (ptset2, simple_eq);
+
+ aterm_list_scan (ptset1, &scan1);
+ aterm_list_scan (ptset2, &scan2);
+ while (list_next (&scan1, &data1))
+ {
+ list_next (&scan2, &data2);
+ if (data1 != data2)
+ return false;
+ }
+ return true;
+}
static bool
andersen_may_alias (struct tree_alias_ops *ops ATTRIBUTE_UNUSED,
alias_typevar ptrtv, alias_typevar vartv)
Index: opts.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/opts.c,v
retrieving revision 1.31.2.6
diff -u -3 -p -r1.31.2.6 opts.c
--- opts.c 29 Jul 2003 04:45:58 -0000 1.31.2.6
+++ opts.c 11 Aug 2003 02:14:41 -0000
@@ -1383,6 +1383,8 @@ common_handle_option (size_t scode, cons
#else
warning ("Andersen's PTA not available - libbanshee not compiled.");
#endif
+ else if (!strcmp (arg, "none"))
+ flag_tree_points_to = PTA_NONE;
else
{
warning ("`%s`: unknown points-to analysis algorithm", arg);