Revert accidental commit (patch coming for this :P)

From-SVN: r119113
This commit is contained in:
Daniel Berlin 2006-11-23 02:19:39 +00:00
parent 78ab22b9d3
commit f71ef09df3
1 changed files with 544 additions and 114 deletions

View File

@ -434,14 +434,53 @@ struct constraint
static VEC(constraint_t,heap) *constraints;
static alloc_pool constraint_pool;
/* An edge in the weighted constraint graph. The edges are weighted,
with a bit set in weights meaning their is an edge with that
weight.
We don't keep the src in the edge, because we always know what it
is. */
/* The constraint graph is represented as an array of bitmaps
containing successor nodes. */
struct constraint_edge
{
unsigned int dest;
bitmap weights;
};
typedef struct constraint_edge *constraint_edge_t;
static alloc_pool constraint_edge_pool;
/* Return a new constraint edge from SRC to DEST. */
static constraint_edge_t
new_constraint_edge (unsigned int dest)
{
constraint_edge_t ret = pool_alloc (constraint_edge_pool);
ret->dest = dest;
ret->weights = NULL;
return ret;
}
DEF_VEC_P(constraint_edge_t);
DEF_VEC_ALLOC_P(constraint_edge_t,heap);
/* The constraint graph is represented internally in two different
ways. The overwhelming majority of edges in the constraint graph
are zero weigh edges, and thus, using a vector of contrainst_edge_t
is a waste of time and memory, since they have no weights. We
simply use a bitmap to store the preds and succs for each node.
The weighted edges are stored as a set of adjacency vectors, one
per variable. succs[x] is the vector of successors for variable x,
and preds[x] is the vector of predecessors for variable x. IOW,
all edges are "forward" edges, which is not like our CFG. So
remember that preds[x]->src == x, and succs[x]->src == x. */
struct constraint_graph
{
bitmap *succs;
bitmap *preds;
bitmap *zero_weight_succs;
bitmap *zero_weight_preds;
VEC(constraint_edge_t,heap) **succs;
VEC(constraint_edge_t,heap) **preds;
};
typedef struct constraint_graph *constraint_graph_t;
@ -700,6 +739,44 @@ insert_into_complex (unsigned int var, constraint_t c)
}
/* Compare two constraint edges A and B, return true if they are equal. */
static bool
constraint_edge_equal (struct constraint_edge a, struct constraint_edge b)
{
return a.dest == b.dest;
}
/* Compare two constraint edges, return true if A is less than B */
static bool
constraint_edge_less (const constraint_edge_t a, const constraint_edge_t b)
{
if (a->dest < b->dest)
return true;
return false;
}
/* Find the constraint edge that matches LOOKFOR, in VEC.
Return the edge, if found, NULL otherwise. */
static constraint_edge_t
constraint_edge_vec_find (VEC(constraint_edge_t,heap) *vec,
struct constraint_edge lookfor)
{
unsigned int place;
constraint_edge_t edge = NULL;
place = VEC_lower_bound (constraint_edge_t, vec, &lookfor,
constraint_edge_less);
if (place >= VEC_length (constraint_edge_t, vec))
return NULL;
edge = VEC_index (constraint_edge_t, vec, place);
if (!constraint_edge_equal (*edge, lookfor))
return NULL;
return edge;
}
/* Condense two variable nodes into a single variable node, by moving
all associated info from SRC to TO. */
@ -738,43 +815,206 @@ condense_varmap_nodes (unsigned int to, unsigned int src)
srcvi->complex = NULL;
}
/* Erase an edge from SRC to SRC from GRAPH. This routine only
handles self-edges (e.g. an edge from a to a). */
static void
erase_graph_self_edge (constraint_graph_t graph, unsigned int src)
{
VEC(constraint_edge_t,heap) *predvec = graph->preds[src];
VEC(constraint_edge_t,heap) *succvec = graph->succs[src];
struct constraint_edge edge;
unsigned int place;
edge.dest = src;
/* Remove from the successors. */
place = VEC_lower_bound (constraint_edge_t, succvec, &edge,
constraint_edge_less);
/* Make sure we found the edge. */
#ifdef ENABLE_CHECKING
{
constraint_edge_t tmp = VEC_index (constraint_edge_t, succvec, place);
gcc_assert (constraint_edge_equal (*tmp, edge));
}
#endif
VEC_ordered_remove (constraint_edge_t, succvec, place);
/* Remove from the predecessors. */
place = VEC_lower_bound (constraint_edge_t, predvec, &edge,
constraint_edge_less);
/* Make sure we found the edge. */
#ifdef ENABLE_CHECKING
{
constraint_edge_t tmp = VEC_index (constraint_edge_t, predvec, place);
gcc_assert (constraint_edge_equal (*tmp, edge));
}
#endif
VEC_ordered_remove (constraint_edge_t, predvec, place);
}
/* Remove edges involving NODE from GRAPH. */
static void
clear_edges_for_node (constraint_graph_t graph, unsigned int node)
{
VEC(constraint_edge_t,heap) *succvec = graph->succs[node];
VEC(constraint_edge_t,heap) *predvec = graph->preds[node];
bitmap_iterator bi;
unsigned int j;
constraint_edge_t c = NULL;
int i;
/* Walk the successors, erase the associated preds. */
EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[node], 0, j, bi)
EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_succs[node], 0, j, bi)
if (j != node)
bitmap_clear_bit (graph->preds[j], node);
bitmap_clear_bit (graph->zero_weight_preds[j], node);
for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
if (c->dest != node)
{
unsigned int place;
struct constraint_edge lookfor;
constraint_edge_t result;
lookfor.dest = node;
place = VEC_lower_bound (constraint_edge_t, graph->preds[c->dest],
&lookfor, constraint_edge_less);
result = VEC_ordered_remove (constraint_edge_t,
graph->preds[c->dest], place);
pool_free (constraint_edge_pool, result);
}
/* Walk the preds, erase the associated succs. */
EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[node], 0, j, bi)
EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_preds[node], 0, j, bi)
if (j != node)
bitmap_clear_bit (graph->succs[j], node);
bitmap_clear_bit (graph->zero_weight_succs[j], node);
for (i =0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
if (c->dest != node)
{
unsigned int place;
struct constraint_edge lookfor;
constraint_edge_t result;
if (graph->preds[node])
lookfor.dest = node;
place = VEC_lower_bound (constraint_edge_t, graph->succs[c->dest],
&lookfor, constraint_edge_less);
result = VEC_ordered_remove (constraint_edge_t,
graph->succs[c->dest], place);
pool_free (constraint_edge_pool, result);
}
if (graph->zero_weight_preds[node])
{
BITMAP_FREE (graph->preds[node]);
graph->preds[node] = NULL;
BITMAP_FREE (graph->zero_weight_preds[node]);
graph->zero_weight_preds[node] = NULL;
}
if (graph->succs[node])
if (graph->zero_weight_succs[node])
{
BITMAP_FREE (graph->succs[node]);
graph->succs[node] = NULL;
}
BITMAP_FREE (graph->zero_weight_succs[node]);
graph->zero_weight_succs[node] = NULL;
}
VEC_free (constraint_edge_t, heap, graph->preds[node]);
VEC_free (constraint_edge_t, heap, graph->succs[node]);
graph->preds[node] = NULL;
graph->succs[node] = NULL;
}
static bool edge_added = false;
/* Add edge (src, dest) to the graph. */
static bool
add_graph_edge (constraint_graph_t graph, unsigned int src, unsigned int dest)
{
unsigned int place;
VEC(constraint_edge_t,heap) *vec;
struct constraint_edge newe;
newe.dest = dest;
vec = graph->preds[src];
place = VEC_lower_bound (constraint_edge_t, vec, &newe,
constraint_edge_less);
if (place == VEC_length (constraint_edge_t, vec)
|| VEC_index (constraint_edge_t, vec, place)->dest != dest)
{
constraint_edge_t edge = new_constraint_edge (dest);
VEC_safe_insert (constraint_edge_t, heap, graph->preds[src],
place, edge);
edge = new_constraint_edge (src);
place = VEC_lower_bound (constraint_edge_t, graph->succs[dest],
edge, constraint_edge_less);
VEC_safe_insert (constraint_edge_t, heap, graph->succs[dest],
place, edge);
edge_added = true;
stats.num_edges++;
return true;
}
else
return false;
}
/* Return the bitmap representing the weights of edge (SRC, DEST). */
static bitmap *
get_graph_weights (constraint_graph_t graph, unsigned int src,
unsigned int dest)
{
constraint_edge_t edge;
VEC(constraint_edge_t,heap) *vec;
struct constraint_edge lookfor;
lookfor.dest = dest;
vec = graph->preds[src];
edge = constraint_edge_vec_find (vec, lookfor);
gcc_assert (edge != NULL);
return &edge->weights;
}
/* Allocate graph weight bitmap for the edges associated with SRC and
DEST in GRAPH. Both the pred and the succ edges share a single
bitmap, so we need to set both edges to that bitmap. */
static bitmap
allocate_graph_weights (constraint_graph_t graph, unsigned int src,
unsigned int dest)
{
bitmap result;
constraint_edge_t edge;
VEC(constraint_edge_t,heap) *vec;
struct constraint_edge lookfor;
result = BITMAP_ALLOC (&ptabitmap_obstack);
/* Set the pred weight. */
lookfor.dest = dest;
vec = graph->preds[src];
edge = constraint_edge_vec_find (vec, lookfor);
gcc_assert (edge != NULL);
edge->weights = result;
/* Set the succ weight. */
lookfor.dest = src;
vec = graph->succs[dest];
edge = constraint_edge_vec_find (vec, lookfor);
gcc_assert (edge != NULL);
edge->weights = result;
return result;
}
/* Merge GRAPH nodes FROM and TO into node TO. */
@ -782,72 +1022,144 @@ static void
merge_graph_nodes (constraint_graph_t graph, unsigned int to,
unsigned int from)
{
VEC(constraint_edge_t,heap) *succvec = graph->succs[from];
VEC(constraint_edge_t,heap) *predvec = graph->preds[from];
int i;
constraint_edge_t c;
unsigned int j;
bitmap_iterator bi;
/* Merge all the predecessor edges. */
if (graph->preds[from])
/* Merge all the zero weighted predecessor edges. */
if (graph->zero_weight_preds[from])
{
if (!graph->preds[to])
graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
if (!graph->zero_weight_preds[to])
graph->zero_weight_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
EXECUTE_IF_SET_IN_BITMAP (graph->preds[from], 0, j, bi)
EXECUTE_IF_SET_IN_BITMAP (graph->zero_weight_preds[from], 0, j, bi)
{
if (j != to)
{
bitmap_clear_bit (graph->succs[j], from);
bitmap_set_bit (graph->succs[j], to);
bitmap_clear_bit (graph->zero_weight_succs[j], from);
bitmap_set_bit (graph->zero_weight_succs[j], to);
}
}
bitmap_ior_into (graph->preds[to],
graph->preds[from]);
bitmap_ior_into (graph->zero_weight_preds[to],
graph->zero_weight_preds[from]);
}
/* Merge all the successor edges. */
if (graph->succs[from])
/* Merge all the zero weighted successor edges. */
if (graph->zero_weight_succs[from])
{
if (!graph->succs[to])
graph->succs[to] = BITMAP_ALLOC (&ptabitmap_obstack);
EXECUTE_IF_SET_IN_BITMAP (graph->succs[from], 0, j, bi)
if (!graph->zero_weight_succs[to])
graph->zero_weight_succs[to] = BITMAP_ALLOC (&ptabitmap_obstack);
EXECUTE_IF_SET_IN_BITMAP (graph->zero_weight_succs[from], 0, j, bi)
{
bitmap_clear_bit (graph->preds[j], from);
bitmap_set_bit (graph->preds[j], to);
bitmap_clear_bit (graph->zero_weight_preds[j], from);
bitmap_set_bit (graph->zero_weight_preds[j], to);
}
bitmap_ior_into (graph->succs[to],
graph->succs[from]);
bitmap_ior_into (graph->zero_weight_succs[to],
graph->zero_weight_succs[from]);
}
/* Merge all the nonzero weighted predecessor edges. */
for (i = 0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
{
unsigned int d = c->dest;
bitmap temp;
bitmap *weights;
if (c->dest == from)
d = to;
add_graph_edge (graph, to, d);
temp = *(get_graph_weights (graph, from, c->dest));
if (temp)
{
weights = get_graph_weights (graph, to, d);
if (!*weights)
*weights = allocate_graph_weights (graph, to, d);
bitmap_ior_into (*weights, temp);
}
}
/* Merge all the nonzero weighted successor edges. */
for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
{
unsigned int d = c->dest;
bitmap temp;
bitmap *weights;
if (c->dest == from)
d = to;
add_graph_edge (graph, d, to);
temp = *(get_graph_weights (graph, c->dest, from));
if (temp)
{
weights = get_graph_weights (graph, d, to);
if (!*weights)
*weights = allocate_graph_weights (graph, d, to);
bitmap_ior_into (*weights, temp);
}
}
clear_edges_for_node (graph, from);
}
/* Add a graph edge to GRAPH, going from TO to FROM if
/* Add a graph edge to GRAPH, going from TO to FROM, with WEIGHT, if
it doesn't exist in the graph already.
Return false if the edge already existed, true otherwise. */
static bool
add_graph_edge (constraint_graph_t graph, unsigned int to,
unsigned int from)
int_add_graph_edge (constraint_graph_t graph, unsigned int to,
unsigned int from, unsigned HOST_WIDE_INT weight)
{
if (to == from)
if (to == from && weight == 0)
{
return false;
}
else
{
bool r = false;
if (!graph->preds[to])
graph->preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
if (!graph->succs[from])
graph->succs[from] = BITMAP_ALLOC (&ptabitmap_obstack);
if (!bitmap_bit_p (graph->succs[from], to))
if (weight == 0)
{
edge_added = true;
r = true;
stats.num_edges++;
bitmap_set_bit (graph->preds[to], from);
bitmap_set_bit (graph->succs[from], to);
if (!graph->zero_weight_preds[to])
graph->zero_weight_preds[to] = BITMAP_ALLOC (&predbitmap_obstack);
if (!graph->zero_weight_succs[from])
graph->zero_weight_succs[from] = BITMAP_ALLOC (&ptabitmap_obstack);
if (!bitmap_bit_p (graph->zero_weight_succs[from], to))
{
edge_added = true;
r = true;
stats.num_edges++;
bitmap_set_bit (graph->zero_weight_preds[to], from);
bitmap_set_bit (graph->zero_weight_succs[from], to);
}
}
else
{
bitmap *weights;
r = add_graph_edge (graph, to, from);
weights = get_graph_weights (graph, to, from);
if (!*weights)
{
r = true;
*weights = allocate_graph_weights (graph, to, from);
bitmap_set_bit (*weights, weight);
}
else
{
r |= !bitmap_bit_p (*weights, weight);
bitmap_set_bit (*weights, weight);
}
}
return r;
}
}
@ -859,10 +1171,28 @@ static bool
valid_graph_edge (constraint_graph_t graph, unsigned int src,
unsigned int dest)
{
return (graph->succs[dest]
&& bitmap_bit_p (graph->succs[dest], src));
struct constraint_edge lookfor;
lookfor.dest = src;
return (graph->zero_weight_succs[dest]
&& bitmap_bit_p (graph->zero_weight_succs[dest], src))
|| constraint_edge_vec_find (graph->succs[dest], lookfor) != NULL;
}
/* Return true if {DEST, SRC} is an existing weighted graph edge (IE has
a weight other than 0) in GRAPH. */
static bool
valid_weighted_graph_edge (constraint_graph_t graph, unsigned int src,
unsigned int dest)
{
struct constraint_edge lookfor;
lookfor.dest = src;
return graph->preds[src]
&& constraint_edge_vec_find (graph->succs[dest], lookfor) != NULL;
}
/* Build the constraint graph. */
static void
@ -873,8 +1203,10 @@ build_constraint_graph (void)
graph = XNEW (struct constraint_graph);
graph_size = VEC_length (varinfo_t, varmap) + 1;
graph->succs = XCNEWVEC (bitmap, graph_size);
graph->preds = XCNEWVEC (bitmap, graph_size);
graph->succs = XCNEWVEC (VEC(constraint_edge_t,heap) *, graph_size);
graph->preds = XCNEWVEC (VEC(constraint_edge_t,heap) *, graph_size);
graph->zero_weight_succs = XCNEWVEC (bitmap, graph_size);
graph->zero_weight_preds = XCNEWVEC (bitmap, graph_size);
for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++)
{
@ -902,14 +1234,12 @@ build_constraint_graph (void)
}
else if (lhsvar > anything_id)
{
/* Ignore self edges, as they can't possibly contribute
/* Ignore 0 weighted self edges, as they can't possibly contribute
anything */
if (lhsvar != rhsvar || rhs.offset != 0 || lhs.offset != 0)
{
if (rhs.offset != 0 || lhs.offset != 0)
insert_into_complex (lhsvar, c);
else
add_graph_edge (graph, lhs.var, rhs.var);
/* x = y (simple) */
int_add_graph_edge (graph, lhs.var, rhs.var, rhs.offset);
}
}
@ -961,7 +1291,7 @@ scc_visit (constraint_graph_t graph, struct scc_info *si, unsigned int n)
si->visited_index[n] = si->current_index ++;
/* Visit all the successors. */
EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[n], 0, i, bi)
EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_succs[n], 0, i, bi)
{
unsigned int w = i;
if (!TEST_BIT (si->visited, w))
@ -1010,10 +1340,16 @@ collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from)
if (valid_graph_edge (graph, to, to))
{
if (graph->preds[to])
if (graph->zero_weight_preds[to])
{
bitmap_clear_bit (graph->preds[to], to);
bitmap_clear_bit (graph->succs[to], 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));
if (!weights || bitmap_empty_p (weights))
erase_graph_self_edge (graph, to);
}
}
BITMAP_FREE (fromsol);
@ -1058,7 +1394,7 @@ process_unification_queue (constraint_graph_t graph, struct scc_info *si,
Merge tmp into solution for rep, marking rep changed if this
changed rep's solution.
Delete any self-edges we now have for rep. */
Delete any 0 weighted self-edges we now have for rep. */
while (i != VEC_length (unsigned, si->unification_queue))
{
unsigned int tounify = VEC_index (unsigned, si->unification_queue, i);
@ -1111,11 +1447,17 @@ process_unification_queue (constraint_graph_t graph, struct scc_info *si,
if (valid_graph_edge (graph, n, n))
{
if (graph->succs[n])
if (graph->zero_weight_succs[n])
{
if (graph->preds[n])
bitmap_clear_bit (graph->preds[n], n);
bitmap_clear_bit (graph->succs[n], 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);
}
}
}
@ -1167,12 +1509,24 @@ static void
topo_visit (constraint_graph_t graph, struct topo_info *ti,
unsigned int n)
{
VEC(constraint_edge_t,heap) *succs = graph->succs[n];
bitmap temp;
bitmap_iterator bi;
constraint_edge_t c;
int i;
unsigned int j;
SET_BIT (ti->visited, n);
temp = graph->succs[n];
if (VEC_length (constraint_edge_t, succs) != 0)
{
temp = BITMAP_ALLOC (&iteration_obstack);
if (graph->zero_weight_succs[n])
bitmap_ior_into (temp, graph->zero_weight_succs[n]);
for (i = 0; VEC_iterate (constraint_edge_t, succs, i, c); i++)
bitmap_set_bit (temp, c->dest);
}
else
temp = graph->zero_weight_succs[n];
if (temp)
EXECUTE_IF_SET_IN_BITMAP (temp, 0, j, bi)
@ -1286,7 +1640,7 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
They don't have sets that can change. */
if (get_varinfo (t) ->is_special_var)
flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
else if (add_graph_edge (graph, lhs, t))
else if (int_add_graph_edge (graph, lhs, t, 0))
flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
}
else if (0 && dump_file && !(get_varinfo (j)->is_special_var))
@ -1310,7 +1664,7 @@ done:
/* Process a constraint C that represents *x = y. */
static void
do_ds_constraint (constraint_t c, bitmap delta)
do_ds_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
{
unsigned int rhs = get_varinfo (c->rhs.var)->node;
unsigned HOST_WIDE_INT roff = c->rhs.offset;
@ -1356,26 +1710,27 @@ do_ds_constraint (constraint_t c, bitmap delta)
varinfo_t v;
unsigned int t;
unsigned HOST_WIDE_INT fieldoffset = get_varinfo (j)->offset + loff;
bitmap tmp;
v = first_vi_for_offset (get_varinfo (j), fieldoffset);
if (!v)
continue;
t = v->node;
tmp = get_varinfo (t)->solution;
if (set_union_with_increment (tmp, sol, roff))
if (int_add_graph_edge (graph, t, rhs, roff))
{
get_varinfo (t)->solution = tmp;
if (t == rhs)
sol = get_varinfo (rhs)->solution;
if (!TEST_BIT (changed, t))
bitmap tmp = get_varinfo (t)->solution;
if (set_union_with_increment (tmp, sol, roff))
{
SET_BIT (changed, t);
changed_count++;
get_varinfo (t)->solution = tmp;
if (t == rhs)
sol = get_varinfo (rhs)->solution;
if (!TEST_BIT (changed, t))
{
SET_BIT (changed, t);
changed_count++;
}
}
}
}
}
else if (0 && dump_file && !(get_varinfo (j)->is_special_var))
fprintf (dump_file, "Untypesafe usage in do_ds_constraint\n");
}
@ -1397,40 +1752,15 @@ do_complex_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
else
{
/* *x = y */
do_ds_constraint (c, delta);
do_ds_constraint (graph, c, delta);
}
}
else if (c->rhs.type == DEREF)
else
{
/* x = *y */
if (!(get_varinfo (c->lhs.var)->is_special_var))
do_sd_constraint (graph, c, delta);
}
else
{
bitmap tmp;
bitmap solution;
bool flag = false;
unsigned int t;
gcc_assert(c->rhs.type == SCALAR && c->lhs.type == SCALAR);
t = get_varinfo (c->rhs.var)->node;
solution = get_varinfo (t)->solution;
t = get_varinfo (c->lhs.var)->node;
tmp = get_varinfo (t)->solution;
flag = set_union_with_increment (tmp, solution, c->rhs.offset);
if (flag)
{
get_varinfo (t)->solution = tmp;
if (!TEST_BIT (changed, c->lhs.var))
{
SET_BIT (changed, c->lhs.var);
changed_count++;
}
}
}
}
/* Initialize and return a new SCC info structure. */
@ -1501,6 +1831,21 @@ compute_topo_order (constraint_graph_t graph,
topo_visit (graph, ti, i);
}
/* Return true if bitmap B is empty, or a bitmap other than bit 0 is set. */
static bool
bitmap_other_than_zero_bit_set (bitmap b)
{
unsigned int i;
bitmap_iterator bi;
if (bitmap_empty_p (b))
return false;
EXECUTE_IF_SET_IN_BITMAP (b, 1, i, bi)
return true;
return false;
}
/* Perform offline variable substitution.
This is a linear time way of identifying variables that must have
@ -1524,9 +1869,12 @@ perform_var_substitution (constraint_graph_t graph)
while (VEC_length (unsigned, ti->topo_order) != 0)
{
unsigned int i = VEC_pop (unsigned, ti->topo_order);
unsigned int pred;
varinfo_t vi = get_varinfo (i);
bool okay_to_elim = false;
unsigned int root = VEC_length (varinfo_t, varmap);
VEC(constraint_edge_t,heap) *predvec = graph->preds[i];
constraint_edge_t ce = NULL;
bitmap tmp;
unsigned int k;
bitmap_iterator bi;
@ -1537,7 +1885,7 @@ perform_var_substitution (constraint_graph_t graph)
continue;
/* See if all predecessors of I are ripe for elimination */
EXECUTE_IF_IN_NONNULL_BITMAP (graph->preds[i], 0, k, bi)
EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_preds[i], 0, k, bi)
{
unsigned int w;
w = get_varinfo (k)->node;
@ -1573,6 +1921,55 @@ perform_var_substitution (constraint_graph_t graph)
BITMAP_FREE (tmp);
}
if (okay_to_elim)
for (pred = 0;
VEC_iterate (constraint_edge_t, predvec, pred, ce);
pred++)
{
bitmap weight;
unsigned int w;
weight = *(get_graph_weights (graph, i, ce->dest));
/* We can't eliminate variables that have nonzero weighted
edges between them. */
if (weight && bitmap_other_than_zero_bit_set (weight))
{
okay_to_elim = false;
break;
}
w = get_varinfo (ce->dest)->node;
/* We can't eliminate the node if one of the predecessors is
part of a different strongly connected component. */
if (!okay_to_elim)
{
root = w;
okay_to_elim = true;
}
else if (w != root)
{
okay_to_elim = false;
break;
}
/* Theorem 4 in Rountev and Chandra: If i is a direct node,
then Solution(i) is a subset of Solution (w), where w is a
predecessor in the graph.
Corollary: If all predecessors of i have the same
points-to set, then i has that same points-to set as
those predecessors. */
tmp = BITMAP_ALLOC (NULL);
bitmap_and_compl (tmp, get_varinfo (i)->solution,
get_varinfo (w)->solution);
if (!bitmap_empty_p (tmp))
{
okay_to_elim = false;
BITMAP_FREE (tmp);
break;
}
BITMAP_FREE (tmp);
}
/* See if the root is different than the original node.
If so, we've found an equivalence. */
if (root != get_varinfo (i)->node && okay_to_elim)
@ -1647,9 +2044,11 @@ solve_graph (constraint_graph_t graph)
{
unsigned int j;
constraint_t c;
constraint_edge_t e = NULL;
bitmap solution;
bitmap_iterator bi;
VEC(constraint_t,heap) *complex = get_varinfo (i)->complex;
VEC(constraint_edge_t,heap) *succs;
bool solution_empty;
RESET_BIT (changed, i);
@ -1674,14 +2073,14 @@ solve_graph (constraint_graph_t graph)
if (!solution_empty)
{
/* Propagate solution to all successors. */
EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i],
succs = graph->succs[i];
EXECUTE_IF_IN_NONNULL_BITMAP (graph->zero_weight_succs[i],
0, j, bi)
{
bitmap tmp = get_varinfo (j)->solution;
bool flag = false;
gcc_assert (get_varinfo (j)->node == j);
flag = set_union_with_increment (tmp, solution, 0);
if (flag)
@ -1694,13 +2093,35 @@ solve_graph (constraint_graph_t graph)
}
}
}
for (j = 0; VEC_iterate (constraint_edge_t, succs, j, e); j++)
{
bitmap tmp = get_varinfo (e->dest)->solution;
bool flag = false;
unsigned int k;
bitmap weights = e->weights;
bitmap_iterator bi;
gcc_assert (weights && !bitmap_empty_p (weights));
EXECUTE_IF_SET_IN_BITMAP (weights, 0, k, bi)
flag |= set_union_with_increment (tmp, solution, k);
if (flag)
{
get_varinfo (e->dest)->solution = tmp;
if (!TEST_BIT (changed, e->dest))
{
SET_BIT (changed, e->dest);
changed_count++;
}
}
}
}
}
}
free_topo_info (ti);
bitmap_obstack_release (&iteration_obstack);
}
sbitmap_free (changed);
}
@ -4246,6 +4667,9 @@ init_alias_vars (void)
sizeof (struct constraint), 30);
variable_info_pool = create_alloc_pool ("Variable info pool",
sizeof (struct variable_info), 30);
constraint_edge_pool = create_alloc_pool ("Constraint edges",
sizeof (struct constraint_edge), 30);
constraints = VEC_alloc (constraint_t, heap, 8);
varmap = VEC_alloc (varinfo_t, heap, 8);
id_for_tree = htab_create (10, tree_id_hash, tree_id_eq, free);
@ -4449,15 +4873,21 @@ delete_points_to_sets (void)
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);
}
free (graph->preds);
free (graph->zero_weight_preds);
free (graph->zero_weight_succs);
free (graph->succs);
free (graph->preds);
free (graph);
VEC_free (varinfo_t, heap, varmap);
free_alloc_pool (variable_info_pool);
free_alloc_pool (constraint_pool);
free_alloc_pool (constraint_edge_pool);
have_alias_info = false;
}