[PATCH]: alias slowdown patch
Daniel Berlin
dberlin@dberlin.org
Tue Nov 21 15:57:00 GMT 2006
Here ya go. This should fix your time and memory issues.
For cplusplus_grammar.ii i get:
tree PTA : 1.76 ( 3%) usr 0.09 ( 1%) sys 2.03 (
2%) wall 3591 kB ( 1%) ggc
tree alias analysis : 7.93 (12%) usr 1.26 ( 9%) sys 9.95
(11%) wall 3986 kB ( 1%) ggc
Note that the remaining "tree alias analysis" time is actually copying
the bitmap sets from PTA to SSA_NAME_PTR_INFO, 5 times, for 100000
variables. We then take these bitmaps from SSA_NAME_PTR_INFO, and
explicitly enumerate them into vectors in the form of add_may_alias.
This is a bit dumb.
The second worst part is that we know only about 30000 of them have
different points-to sets, but there is no way to explain this to what
is asking us.
While fixing the timing issue, i discovered serious memory usage
issues that occur if we try to compute the real points-to sets instead
of punting (which is what i've really done with this patch).
In fact, I got it to compute the complete points-to sets in 3 seconds,
using 50 meg of memory.
However, we then take these sets, and explicitly enumerate them into
these two places I mentioned above, and waste 800 meg of memory
keeping them around.
So for now, i have punted and we don't compute the points-to set for
global variables anymore to avoid this, but this is really a kludge
(if you were to say, move the large table into the function, you would
hit the same problem)
I want to move us to something other than sparse bitmaps for points-to
(BDD's), because they are about 100x more memory efficient (it is like
sharing all the same bits of the bitmaps for all the points-to sets at
once), but real overall memory savings will mean we are going to have
to stop explicitly enumerating *all* of our points-to sets into
bitmaps at once during alias analysis like we do now.
It is perfectly fine and fast to enumerate the set for one variable at
a time from the BDD (it's cached), as long as we stop trying to keep
the bitmaps around.
As our points-to sets get bigger (which is inveitable if we have to
handle codes like this, and move to interprocedural analysis), this is
only going to get worse and worse.
I can make it fast, but without changing the way we postprocess these
sets, i can't make it memory efficient.
Thoughts?
(I will commit this patch to 4.2 branch and mainline once it finishes
bootstrap/regtesting. It already passed bootstrap once, though that
version had a few should-be-cosmetic differences than this one, just
to CYA :P )
--Dan
2006-11-21 Daniel Berlin <dberlin@dberlin.org>
* tree-ssa-structalias.c: Update comments.
(var_escaped_vars): Remove.
(escaped_vars_tree): Remove.
(escaped_vars_id): Remove.
(constraint_expr_type): Add INCLUDES.
(graph_size): Removed.
(dump_constraint): Support INCLUDES.
(build_constraint_graph): Ditto.
(collapse_nodes): Add merge_solutions argument.
Don't merge attributes.
(process_unification_queue): Just use collapse_nodes.
(perform_var_substitution): Update call to collapse_nodes.
(get_constraint_exp_from_ssa_var): Use INCLUDES.
(process_constraint): Fix non-field sensitive handling
Handle includes.
(get_constraint_for): Use INCLUDES.
(make_constraint_from_escaped): Use nonlocal_vars_id.
(make_constraint_to_escaped): Removed.
(find_global_initializers): Removed.
(create_variable_info_for): Do not make constraints to escaped
vars anymore.
(dump_solution_for_var): Don't print out the equivalent points-to
sets, just use the name of the variable it shares it with.
(intra_create_variable_infos): Use INCLUDES.
Move initialization of nonlocal variable to init_base_vars.
(init_base_vars): Init nonlocal variable here.
Remove escaped_vars initialization.
(find_escape_constraints): Removed.
(delete_points_to_sets): Remove dead code.
-------------- next part --------------
--- gcc/tree-ssa-structalias.c (/mirror/gcc-trunk) (revision 173)
+++ gcc/tree-ssa-structalias.c (/local/gcc-clean) (revision 173)
@@ -72,9 +72,10 @@ Foundation, Inc., 51 Franklin Street, Fi
of C Code in a Second" by ""Nevin Heintze and Olivier Tardieu" at
http://citeseer.ist.psu.edu/heintze01ultrafast.html
- There are three types of constraint expressions, DEREF, ADDRESSOF, and
- SCALAR. Each constraint expression consists of a constraint type,
- a variable, and an offset.
+ There are three types of real constraint expressions, DEREF,
+ ADDRESSOF, and SCALAR. There is one type of fake constraint
+ expression, called INCLUDES. Each constraint expression consists
+ of a constraint type, a variable, and an offset.
SCALAR is a constraint expression type used to represent x, whether
it appears on the LHS or the RHS of a statement.
@@ -82,6 +83,10 @@ Foundation, Inc., 51 Franklin Street, Fi
it appears on the LHS or the RHS of a statement.
ADDRESSOF is a constraint expression used to represent &x, whether
it appears on the LHS or the RHS of a statement.
+ INCLUDES is a constraint expression type used to represent just a
+ setting of a bit in the points-to set without having the address
+ taken. It exists mainly for abstraction sake, and is used for
+ initializing fake variables like the ESCAPED_VARS set.
Each pointer variable in the program is assigned an integer id, and
each field of a structure variable is assigned an integer id as well.
@@ -322,14 +327,8 @@ static varinfo_t var_integer;
static tree integer_tree;
static unsigned int integer_id;
-/* Variable that represents escaped variables. This is used to give
- incoming pointer variables a better set than ANYTHING. */
-static varinfo_t var_escaped_vars;
-static tree escaped_vars_tree;
-static unsigned int escaped_vars_id;
-
-/* Variable that represents non-local variables before we expand it to
- one for each type. */
+/* Variable that represents non-local variables. */
+static varinfo_t var_nonlocal;
static unsigned int nonlocal_vars_id;
/* Lookup a heap var for FROM, and return it if we find one. */
@@ -391,7 +390,7 @@ new_var_info (tree t, unsigned int id, c
return ret;
}
-typedef enum {SCALAR, DEREF, ADDRESSOF} constraint_expr_type;
+typedef enum {SCALAR, DEREF, ADDRESSOF, INCLUDES} constraint_expr_type;
/* An expression that appears in a constraint. */
@@ -486,7 +485,6 @@ struct constraint_graph
typedef struct constraint_graph *constraint_graph_t;
static constraint_graph_t graph;
-static int graph_size;
/* Create a new constraint consisting of LHS and RHS expressions. */
@@ -508,7 +506,7 @@ dump_constraint (FILE *file, constraint_
if (c->lhs.type == ADDRESSOF)
fprintf (file, "&");
else if (c->lhs.type == DEREF)
- fprintf (file, "*");
+ fprintf (file, "*");
fprintf (file, "%s", get_varinfo_fc (c->lhs.var)->name);
if (c->lhs.offset != 0)
fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->lhs.offset);
@@ -517,9 +515,13 @@ dump_constraint (FILE *file, constraint_
fprintf (file, "&");
else if (c->rhs.type == DEREF)
fprintf (file, "*");
+ else if (c->rhs.type == INCLUDES)
+ fprintf (file, "{");
fprintf (file, "%s", get_varinfo_fc (c->rhs.var)->name);
if (c->rhs.offset != 0)
fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
+ if (c->rhs.type == INCLUDES)
+ fprintf (file, "}");
fprintf (file, "\n");
}
@@ -1200,6 +1202,7 @@ build_constraint_graph (void)
{
int i = 0;
constraint_t c;
+ int graph_size;
graph = XNEW (struct constraint_graph);
graph_size = VEC_length (varinfo_t, varmap) + 1;
@@ -1227,7 +1230,7 @@ build_constraint_graph (void)
if (!(get_varinfo (lhsvar)->is_special_var))
insert_into_complex (rhsvar, c);
}
- else if (rhs.type == ADDRESSOF)
+ else if (rhs.type == ADDRESSOF || rhs.type == INCLUDES)
{
/* x = &y */
bitmap_set_bit (get_varinfo (lhsvar)->solution, rhsvar);
@@ -1325,26 +1328,33 @@ scc_visit (constraint_graph_t graph, str
}
-/* Collapse two variables into one variable. */
+/* Collapse two variables into one variable, merging solutions if
+ requested. */
static void
-collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from)
+collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
+ bool merge_solutions)
{
bitmap tosol, fromsol;
- condense_varmap_nodes (to, from);
- tosol = get_varinfo (to)->solution;
- fromsol = get_varinfo (from)->solution;
- bitmap_ior_into (tosol, fromsol);
merge_graph_nodes (graph, to, from);
+ condense_varmap_nodes (to, from);
+ if (merge_solutions)
+ {
+ tosol = get_varinfo (to)->solution;
+ fromsol = get_varinfo (from)->solution;
+ bitmap_ior_into (tosol, fromsol);
+ BITMAP_FREE (fromsol);
+ }
if (valid_graph_edge (graph, to, to))
{
- if (graph->zero_weight_preds[to])
+ if (graph->zero_weight_succs[to])
{
bitmap_clear_bit (graph->zero_weight_preds[to], to);
bitmap_clear_bit (graph->zero_weight_succs[to], to);
}
+
if (valid_weighted_graph_edge (graph, to, to))
{
bitmap weights = *(get_graph_weights (graph, to, to));
@@ -1352,9 +1362,6 @@ collapse_nodes (constraint_graph_t graph
erase_graph_self_edge (graph, to);
}
}
- BITMAP_FREE (fromsol);
- get_varinfo (to)->address_taken |= get_varinfo (from)->address_taken;
- get_varinfo (to)->indirect_target |= get_varinfo (from)->indirect_target;
}
@@ -1409,8 +1416,7 @@ process_unification_queue (constraint_gr
else
stats.unified_vars_static++;
bitmap_ior_into (tmp, get_varinfo (tounify)->solution);
- merge_graph_nodes (graph, n, tounify);
- condense_varmap_nodes (n, tounify);
+ collapse_nodes (graph, n, tounify, false);
if (update_changed && TEST_BIT (changed, tounify))
{
@@ -1444,22 +1450,6 @@ process_unification_queue (constraint_gr
}
}
bitmap_clear (tmp);
-
- if (valid_graph_edge (graph, n, n))
- {
- if (graph->zero_weight_succs[n])
- {
- if (graph->zero_weight_preds[n])
- bitmap_clear_bit (graph->zero_weight_preds[n], n);
- bitmap_clear_bit (graph->zero_weight_succs[n], n);
- }
- if (valid_weighted_graph_edge (graph, n, n))
- {
- bitmap weights = *(get_graph_weights (graph, n, n));
- if (!weights || bitmap_empty_p (weights))
- erase_graph_self_edge (graph, n);
- }
- }
}
}
BITMAP_FREE (tmp);
@@ -1878,7 +1868,7 @@ perform_var_substitution (constraint_gra
bitmap tmp;
unsigned int k;
bitmap_iterator bi;
-
+
/* We can't eliminate things whose address is taken, or which is
the target of a dereference. */
if (vi->address_taken || vi->indirect_target)
@@ -1976,7 +1966,7 @@ perform_var_substitution (constraint_gra
{
/* Found an equivalence */
get_varinfo (i)->node = root;
- collapse_nodes (graph, root, i);
+ collapse_nodes (graph, root, i, true);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Collapsing %s into %s\n",
get_varinfo (i)->name,
@@ -2266,7 +2256,7 @@ get_constraint_exp_from_ssa_var (tree t)
say it points to readonly memory instead. */
if (cexpr.var == anything_id && TREE_READONLY (t))
{
- cexpr.type = ADDRESSOF;
+ cexpr.type = INCLUDES;
cexpr.var = readonly_id;
}
@@ -2285,18 +2275,27 @@ process_constraint (constraint_t t)
gcc_assert (rhs.var < VEC_length (varinfo_t, varmap));
gcc_assert (lhs.var < VEC_length (varinfo_t, varmap));
-
+
+ gcc_assert (lhs.type != INCLUDES);
+
if (lhs.type == DEREF)
get_varinfo (lhs.var)->directly_dereferenced = true;
if (rhs.type == DEREF)
get_varinfo (rhs.var)->directly_dereferenced = true;
+
+ if (!use_field_sensitive)
+ {
+ t->rhs.offset = 0;
+ t->lhs.offset = 0;
+ }
/* ANYTHING == ANYTHING is pointless. */
if (lhs.var == anything_id && rhs.var == anything_id)
return;
/* If we have &ANYTHING = something, convert to SOMETHING = &ANYTHING) */
- else if (lhs.var == anything_id && lhs.type == ADDRESSOF)
+ else if (lhs.var == anything_id
+ && (lhs.type == INCLUDES || lhs.type == ADDRESSOF))
{
rhs = t->lhs;
t->lhs = t->rhs;
@@ -2327,11 +2326,8 @@ process_constraint (constraint_t t)
varinfo_t vi;
gcc_assert (rhs.offset == 0);
- /* No need to mark address taken simply because of escaped vars
- constraints. */
- if (lhs.var != escaped_vars_id)
- for (vi = get_varinfo (rhs.var); vi != NULL; vi = vi->next)
- vi->address_taken = true;
+ for (vi = get_varinfo (rhs.var); vi != NULL; vi = vi->next)
+ vi->address_taken = true;
VEC_safe_push (constraint_t, heap, constraints, t);
}
@@ -2655,14 +2651,14 @@ get_constraint_for (tree t, VEC (ce_s, h
vi = get_varinfo (temp.var);
vi->is_artificial_var = 1;
vi->is_heap_var = 1;
- temp.type = ADDRESSOF;
+ temp.type = INCLUDES;
temp.offset = 0;
VEC_safe_push (ce_s, heap, *results, &temp);
return;
}
else
{
- temp.var = escaped_vars_id;
+ temp.var = anything_id;
temp.type = SCALAR;
temp.offset = 0;
VEC_safe_push (ce_s, heap, *results, &temp);
@@ -3817,24 +3813,9 @@ make_constraint_from_escaped (varinfo_t
lhs.offset = 0;
lhs.type = SCALAR;
- rhs.var = escaped_vars_id;
+ rhs.var = nonlocal_vars_id;
rhs.offset = 0;
- rhs.type = SCALAR;
- process_constraint (new_constraint (lhs, rhs));
-}
-
-/* Create a constraint to the ESCAPED_VARS variable from constraint
- expression RHS. */
-
-static void
-make_constraint_to_escaped (struct constraint_expr rhs)
-{
- struct constraint_expr lhs;
-
- lhs.var = escaped_vars_id;
- lhs.offset = 0;
- lhs.type = SCALAR;
-
+ rhs.type = INCLUDES;
process_constraint (new_constraint (lhs, rhs));
}
@@ -3988,59 +3969,6 @@ check_for_overlaps (VEC (fieldoff_s,heap
return false;
}
-/* This function is called through walk_tree to walk global
- initializers looking for constraints we need to add to the
- constraint list. */
-
-static tree
-find_global_initializers (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- void *viv)
-{
- varinfo_t vi = (varinfo_t)viv;
- tree t = *tp;
-
- switch (TREE_CODE (t))
- {
- /* Dereferences and addressofs are the only important things
- here, and i don't even remember if dereferences are legal
- here in initializers. */
- case INDIRECT_REF:
- case ADDR_EXPR:
- {
- struct constraint_expr *c;
- size_t i;
-
- VEC(ce_s, heap) *rhsc = NULL;
- get_constraint_for (t, &rhsc);
- for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
- {
- struct constraint_expr lhs;
-
- lhs.var = vi->id;
- lhs.type = SCALAR;
- lhs.offset = 0;
- process_constraint (new_constraint (lhs, *c));
- }
-
- VEC_free (ce_s, heap, rhsc);
- }
- break;
- case VAR_DECL:
- /* We might not have walked this because we skip
- DECL_EXTERNALs during the initial scan. */
- if (referenced_vars)
- {
- get_var_ann (t);
- if (referenced_var_check_and_insert (t))
- mark_sym_for_renaming (t);
- }
- break;
- default:
- break;
- }
- return NULL_TREE;
-}
-
/* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
This will also create any varinfo structures necessary for fields
of DECL. */
@@ -4098,27 +4026,7 @@ create_variable_info_for (tree decl, con
insert_id_for_tree (vi->decl, index);
VEC_safe_push (varinfo_t, heap, varmap, vi);
if (is_global && (!flag_whole_program || !in_ipa_mode))
- {
- make_constraint_from_escaped (vi);
-
- /* If the variable can't be aliased, there is no point in
- putting it in the set of nonlocal vars. */
- if (may_be_aliased (vi->decl))
- {
- struct constraint_expr rhs;
- rhs.var = index;
- rhs.type = ADDRESSOF;
- rhs.offset = 0;
- make_constraint_to_escaped (rhs);
- }
-
- if (TREE_CODE (decl) != FUNCTION_DECL && DECL_INITIAL (decl))
- {
- walk_tree_without_duplicates (&DECL_INITIAL (decl),
- find_global_initializers,
- (void *)vi);
- }
- }
+ make_constraint_from_escaped (vi);
stats.total_vars++;
if (use_field_sensitive
@@ -4198,20 +4106,7 @@ create_variable_info_for (tree decl, con
insert_into_field_list (vi, newvi);
VEC_safe_push (varinfo_t, heap, varmap, newvi);
if (is_global && (!flag_whole_program || !in_ipa_mode))
- {
- /* If the variable can't be aliased, there is no point in
- putting it in the set of nonlocal vars. */
- if (may_be_aliased (vi->decl))
- {
- struct constraint_expr rhs;
-
- rhs.var = newindex;
- rhs.type = ADDRESSOF;
- rhs.offset = 0;
- make_constraint_to_escaped (rhs);
- }
make_constraint_from_escaped (newvi);
- }
stats.total_vars++;
}
@@ -4229,12 +4124,20 @@ dump_solution_for_var (FILE *file, unsig
unsigned int i;
bitmap_iterator bi;
- fprintf (file, "%s = { ", vi->name);
- EXECUTE_IF_SET_IN_BITMAP (get_varinfo (vi->node)->solution, 0, i, bi)
+ if (vi->node != var)
+ {
+ varinfo_t vipt = get_varinfo (vi->node);
+ fprintf (file, "%s = same as %s\n", vi->name, vipt->name);
+ }
+ else
{
- fprintf (file, "%s ", get_varinfo (i)->name);
+ fprintf (file, "%s = { ", vi->name);
+ EXECUTE_IF_SET_IN_BITMAP (get_varinfo (vi->node)->solution, 0, i, bi)
+ {
+ fprintf (file, "%s ", get_varinfo (i)->name);
+ }
+ fprintf (file, "}\n");
}
- fprintf (file, "}\n");
}
/* Print the points-to solution for VAR to stdout. */
@@ -4253,7 +4156,6 @@ intra_create_variable_infos (void)
{
tree t;
struct constraint_expr lhs, rhs;
- varinfo_t nonlocal_vi;
/* For each incoming pointer argument arg, ARG = ESCAPED_VARS or a
dummy variable if flag_argument_noalias > 2. */
@@ -4296,7 +4198,7 @@ intra_create_variable_infos (void)
vi->is_artificial_var = 1;
vi->is_heap_var = 1;
rhs.var = id;
- rhs.type = ADDRESSOF;
+ rhs.type = INCLUDES;
rhs.offset = 0;
for (p = get_varinfo (lhs.var); p; p = p->next)
{
@@ -4311,28 +4213,6 @@ intra_create_variable_infos (void)
make_constraint_from_escaped (p);
}
}
- if (!nonlocal_all)
- nonlocal_all = create_nonlocal_var (void_type_node);
-
- /* Create variable info for the nonlocal var if it does not
- exist. */
- nonlocal_vars_id = create_variable_info_for (nonlocal_all,
- get_name (nonlocal_all));
- nonlocal_vi = get_varinfo (nonlocal_vars_id);
- nonlocal_vi->is_artificial_var = 1;
- nonlocal_vi->is_heap_var = 1;
- nonlocal_vi->is_unknown_size_var = 1;
- nonlocal_vi->directly_dereferenced = true;
-
- rhs.var = nonlocal_vars_id;
- rhs.type = ADDRESSOF;
- rhs.offset = 0;
-
- lhs.var = escaped_vars_id;
- lhs.type = SCALAR;
- lhs.offset = 0;
-
- process_constraint (new_constraint (lhs, rhs));
}
/* Set bits in INTO corresponding to the variable uids in solution set
@@ -4514,7 +4394,7 @@ dump_sa_points_to_info (FILE *outfile)
fprintf (outfile, "Iterations: %d\n", stats.iterations);
fprintf (outfile, "Number of edges: %d\n", stats.num_edges);
}
-
+
for (i = 0; i < VEC_length (varinfo_t, varmap); i++)
dump_solution_for_var (outfile, i);
}
@@ -4570,7 +4450,7 @@ init_base_vars (void)
lhs.type = SCALAR;
lhs.var = anything_id;
lhs.offset = 0;
- rhs.type = ADDRESSOF;
+ rhs.type = INCLUDES;
rhs.var = anything_id;
rhs.offset = 0;
var_anything->address_taken = true;
@@ -4601,7 +4481,7 @@ init_base_vars (void)
lhs.type = SCALAR;
lhs.var = readonly_id;
lhs.offset = 0;
- rhs.type = ADDRESSOF;
+ rhs.type = INCLUDES;
rhs.var = anything_id;
rhs.offset = 0;
@@ -4626,30 +4506,29 @@ init_base_vars (void)
lhs.type = SCALAR;
lhs.var = integer_id;
lhs.offset = 0;
- rhs.type = ADDRESSOF;
+ rhs.type = INCLUDES;
rhs.var = anything_id;
rhs.offset = 0;
process_constraint (new_constraint (lhs, rhs));
-
- /* Create the ESCAPED_VARS variable used to represent variables that
- escape this function. */
- escaped_vars_tree = create_tmp_var_raw (void_type_node, "ESCAPED_VARS");
- var_escaped_vars = new_var_info (escaped_vars_tree, 4, "ESCAPED_VARS", 4);
- insert_id_for_tree (escaped_vars_tree, 4);
- var_escaped_vars->is_artificial_var = 1;
- var_escaped_vars->size = ~0;
- var_escaped_vars->fullsize = ~0;
- var_escaped_vars->offset = 0;
- var_escaped_vars->next = NULL;
- escaped_vars_id = 4;
- VEC_safe_push (varinfo_t, heap, varmap, var_escaped_vars);
- /* ESCAPED_VARS = *ESCAPED_VARS */
+ if (!nonlocal_all)
+ nonlocal_all = create_nonlocal_var (void_type_node);
+
+ /* Create variable info for the nonlocal var if it does not
+ exist. */
+ nonlocal_vars_id = create_variable_info_for (nonlocal_all,
+ get_name (nonlocal_all));
+ var_nonlocal = get_varinfo (nonlocal_vars_id);
+ var_nonlocal->is_artificial_var = 1;
+ var_nonlocal->is_heap_var = 1;
+ var_nonlocal->is_unknown_size_var = 1;
+ var_nonlocal->directly_dereferenced = true;
+
lhs.type = SCALAR;
- lhs.var = escaped_vars_id;
+ lhs.var = nonlocal_vars_id;
lhs.offset = 0;
- rhs.type = DEREF;
- rhs.var = escaped_vars_id;
+ rhs.type = INCLUDES;
+ rhs.var = nonlocal_vars_id;
rhs.offset = 0;
process_constraint (new_constraint (lhs, rhs));
@@ -4678,105 +4557,6 @@ init_alias_vars (void)
init_base_vars ();
}
-/* Given a statement STMT, generate necessary constraints to
- escaped_vars for the escaping variables. */
-
-static void
-find_escape_constraints (tree stmt)
-{
- enum escape_type stmt_escape_type = is_escape_site (stmt);
- tree rhs;
- VEC(ce_s, heap) *rhsc = NULL;
- struct constraint_expr *c;
- size_t i;
-
- if (stmt_escape_type == NO_ESCAPE)
- return;
-
- if (TREE_CODE (stmt) == RETURN_EXPR)
- {
- /* Returns are either bare, with an embedded MODIFY_EXPR, or
- just a plain old expression. */
- if (!TREE_OPERAND (stmt, 0))
- return;
- if (TREE_CODE (TREE_OPERAND (stmt, 0)) == MODIFY_EXPR)
- rhs = TREE_OPERAND (TREE_OPERAND (stmt, 0), 1);
- else
- rhs = TREE_OPERAND (stmt, 0);
-
- get_constraint_for (rhs, &rhsc);
- for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
- make_constraint_to_escaped (*c);
- VEC_free (ce_s, heap, rhsc);
- return;
- }
- else if (TREE_CODE (stmt) == ASM_EXPR)
- {
- /* Whatever the inputs of the ASM are, escape. */
- tree arg;
-
- for (arg = ASM_INPUTS (stmt); arg; arg = TREE_CHAIN (arg))
- {
- rhsc = NULL;
- get_constraint_for (TREE_VALUE (arg), &rhsc);
- for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
- make_constraint_to_escaped (*c);
- VEC_free (ce_s, heap, rhsc);
- }
- return;
- }
- else if (TREE_CODE (stmt) == CALL_EXPR
- || (TREE_CODE (stmt) == MODIFY_EXPR
- && TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
- {
- /* Calls cause all of the arguments passed in to escape. */
- tree arg;
-
- if (TREE_CODE (stmt) == MODIFY_EXPR)
- stmt = TREE_OPERAND (stmt, 1);
- for (arg = TREE_OPERAND (stmt, 1); arg; arg = TREE_CHAIN (arg))
- {
- if (POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (arg))))
- {
- rhsc = NULL;
- get_constraint_for (TREE_VALUE (arg), &rhsc);
- for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
- make_constraint_to_escaped (*c);
- VEC_free (ce_s, heap, rhsc);
- }
- }
- return;
- }
- else
- {
- gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR);
- }
-
- gcc_assert (stmt_escape_type == ESCAPE_BAD_CAST
- || stmt_escape_type == ESCAPE_STORED_IN_GLOBAL
- || stmt_escape_type == ESCAPE_UNKNOWN);
- rhs = TREE_OPERAND (stmt, 1);
-
- /* Look through casts for the real escaping variable.
- Constants don't really escape, so ignore them.
- Otherwise, whatever escapes must be on our RHS. */
- if (TREE_CODE (rhs) == NOP_EXPR
- || TREE_CODE (rhs) == CONVERT_EXPR
- || TREE_CODE (rhs) == NON_LVALUE_EXPR)
- {
- get_constraint_for (TREE_OPERAND (rhs, 0), &rhsc);
- }
- else if (CONSTANT_CLASS_P (rhs))
- return;
- else
- {
- get_constraint_for (rhs, &rhsc);
- }
- for (i = 0; VEC_iterate (ce_s, rhsc, i, c); i++)
- make_constraint_to_escaped (*c);
- VEC_free (ce_s, heap, rhsc);
-}
-
/* Create points-to sets for the current function. See the comments
at the start of the file for an algorithmic overview. */
@@ -4815,7 +4595,6 @@ compute_points_to_sets (struct alias_inf
tree stmt = bsi_stmt (bsi);
find_func_aliases (stmt);
- find_escape_constraints (stmt);
/* Update various related attributes like escaped
addresses, pointer dereferences for loads and stores.
This is used when creating name tags and alias
@@ -4869,10 +4648,6 @@ delete_points_to_sets (void)
for (i = 0; VEC_iterate (varinfo_t, varmap, i, v); i++)
{
- /* Nonlocal vars may add more varinfos. */
- if (i >= graph_size)
- break;
-
VEC_free (constraint_edge_t, heap, graph->succs[i]);
VEC_free (constraint_edge_t, heap, graph->preds[i]);
VEC_free (constraint_t, heap, v->complex);
Property changes on:
___________________________________________________________________
Name: svk:merge
+138bc75d-0d04-0410-961f-82ee72b054a4:/trunk:119018
+7dca8dba-45c1-47dc-8958-1a7301c5ed47:/local-gcc/md-constraint:113709
+f367781f-d768-471e-ba66-e306e17dff77:/local/gen-rework-20060122:110130
More information about the Gcc-patches
mailing list