tree-ssanames.c (make_ssa_name): No longer need to clear, then initialize key elements here.
* tree-ssanames.c (make_ssa_name): No longer need to clear, then initialize key elements here. (release_ssa_name): Zero the released SSA_NAME here. * tree.h (SSA_NAME_EQUIV, SET_SSA_NAME_EQUIV): New macros. (struct tree_ssa_name): Add new "equiv" field. * tree-ssa-dom.c (const_and_copies): Kill the global varray. (tree_ssa_dominator_optimize): No longer allocate, resize or clear CONST_AND_COPIES. (get_value_for, set_value_for): Kill. (thread_across_edge): Get/set the equivalency using SSA_NAME_EQUIV and SET_SSA_NAME_EQUIV. (restore_vars_to_original_value): Likewise. (record_equivalences_from_phis): Likewise. (record_dominating_conditions): Likewise. (record_const_or_copy, record_equality): Likewise. (lookup_avail_expr): Likewise. (record_equivalences_from_stmt, cprop_operand): Likewise. (cprop_into_successor_phis): No longer need to pass around CONST_AND_COPIES. Callers updated. Get equivalences via SSA_NAME_EQUIV. (cprop_into_phis): Likewise. Co-Authored-By: Jan Hubicka <jh@suse.cz> From-SVN: r87787
This commit is contained in:
parent
c162c75e43
commit
6f2aec072e
4 changed files with 86 additions and 73 deletions
|
@ -1,3 +1,28 @@
|
|||
2004-09-20 Jeff Law <law@redhat.com>
|
||||
Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree-ssanames.c (make_ssa_name): No longer need to clear, then
|
||||
initialize key elements here.
|
||||
(release_ssa_name): Zero the released SSA_NAME here.
|
||||
* tree.h (SSA_NAME_EQUIV, SET_SSA_NAME_EQUIV): New macros.
|
||||
(struct tree_ssa_name): Add new "equiv" field.
|
||||
* tree-ssa-dom.c (const_and_copies): Kill the global varray.
|
||||
(tree_ssa_dominator_optimize): No longer allocate, resize or
|
||||
clear CONST_AND_COPIES.
|
||||
(get_value_for, set_value_for): Kill.
|
||||
(thread_across_edge): Get/set the equivalency using
|
||||
SSA_NAME_EQUIV and SET_SSA_NAME_EQUIV.
|
||||
(restore_vars_to_original_value): Likewise.
|
||||
(record_equivalences_from_phis): Likewise.
|
||||
(record_dominating_conditions): Likewise.
|
||||
(record_const_or_copy, record_equality): Likewise.
|
||||
(lookup_avail_expr): Likewise.
|
||||
(record_equivalences_from_stmt, cprop_operand): Likewise.
|
||||
(cprop_into_successor_phis): No longer need to pass around
|
||||
CONST_AND_COPIES. Callers updated. Get equivalences via
|
||||
SSA_NAME_EQUIV.
|
||||
(cprop_into_phis): Likewise.
|
||||
|
||||
2004-09-20 Matt Austern <austern@apple.com>
|
||||
Zack Weinberg <zack@codesourcery.com>
|
||||
|
||||
|
|
|
@ -109,16 +109,6 @@ struct expr_hash_elt
|
|||
hashval_t hash;
|
||||
};
|
||||
|
||||
/* Table of constant values and copies indexed by SSA name. When the
|
||||
renaming pass finds an assignment of a constant (X_i = C) or a copy
|
||||
assignment from another SSA variable (X_i = Y_j), it creates a mapping
|
||||
between X_i and the RHS in this table. This mapping is used later on,
|
||||
when renaming uses of X_i. If an assignment to X_i is found in this
|
||||
table, instead of using X_i, we use the RHS of the statement stored in
|
||||
this table (thus performing very simplistic copy and constant
|
||||
propagation). */
|
||||
static varray_type const_and_copies;
|
||||
|
||||
/* Stack of dest,src pairs that need to be restored during finalization.
|
||||
|
||||
A NULL entry is used to mark the end of pairs which need to be
|
||||
|
@ -229,8 +219,6 @@ struct eq_expr_value
|
|||
static void optimize_stmt (struct dom_walk_data *,
|
||||
basic_block bb,
|
||||
block_stmt_iterator);
|
||||
static inline tree get_value_for (tree, varray_type table);
|
||||
static inline void set_value_for (tree, tree, varray_type table);
|
||||
static tree lookup_avail_expr (tree, bool);
|
||||
static struct eq_expr_value get_eq_expr_value (tree, int, basic_block);
|
||||
static hashval_t avail_expr_hash (const void *);
|
||||
|
@ -281,22 +269,6 @@ local_fold (tree t)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* Return the value associated with variable VAR in TABLE. */
|
||||
|
||||
static inline tree
|
||||
get_value_for (tree var, varray_type table)
|
||||
{
|
||||
return VARRAY_TREE (table, SSA_NAME_VERSION (var));
|
||||
}
|
||||
|
||||
/* Associate VALUE to variable VAR in TABLE. */
|
||||
|
||||
static inline void
|
||||
set_value_for (tree var, tree value, varray_type table)
|
||||
{
|
||||
VARRAY_TREE (table, SSA_NAME_VERSION (var)) = value;
|
||||
}
|
||||
|
||||
/* Jump threading, redundancy elimination and const/copy propagation.
|
||||
|
||||
This pass may expose new symbols that need to be renamed into SSA. For
|
||||
|
@ -321,7 +293,6 @@ tree_ssa_dominator_optimize (void)
|
|||
avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
|
||||
VARRAY_TREE_INIT (avail_exprs_stack, 20, "Available expression stack");
|
||||
VARRAY_TREE_INIT (block_defs_stack, 20, "Block DEFS stack");
|
||||
VARRAY_TREE_INIT (const_and_copies, num_ssa_names, "const_and_copies");
|
||||
VARRAY_TREE_INIT (const_and_copies_stack, 20, "Block const_and_copies stack");
|
||||
VARRAY_TREE_INIT (nonzero_vars_stack, 20, "Block nonzero_vars stack");
|
||||
VARRAY_TREE_INIT (vrp_variables_stack, 20, "Block vrp_variables stack");
|
||||
|
@ -392,16 +363,12 @@ tree_ssa_dominator_optimize (void)
|
|||
|
||||
rewrite_ssa_into_ssa ();
|
||||
|
||||
if (VARRAY_ACTIVE_SIZE (const_and_copies) <= num_ssa_names)
|
||||
{
|
||||
VARRAY_GROW (const_and_copies, num_ssa_names);
|
||||
VARRAY_GROW (vrp_data, num_ssa_names);
|
||||
}
|
||||
if (VARRAY_ACTIVE_SIZE (vrp_data) <= num_ssa_names)
|
||||
VARRAY_GROW (vrp_data, num_ssa_names);
|
||||
|
||||
/* Reinitialize the various tables. */
|
||||
bitmap_clear (nonzero_vars);
|
||||
htab_empty (avail_exprs);
|
||||
VARRAY_CLEAR (const_and_copies);
|
||||
VARRAY_CLEAR (vrp_data);
|
||||
|
||||
for (i = 0; i < num_referenced_vars; i++)
|
||||
|
@ -525,7 +492,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
|
||||
uses_copy[i] = USE_OP (uses, i);
|
||||
if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME)
|
||||
tmp = get_value_for (USE_OP (uses, i), const_and_copies);
|
||||
tmp = SSA_NAME_EQUIV (USE_OP (uses, i));
|
||||
if (tmp)
|
||||
SET_USE_OP (uses, i, tmp);
|
||||
}
|
||||
|
@ -537,7 +504,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
|
||||
vuses_copy[i] = VUSE_OP (vuses, i);
|
||||
if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME)
|
||||
tmp = get_value_for (VUSE_OP (vuses, i), const_and_copies);
|
||||
tmp = SSA_NAME_EQUIV (VUSE_OP (vuses, i));
|
||||
if (tmp)
|
||||
SET_VUSE_OP (vuses, i, tmp);
|
||||
}
|
||||
|
@ -629,14 +596,14 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
/* Get the current value of both operands. */
|
||||
if (TREE_CODE (op0) == SSA_NAME)
|
||||
{
|
||||
tree tmp = get_value_for (op0, const_and_copies);
|
||||
tree tmp = SSA_NAME_EQUIV (op0);
|
||||
if (tmp)
|
||||
op0 = tmp;
|
||||
}
|
||||
|
||||
if (TREE_CODE (op1) == SSA_NAME)
|
||||
{
|
||||
tree tmp = get_value_for (op1, const_and_copies);
|
||||
tree tmp = SSA_NAME_EQUIV (op1);
|
||||
if (tmp)
|
||||
op1 = tmp;
|
||||
}
|
||||
|
@ -676,7 +643,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
|||
else if (TREE_CODE (cond) == SSA_NAME)
|
||||
{
|
||||
cached_lhs = cond;
|
||||
cached_lhs = get_value_for (cached_lhs, const_and_copies);
|
||||
cached_lhs = SSA_NAME_EQUIV (cached_lhs);
|
||||
if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
|
||||
cached_lhs = 0;
|
||||
}
|
||||
|
@ -831,7 +798,7 @@ restore_vars_to_original_value (void)
|
|||
prev_value = VARRAY_TOP_TREE (const_and_copies_stack);
|
||||
VARRAY_POP (const_and_copies_stack);
|
||||
|
||||
set_value_for (dest, prev_value, const_and_copies);
|
||||
SET_SSA_NAME_EQUIV (dest, prev_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1083,7 +1050,7 @@ record_equivalences_from_phis (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
|||
by this assignment, so unwinding just costs time and space. */
|
||||
if (i == PHI_NUM_ARGS (phi)
|
||||
&& may_propagate_copy (lhs, rhs))
|
||||
set_value_for (lhs, rhs, const_and_copies);
|
||||
SET_SSA_NAME_EQUIV (lhs, rhs);
|
||||
|
||||
/* Now see if we know anything about the nonzero property for the
|
||||
result of this PHI. */
|
||||
|
@ -1479,7 +1446,7 @@ record_dominating_conditions (tree cond)
|
|||
static void
|
||||
record_const_or_copy_1 (tree x, tree y, tree prev_x)
|
||||
{
|
||||
set_value_for (x, y, const_and_copies);
|
||||
SET_SSA_NAME_EQUIV (x, y);
|
||||
|
||||
VARRAY_PUSH_TREE (const_and_copies_stack, prev_x);
|
||||
VARRAY_PUSH_TREE (const_and_copies_stack, x);
|
||||
|
@ -1491,11 +1458,11 @@ record_const_or_copy_1 (tree x, tree y, tree prev_x)
|
|||
static void
|
||||
record_const_or_copy (tree x, tree y)
|
||||
{
|
||||
tree prev_x = get_value_for (x, const_and_copies);
|
||||
tree prev_x = SSA_NAME_EQUIV (x);
|
||||
|
||||
if (TREE_CODE (y) == SSA_NAME)
|
||||
{
|
||||
tree tmp = get_value_for (y, const_and_copies);
|
||||
tree tmp = SSA_NAME_EQUIV (y);
|
||||
if (tmp)
|
||||
y = tmp;
|
||||
}
|
||||
|
@ -1512,9 +1479,9 @@ record_equality (tree x, tree y)
|
|||
tree prev_x = NULL, prev_y = NULL;
|
||||
|
||||
if (TREE_CODE (x) == SSA_NAME)
|
||||
prev_x = get_value_for (x, const_and_copies);
|
||||
prev_x = SSA_NAME_EQUIV (x);
|
||||
if (TREE_CODE (y) == SSA_NAME)
|
||||
prev_y = get_value_for (y, const_and_copies);
|
||||
prev_y = SSA_NAME_EQUIV (y);
|
||||
|
||||
/* If one of the previous values is invariant, then use that.
|
||||
Otherwise it doesn't matter which value we choose, just so
|
||||
|
@ -2169,9 +2136,7 @@ simplify_switch_and_lookup_avail_expr (tree stmt, int insert)
|
|||
nodes of the successors of BB. */
|
||||
|
||||
static void
|
||||
cprop_into_successor_phis (basic_block bb,
|
||||
varray_type const_and_copies,
|
||||
bitmap nonzero_vars)
|
||||
cprop_into_successor_phis (basic_block bb, bitmap nonzero_vars)
|
||||
{
|
||||
edge e;
|
||||
|
||||
|
@ -2243,7 +2208,7 @@ cprop_into_successor_phis (basic_block bb,
|
|||
|
||||
/* If we have *ORIG_P in our constant/copy table, then replace
|
||||
ORIG_P with its value in our constant/copy table. */
|
||||
new = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (orig));
|
||||
new = SSA_NAME_EQUIV (orig);
|
||||
if (new
|
||||
&& (TREE_CODE (new) == SSA_NAME
|
||||
|| is_gimple_min_invariant (new))
|
||||
|
@ -2263,7 +2228,7 @@ static void
|
|||
cprop_into_phis (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
{
|
||||
cprop_into_successor_phis (bb, const_and_copies, nonzero_vars);
|
||||
cprop_into_successor_phis (bb, nonzero_vars);
|
||||
}
|
||||
|
||||
/* Search for redundant computations in STMT. If any are found, then
|
||||
|
@ -2388,7 +2353,7 @@ record_equivalences_from_stmt (tree stmt,
|
|||
if (may_optimize_p
|
||||
&& (TREE_CODE (rhs) == SSA_NAME
|
||||
|| is_gimple_min_invariant (rhs)))
|
||||
set_value_for (lhs, rhs, const_and_copies);
|
||||
SET_SSA_NAME_EQUIV (lhs, rhs);
|
||||
|
||||
/* alloca never returns zero and the address of a non-weak symbol
|
||||
is never zero. NOP_EXPRs and CONVERT_EXPRs can be completely
|
||||
|
@ -2499,7 +2464,7 @@ record_equivalences_from_stmt (tree stmt,
|
|||
CONST_AND_COPIES. */
|
||||
|
||||
static bool
|
||||
cprop_operand (tree stmt, use_operand_p op_p, varray_type const_and_copies)
|
||||
cprop_operand (tree stmt, use_operand_p op_p)
|
||||
{
|
||||
bool may_have_exposed_new_symbols = false;
|
||||
tree val;
|
||||
|
@ -2508,7 +2473,7 @@ cprop_operand (tree stmt, use_operand_p op_p, varray_type const_and_copies)
|
|||
/* If the operand has a known constant value or it is known to be a
|
||||
copy of some other variable, use the value or copy stored in
|
||||
CONST_AND_COPIES. */
|
||||
val = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (op));
|
||||
val = SSA_NAME_EQUIV (op);
|
||||
if (val)
|
||||
{
|
||||
tree op_type, val_type;
|
||||
|
@ -2590,7 +2555,7 @@ cprop_operand (tree stmt, use_operand_p op_p, varray_type const_and_copies)
|
|||
v_may_def_ops of STMT. */
|
||||
|
||||
static bool
|
||||
cprop_into_stmt (tree stmt, varray_type const_and_copies)
|
||||
cprop_into_stmt (tree stmt)
|
||||
{
|
||||
bool may_have_exposed_new_symbols = false;
|
||||
use_operand_p op_p;
|
||||
|
@ -2600,8 +2565,7 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies)
|
|||
FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_ALL_USES)
|
||||
{
|
||||
if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
|
||||
may_have_exposed_new_symbols
|
||||
|= cprop_operand (stmt, op_p, const_and_copies);
|
||||
may_have_exposed_new_symbols |= cprop_operand (stmt, op_p);
|
||||
}
|
||||
|
||||
if (may_have_exposed_new_symbols)
|
||||
|
@ -2653,7 +2617,7 @@ optimize_stmt (struct dom_walk_data *walk_data, basic_block bb,
|
|||
}
|
||||
|
||||
/* Const/copy propagate into USES, VUSES and the RHS of V_MAY_DEFs. */
|
||||
may_have_exposed_new_symbols = cprop_into_stmt (stmt, const_and_copies);
|
||||
may_have_exposed_new_symbols = cprop_into_stmt (stmt);
|
||||
|
||||
/* If the statement has been modified with constant replacements,
|
||||
fold its RHS before checking for redundant computations. */
|
||||
|
@ -2895,7 +2859,7 @@ lookup_avail_expr (tree stmt, bool insert)
|
|||
use the value from the const_and_copies table. */
|
||||
if (TREE_CODE (lhs) == SSA_NAME)
|
||||
{
|
||||
temp = get_value_for (lhs, const_and_copies);
|
||||
temp = SSA_NAME_EQUIV (lhs);
|
||||
if (temp)
|
||||
lhs = temp;
|
||||
}
|
||||
|
|
|
@ -186,27 +186,19 @@ make_ssa_name (tree var, tree stmt)
|
|||
|
||||
gcc_assert (!stmt || EXPR_P (stmt) || TREE_CODE (stmt) == PHI_NODE);
|
||||
|
||||
/* If our free list has an element, then use it. Also reuse the
|
||||
SSA version number of the element on the free list which helps
|
||||
keep sbitmaps and arrays sized HIGHEST_SSA_VERSION smaller. */
|
||||
/* If our free list has an element, then use it. */
|
||||
if (free_ssanames)
|
||||
{
|
||||
unsigned int save_version;
|
||||
|
||||
t = free_ssanames;
|
||||
free_ssanames = TREE_CHAIN (free_ssanames);
|
||||
#ifdef GATHER_STATISTICS
|
||||
ssa_name_nodes_reused++;
|
||||
#endif
|
||||
|
||||
/* Clear the node so that it looks just like one we would have
|
||||
received from make_node. */
|
||||
save_version = SSA_NAME_VERSION (t);
|
||||
memset (t, 0, tree_size (t));
|
||||
TREE_SET_CODE (t, SSA_NAME);
|
||||
SSA_NAME_VERSION (t) = save_version;
|
||||
gcc_assert (ssa_name (save_version) == NULL);
|
||||
VARRAY_TREE (ssa_names, save_version) = t;
|
||||
/* The node was cleared out when we put it on the free list, so
|
||||
there is no need to do so again here. */
|
||||
gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL);
|
||||
VARRAY_TREE (ssa_names, SSA_NAME_VERSION (t)) = t;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -262,8 +254,27 @@ release_ssa_name (tree var)
|
|||
defining statement. */
|
||||
if (! SSA_NAME_IN_FREE_LIST (var))
|
||||
{
|
||||
tree saved_ssa_name_var = SSA_NAME_VAR (var);
|
||||
int saved_ssa_name_version = SSA_NAME_VERSION (var);
|
||||
|
||||
VARRAY_TREE (ssa_names, SSA_NAME_VERSION (var)) = NULL;
|
||||
memset (var, 0, tree_size (var));
|
||||
|
||||
/* First put back the right tree node so that the tree checking
|
||||
macros do not complain. */
|
||||
TREE_SET_CODE (var, SSA_NAME);
|
||||
|
||||
/* Restore the version number. */
|
||||
SSA_NAME_VERSION (var) = saved_ssa_name_version;
|
||||
|
||||
/* Hopefully this can go away once we have the new incremental
|
||||
SSA updating code installed. */
|
||||
SSA_NAME_VAR (var) = saved_ssa_name_var;
|
||||
|
||||
/* Note this SSA_NAME is now in the first list. */
|
||||
SSA_NAME_IN_FREE_LIST (var) = 1;
|
||||
|
||||
/* And finally link it into the free list. */
|
||||
TREE_CHAIN (var) = free_ssanames;
|
||||
free_ssanames = var;
|
||||
}
|
||||
|
|
13
gcc/tree.h
13
gcc/tree.h
|
@ -1304,12 +1304,23 @@ struct tree_exp GTY(())
|
|||
#define SSA_NAME_OCCURS_IN_ABNORMAL_PHI(NODE) \
|
||||
SSA_NAME_CHECK (NODE)->common.asm_written_flag
|
||||
|
||||
|
||||
/* Nonzero if this SSA_NAME expression is currently on the free list of
|
||||
SSA_NAMES. Using NOTHROW_FLAG seems reasonably safe since throwing
|
||||
has no meaning for an SSA_NAME. */
|
||||
#define SSA_NAME_IN_FREE_LIST(NODE) \
|
||||
SSA_NAME_CHECK (NODE)->common.nothrow_flag
|
||||
|
||||
#define SSA_NAME_EQUIV(NAME) __extension__ \
|
||||
({ tree equiv = SSA_NAME_CHECK (NAME)->ssa_name.equiv; \
|
||||
if (equiv && TREE_CODE (equiv) == SSA_NAME) \
|
||||
equiv = ssa_name (SSA_NAME_VERSION (equiv)); \
|
||||
equiv; \
|
||||
})
|
||||
|
||||
#define SET_SSA_NAME_EQUIV(NAME, EQUIV)\
|
||||
SSA_NAME_CHECK (NAME)->ssa_name.equiv = (EQUIV);
|
||||
|
||||
/* Attributes for SSA_NAMEs for pointer-type variables. */
|
||||
#define SSA_NAME_PTR_INFO(N) \
|
||||
SSA_NAME_CHECK (N)->ssa_name.ptr_info
|
||||
|
@ -1333,6 +1344,8 @@ struct tree_ssa_name GTY(())
|
|||
/* _DECL wrapped by this SSA name. */
|
||||
tree var;
|
||||
|
||||
tree equiv;
|
||||
|
||||
/* SSA version number. */
|
||||
unsigned int version;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue