mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 20:52:05 +08:00
tree-into-ssa.c (block_defs_stack): New toplevel varray.
* tree-into-ssa.c (block_defs_stack): New toplevel varray. (rewrite_block_data): Remove, no longer used. (rewrite_initialize_block_local_data): Remove, no longer used. (rewrite_initialize_block): Mark parameters as unused as needed. Change references to the block local block_defs to be block_defs_stack. Push a marker onto the block_defs_stack. (ssa_rewrite_initialize_block): Similarly. (rewrite_stmt, ssa_rewrite_stmt): Similarly. (ssa_register_new_def): No longer needs varray argument. Use block_defs_stack instead. No longer handle possibly null block_defs varray. Reverse order of items we push on the stack to make it easier to identify our marker. (register_new_def): No longer handle possibly null block_defs varray. (rewrite_finalize_block): Revamp to look for markers in the global block_defs_stack varray rather than wiping a block local varray. Mark arguments as unused as needed. (ssa_rewrite_finalize_block): Similarly. (rewrite_into_ssa): Update initialization of dom walker structure to reflect that we don't need block local data anymore. Initialize the block_defs_stack varray. (rewrite_ssa_into_ssa): Similarly. * tree-ssa-dom.c (block_defs_stack): New toplevel varray. (struct dom_walk_data): Kill block_defs field. (tree_ssa_dominator_optimize): Initialize block_defs_stack. (thread_across_edge): Use the global block_defs_stack instead of the old block_defs varray. (dom_opt_initialize_block_local_data): Update now that we don't have block_defs field to check anymore. (dom_opt_initialize_block): Push a marker onto block_defs_stack. (restore_currdefs_to_original_value): Use the new block_defs_stack instead of a block local varray. (dom_opt_finalize_block): Similarly. (record_equivalencs_from_phis): Similarly. (optimize_stmt, register_definitions_for_stmt): Similarly. From-SVN: r87611
This commit is contained in:
parent
2d0db225d3
commit
9fae925b00
@ -1,3 +1,41 @@
|
||||
2004-09-16 Jeff Law <law@redhat.com>
|
||||
|
||||
* tree-into-ssa.c (block_defs_stack): New toplevel varray.
|
||||
(rewrite_block_data): Remove, no longer used.
|
||||
(rewrite_initialize_block_local_data): Remove, no longer used.
|
||||
(rewrite_initialize_block): Mark parameters as unused as needed.
|
||||
Change references to the block local block_defs to be block_defs_stack.
|
||||
Push a marker onto the block_defs_stack.
|
||||
(ssa_rewrite_initialize_block): Similarly.
|
||||
(rewrite_stmt, ssa_rewrite_stmt): Similarly.
|
||||
(ssa_register_new_def): No longer needs varray argument. Use
|
||||
block_defs_stack instead. No longer handle possibly null block_defs
|
||||
varray. Reverse order of items we push on the stack to make it
|
||||
easier to identify our marker.
|
||||
(register_new_def): No longer handle possibly null block_defs
|
||||
varray.
|
||||
(rewrite_finalize_block): Revamp to look for markers in the global
|
||||
block_defs_stack varray rather than wiping a block local varray.
|
||||
Mark arguments as unused as needed.
|
||||
(ssa_rewrite_finalize_block): Similarly.
|
||||
(rewrite_into_ssa): Update initialization of dom walker structure
|
||||
to reflect that we don't need block local data anymore. Initialize
|
||||
the block_defs_stack varray.
|
||||
(rewrite_ssa_into_ssa): Similarly.
|
||||
* tree-ssa-dom.c (block_defs_stack): New toplevel varray.
|
||||
(struct dom_walk_data): Kill block_defs field.
|
||||
(tree_ssa_dominator_optimize): Initialize block_defs_stack.
|
||||
(thread_across_edge): Use the global block_defs_stack instead of
|
||||
the old block_defs varray.
|
||||
(dom_opt_initialize_block_local_data): Update now that we don't have
|
||||
block_defs field to check anymore.
|
||||
(dom_opt_initialize_block): Push a marker onto block_defs_stack.
|
||||
(restore_currdefs_to_original_value): Use the new block_defs_stack
|
||||
instead of a block local varray.
|
||||
(dom_opt_finalize_block): Similarly.
|
||||
(record_equivalencs_from_phis): Similarly.
|
||||
(optimize_stmt, register_definitions_for_stmt): Similarly.
|
||||
|
||||
2004-09-16 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
PR tree-optimization/17517
|
||||
|
@ -83,6 +83,34 @@ struct def_blocks_d
|
||||
computing PHI pruning heuristics. */
|
||||
static htab_t def_blocks;
|
||||
|
||||
/* Stack of trees used to restore the global currdefs to its original
|
||||
state after completing rewriting of a block and its dominator children.
|
||||
|
||||
This varray is used in two contexts. The first is rewriting of _DECL
|
||||
nodes into SSA_NAMEs. In that context it's elements have the
|
||||
following properties:
|
||||
|
||||
An SSA_NAME indicates that the current definition of the underlying
|
||||
variable should be set to the given SSA_NAME.
|
||||
|
||||
A _DECL node indicates that the underlying variable has no current
|
||||
definition.
|
||||
|
||||
A NULL node is used to mark the last node associated with the
|
||||
current block.
|
||||
|
||||
|
||||
This varray is also used when rewriting an SSA_NAME which has multiple
|
||||
definition sites into multiple SSA_NAMEs. In that context entries come
|
||||
in pairs.
|
||||
|
||||
The top entry is an SSA_NAME and the top-1 entry is the
|
||||
current value for that SSA_NAME.
|
||||
|
||||
A NULL node at the top entry is used to mark the last node associated
|
||||
with the current block. */
|
||||
static varray_type block_defs_stack;
|
||||
|
||||
/* Global data to attach to the main dominator walk structure. */
|
||||
struct mark_def_sites_global_data
|
||||
{
|
||||
@ -96,11 +124,6 @@ struct mark_def_sites_global_data
|
||||
sbitmap names_to_rename;
|
||||
};
|
||||
|
||||
struct rewrite_block_data
|
||||
{
|
||||
varray_type block_defs;
|
||||
};
|
||||
|
||||
/* Information stored for ssa names. */
|
||||
|
||||
struct ssa_name_info
|
||||
@ -116,8 +139,6 @@ struct ssa_name_info
|
||||
|
||||
/* Local functions. */
|
||||
static void rewrite_finalize_block (struct dom_walk_data *, basic_block);
|
||||
static void rewrite_initialize_block_local_data (struct dom_walk_data *,
|
||||
basic_block, bool);
|
||||
static void rewrite_initialize_block (struct dom_walk_data *, basic_block);
|
||||
static void rewrite_add_phi_arguments (struct dom_walk_data *, basic_block);
|
||||
static void mark_def_sites (struct dom_walk_data *walk_data,
|
||||
@ -636,44 +657,23 @@ insert_phi_nodes (bitmap *dfs, bitmap names_to_rename)
|
||||
definitions are restored to the names that were valid in the
|
||||
dominator parent of BB. */
|
||||
|
||||
/* Initialize the local stacks.
|
||||
|
||||
BLOCK_DEFS is used to save all the existing reaching definitions for
|
||||
the new SSA names introduced in this block. Before registering a
|
||||
new definition for a variable, the existing reaching definition is
|
||||
pushed into this stack so that we can restore it in Step 5. */
|
||||
|
||||
static void
|
||||
rewrite_initialize_block_local_data (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED,
|
||||
bool recycled ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct rewrite_block_data *bd
|
||||
= (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
|
||||
/* We get cleared memory from the allocator, so if the memory is
|
||||
not cleared, then we are re-using a previously allocated entry. In
|
||||
that case, we can also re-use the underlying virtual arrays. Just
|
||||
make sure we clear them before using them! */
|
||||
gcc_assert (!recycled || !bd->block_defs || !(VARRAY_ACTIVE_SIZE (bd->block_defs) > 0));
|
||||
}
|
||||
|
||||
|
||||
/* SSA Rewriting Step 1. Initialization, create a block local stack
|
||||
of reaching definitions for new SSA names produced in this block
|
||||
(BLOCK_DEFS). Register new definitions for every PHI node in the
|
||||
block. */
|
||||
|
||||
static void
|
||||
rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
rewrite_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
{
|
||||
tree phi;
|
||||
struct rewrite_block_data *bd
|
||||
= (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
|
||||
|
||||
/* Mark the unwind point for this block. */
|
||||
VARRAY_PUSH_TREE (block_defs_stack, NULL_TREE);
|
||||
|
||||
/* Step 1. Register new definitions for every PHI node in the block.
|
||||
Conceptually, all the PHI nodes are executed in parallel and each PHI
|
||||
node introduces a new version for the associated variable. */
|
||||
@ -681,7 +681,7 @@ rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
{
|
||||
tree result = PHI_RESULT (phi);
|
||||
|
||||
register_new_def (result, &bd->block_defs);
|
||||
register_new_def (result, &block_defs_stack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,7 +690,7 @@ rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
into the stack pointed by BLOCK_DEFS_P. */
|
||||
|
||||
static void
|
||||
ssa_register_new_def (tree var, tree def, varray_type *block_defs_p)
|
||||
ssa_register_new_def (tree var, tree def)
|
||||
{
|
||||
tree currdef;
|
||||
|
||||
@ -705,15 +705,13 @@ ssa_register_new_def (tree var, tree def, varray_type *block_defs_p)
|
||||
}
|
||||
|
||||
currdef = get_current_def (var);
|
||||
if (! *block_defs_p)
|
||||
VARRAY_TREE_INIT (*block_defs_p, 20, "block_defs");
|
||||
|
||||
/* Push the current reaching definition into *BLOCK_DEFS_P. This stack is
|
||||
later used by the dominator tree callbacks to restore the reaching
|
||||
definitions for all the variables defined in the block after a recursive
|
||||
visit to all its immediately dominated blocks. */
|
||||
VARRAY_PUSH_TREE (*block_defs_p, var);
|
||||
VARRAY_PUSH_TREE (*block_defs_p, currdef);
|
||||
VARRAY_PUSH_TREE (block_defs_stack, currdef);
|
||||
VARRAY_PUSH_TREE (block_defs_stack, var);
|
||||
|
||||
/* Set the current reaching definition for VAR to be DEF. */
|
||||
set_current_def (var, def);
|
||||
@ -725,8 +723,6 @@ static void
|
||||
ssa_rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
{
|
||||
tree phi, new_name;
|
||||
struct rewrite_block_data *bd
|
||||
= (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
sbitmap names_to_rename = walk_data->global_data;
|
||||
edge e;
|
||||
bool abnormal_phi;
|
||||
@ -734,6 +730,9 @@ ssa_rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "\n\nRenaming block #%d\n\n", bb->index);
|
||||
|
||||
/* Mark the unwind point for this block. */
|
||||
VARRAY_PUSH_TREE (block_defs_stack, NULL_TREE);
|
||||
|
||||
for (e = bb->pred; e; e = e->pred_next)
|
||||
if (e->flags & EDGE_ABNORMAL)
|
||||
break;
|
||||
@ -757,7 +756,7 @@ ssa_rewrite_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
else
|
||||
new_name = result;
|
||||
|
||||
ssa_register_new_def (result, new_name, &bd->block_defs);
|
||||
ssa_register_new_def (result, new_name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -824,24 +823,28 @@ ssa_rewrite_phi_arguments (struct dom_walk_data *walk_data, basic_block bb)
|
||||
}
|
||||
}
|
||||
|
||||
/* SSA Rewriting Step 5. Restore the current reaching definition for each
|
||||
variable referenced in the block (in reverse order). */
|
||||
|
||||
/* Similar to restore_vars_to_original_value, except that it restores
|
||||
CURRDEFS to its original value. */
|
||||
static void
|
||||
rewrite_finalize_block (struct dom_walk_data *walk_data,
|
||||
rewrite_finalize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct rewrite_block_data *bd
|
||||
= (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
|
||||
/* Step 5. Restore the current reaching definition for each variable
|
||||
referenced in the block (in reverse order). */
|
||||
while (bd->block_defs && VARRAY_ACTIVE_SIZE (bd->block_defs) > 0)
|
||||
/* Restore CURRDEFS to its original state. */
|
||||
while (VARRAY_ACTIVE_SIZE (block_defs_stack) > 0)
|
||||
{
|
||||
tree tmp = VARRAY_TOP_TREE (bd->block_defs);
|
||||
tree tmp = VARRAY_TOP_TREE (block_defs_stack);
|
||||
tree saved_def, var;
|
||||
|
||||
VARRAY_POP (bd->block_defs);
|
||||
VARRAY_POP (block_defs_stack);
|
||||
|
||||
if (tmp == NULL_TREE)
|
||||
break;
|
||||
|
||||
/* If we recorded an SSA_NAME, then make the SSA_NAME the current
|
||||
definition of its underlying variable. If we recorded anything
|
||||
else, it must have been an _DECL node and its current reaching
|
||||
definition must have been NULL. */
|
||||
if (TREE_CODE (tmp) == SSA_NAME)
|
||||
{
|
||||
saved_def = tmp;
|
||||
@ -852,7 +855,7 @@ rewrite_finalize_block (struct dom_walk_data *walk_data,
|
||||
saved_def = NULL;
|
||||
var = tmp;
|
||||
}
|
||||
|
||||
|
||||
set_current_def (var, saved_def);
|
||||
}
|
||||
}
|
||||
@ -860,22 +863,24 @@ rewrite_finalize_block (struct dom_walk_data *walk_data,
|
||||
/* Ditto, for rewriting ssa names. */
|
||||
|
||||
static void
|
||||
ssa_rewrite_finalize_block (struct dom_walk_data *walk_data,
|
||||
ssa_rewrite_finalize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED)
|
||||
{
|
||||
struct rewrite_block_data *bd
|
||||
= (struct rewrite_block_data *)VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
|
||||
/* Step 5. Restore the current reaching definition for each variable
|
||||
referenced in the block (in reverse order). */
|
||||
while (bd->block_defs && VARRAY_ACTIVE_SIZE (bd->block_defs) > 0)
|
||||
while (VARRAY_ACTIVE_SIZE (block_defs_stack) > 0)
|
||||
{
|
||||
tree var;
|
||||
tree saved_def = VARRAY_TOP_TREE (bd->block_defs);
|
||||
VARRAY_POP (bd->block_defs);
|
||||
tree var = VARRAY_TOP_TREE (block_defs_stack);
|
||||
tree saved_def;
|
||||
|
||||
VARRAY_POP (block_defs_stack);
|
||||
|
||||
var = VARRAY_TOP_TREE (bd->block_defs);
|
||||
VARRAY_POP (bd->block_defs);
|
||||
if (var == NULL)
|
||||
break;
|
||||
|
||||
saved_def = VARRAY_TOP_TREE (block_defs_stack);
|
||||
VARRAY_POP (block_defs_stack);
|
||||
|
||||
set_current_def (var, saved_def);
|
||||
}
|
||||
@ -1037,7 +1042,7 @@ insert_phi_nodes_for (tree var, bitmap *dfs, varray_type *work_stack)
|
||||
definition of a variable when a new real or virtual definition is found. */
|
||||
|
||||
static void
|
||||
rewrite_stmt (struct dom_walk_data *walk_data,
|
||||
rewrite_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED,
|
||||
block_stmt_iterator si)
|
||||
{
|
||||
@ -1046,9 +1051,6 @@ rewrite_stmt (struct dom_walk_data *walk_data,
|
||||
use_operand_p use_p;
|
||||
def_operand_p def_p;
|
||||
ssa_op_iter iter;
|
||||
struct rewrite_block_data *bd;
|
||||
|
||||
bd = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
|
||||
stmt = bsi_stmt (si);
|
||||
ann = stmt_ann (stmt);
|
||||
@ -1076,7 +1078,7 @@ rewrite_stmt (struct dom_walk_data *walk_data,
|
||||
|
||||
/* FIXME: We shouldn't be registering new defs if the variable
|
||||
doesn't need to be renamed. */
|
||||
register_new_def (DEF_FROM_PTR (def_p), &bd->block_defs);
|
||||
register_new_def (DEF_FROM_PTR (def_p), &block_defs_stack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1092,11 +1094,8 @@ ssa_rewrite_stmt (struct dom_walk_data *walk_data,
|
||||
ssa_op_iter iter;
|
||||
use_operand_p use_p;
|
||||
def_operand_p def_p;
|
||||
struct rewrite_block_data *bd;
|
||||
sbitmap names_to_rename = walk_data->global_data;
|
||||
|
||||
bd = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
|
||||
stmt = bsi_stmt (si);
|
||||
ann = stmt_ann (stmt);
|
||||
|
||||
@ -1127,7 +1126,7 @@ ssa_rewrite_stmt (struct dom_walk_data *walk_data,
|
||||
continue;
|
||||
|
||||
SET_DEF (def_p, duplicate_ssa_name (var, stmt));
|
||||
ssa_register_new_def (var, DEF_FROM_PTR (def_p), &bd->block_defs);
|
||||
ssa_register_new_def (var, DEF_FROM_PTR (def_p));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1166,8 +1165,6 @@ register_new_def (tree def, varray_type *block_defs_p)
|
||||
}
|
||||
|
||||
currdef = get_current_def (var);
|
||||
if (! *block_defs_p)
|
||||
VARRAY_TREE_INIT (*block_defs_p, 20, "block_defs");
|
||||
|
||||
/* Push the current reaching definition into *BLOCK_DEFS_P. This stack is
|
||||
later used by the dominator tree callbacks to restore the reaching
|
||||
@ -1497,7 +1494,7 @@ rewrite_into_ssa (bool all)
|
||||
/* Setup callbacks for the generic dominator tree walker. */
|
||||
walk_data.walk_stmts_backward = false;
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = rewrite_initialize_block_local_data;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children_before_stmts = rewrite_initialize_block;
|
||||
walk_data.before_dom_children_walk_stmts = rewrite_stmt;
|
||||
walk_data.before_dom_children_after_stmts = rewrite_add_phi_arguments;
|
||||
@ -1505,7 +1502,9 @@ rewrite_into_ssa (bool all)
|
||||
walk_data.after_dom_children_walk_stmts = NULL;
|
||||
walk_data.after_dom_children_after_stmts = rewrite_finalize_block;
|
||||
walk_data.global_data = NULL;
|
||||
walk_data.block_local_data_size = sizeof (struct rewrite_block_data);
|
||||
walk_data.block_local_data_size = 0;
|
||||
|
||||
VARRAY_TREE_INIT (block_defs_stack, 10, "Block DEFS Stack");
|
||||
|
||||
/* Initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
@ -1606,6 +1605,8 @@ rewrite_ssa_into_ssa (void)
|
||||
mark_def_sites_global_data.names_to_rename = snames_to_rename;
|
||||
walk_data.global_data = &mark_def_sites_global_data;
|
||||
|
||||
VARRAY_TREE_INIT (block_defs_stack, 10, "Block DEFS Stack");
|
||||
|
||||
/* We do not have any local data. */
|
||||
walk_data.block_local_data_size = 0;
|
||||
|
||||
@ -1633,8 +1634,7 @@ rewrite_ssa_into_ssa (void)
|
||||
/* Setup callbacks for the generic dominator tree walker. */
|
||||
walk_data.walk_stmts_backward = false;
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data
|
||||
= rewrite_initialize_block_local_data;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children_before_stmts = ssa_rewrite_initialize_block;
|
||||
walk_data.before_dom_children_walk_stmts = ssa_rewrite_stmt;
|
||||
walk_data.before_dom_children_after_stmts = ssa_rewrite_phi_arguments;
|
||||
@ -1642,7 +1642,7 @@ rewrite_ssa_into_ssa (void)
|
||||
walk_data.after_dom_children_walk_stmts = NULL;
|
||||
walk_data.after_dom_children_after_stmts = ssa_rewrite_finalize_block;
|
||||
walk_data.global_data = snames_to_rename;
|
||||
walk_data.block_local_data_size = sizeof (struct rewrite_block_data);
|
||||
walk_data.block_local_data_size = 0;
|
||||
|
||||
/* Initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
@ -61,6 +61,19 @@ static htab_t avail_exprs;
|
||||
marker. */
|
||||
static varray_type avail_exprs_stack;
|
||||
|
||||
/* Stack of trees used to restore the global currdefs to its original
|
||||
state after completing optimization of a block and its dominator children.
|
||||
|
||||
An SSA_NAME indicates that the current definition of the underlying
|
||||
variable should be set to the given SSA_NAME.
|
||||
|
||||
A _DECL node indicates that the underlying variable has no current
|
||||
definition.
|
||||
|
||||
A NULL node is used to mark the last node associated with the
|
||||
current block. */
|
||||
varray_type block_defs_stack;
|
||||
|
||||
/* Stack of statements we need to rescan during finalization for newly
|
||||
exposed variables.
|
||||
|
||||
@ -200,11 +213,6 @@ struct dom_walk_block_data
|
||||
in this basic block. We use this during finalization to know
|
||||
which variables need their VRP data updated. */
|
||||
varray_type vrp_variables;
|
||||
|
||||
/* Array of tree pairs used to restore the global currdefs to its
|
||||
original state after completing optimization of a block and its
|
||||
dominator children. */
|
||||
varray_type block_defs;
|
||||
};
|
||||
|
||||
struct eq_expr_value
|
||||
@ -255,9 +263,8 @@ static void remove_local_expressions_from_table (void);
|
||||
static void restore_vars_to_original_value (varray_type locals,
|
||||
unsigned limit,
|
||||
varray_type table);
|
||||
static void restore_currdefs_to_original_value (varray_type locals,
|
||||
unsigned limit);
|
||||
static void register_definitions_for_stmt (tree, varray_type *);
|
||||
static void restore_currdefs_to_original_value (void);
|
||||
static void register_definitions_for_stmt (tree);
|
||||
static edge single_incoming_edge_ignoring_loop_edges (basic_block);
|
||||
|
||||
/* Local version of fold that doesn't introduce cruft. */
|
||||
@ -314,6 +321,7 @@ tree_ssa_dominator_optimize (void)
|
||||
/* Create our hash tables. */
|
||||
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");
|
||||
nonzero_vars = BITMAP_XMALLOC ();
|
||||
VARRAY_GENERIC_PTR_INIT (vrp_data, num_ssa_names, "vrp_data");
|
||||
@ -461,7 +469,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
||||
tree src = PHI_ARG_DEF_FROM_EDGE (phi, e);
|
||||
tree dst = PHI_RESULT (phi);
|
||||
record_const_or_copy (dst, src, &bd->const_and_copies);
|
||||
register_new_def (dst, &bd->block_defs);
|
||||
register_new_def (dst, &block_defs_stack);
|
||||
}
|
||||
|
||||
for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
|
||||
@ -576,7 +584,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
||||
the result of this statement is used later we can copy propagate
|
||||
suitably. */
|
||||
record_const_or_copy (lhs, cached_lhs, &bd->const_and_copies);
|
||||
register_new_def (lhs, &bd->block_defs);
|
||||
register_new_def (lhs, &block_defs_stack);
|
||||
}
|
||||
|
||||
/* If we stopped at a COND_EXPR or SWITCH_EXPR, then see if we know which
|
||||
@ -735,8 +743,6 @@ dom_opt_initialize_block_local_data (struct dom_walk_data *walk_data ATTRIBUTE_U
|
||||
|| VARRAY_ACTIVE_SIZE (bd->nonzero_vars) == 0);
|
||||
gcc_assert (!bd->vrp_variables
|
||||
|| VARRAY_ACTIVE_SIZE (bd->vrp_variables) == 0);
|
||||
gcc_assert (!bd->block_defs
|
||||
|| VARRAY_ACTIVE_SIZE (bd->block_defs) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,9 +756,10 @@ dom_opt_initialize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index);
|
||||
|
||||
/* Push a marker on AVAIL_EXPRS_STACK so that we know how far to unwind
|
||||
when we finalize this block. */
|
||||
/* Push a marker on the stacks of local information so that we know how
|
||||
far to unwind when we finalize this block. */
|
||||
VARRAY_PUSH_TREE (avail_exprs_stack, NULL_TREE);
|
||||
VARRAY_PUSH_TREE (block_defs_stack, NULL_TREE);
|
||||
|
||||
record_equivalences_from_incoming_edge (walk_data, bb);
|
||||
|
||||
@ -869,18 +876,18 @@ restore_vars_to_original_value (varray_type locals,
|
||||
/* Similar to restore_vars_to_original_value, except that it restores
|
||||
CURRDEFS to its original value. */
|
||||
static void
|
||||
restore_currdefs_to_original_value (varray_type locals, unsigned limit)
|
||||
restore_currdefs_to_original_value (void)
|
||||
{
|
||||
if (!locals)
|
||||
return;
|
||||
|
||||
/* Restore CURRDEFS to its original state. */
|
||||
while (VARRAY_ACTIVE_SIZE (locals) > limit)
|
||||
while (VARRAY_ACTIVE_SIZE (block_defs_stack) > 0)
|
||||
{
|
||||
tree tmp = VARRAY_TOP_TREE (locals);
|
||||
tree tmp = VARRAY_TOP_TREE (block_defs_stack);
|
||||
tree saved_def, var;
|
||||
|
||||
VARRAY_POP (locals);
|
||||
VARRAY_POP (block_defs_stack);
|
||||
|
||||
if (tmp == NULL_TREE)
|
||||
break;
|
||||
|
||||
/* If we recorded an SSA_NAME, then make the SSA_NAME the current
|
||||
definition of its underlying variable. If we recorded anything
|
||||
@ -953,18 +960,15 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
|| phi_nodes (true_edge->dest))
|
||||
{
|
||||
unsigned const_and_copies_limit;
|
||||
unsigned currdefs_limit;
|
||||
|
||||
const_and_copies_limit
|
||||
= bd->const_and_copies ? VARRAY_ACTIVE_SIZE (bd->const_and_copies)
|
||||
: 0;
|
||||
currdefs_limit
|
||||
= bd->block_defs ? VARRAY_ACTIVE_SIZE (bd->block_defs) : 0;
|
||||
|
||||
/* Push a marker onto the available expression stack so that we
|
||||
unwind any expressions related to the TRUE arm before processing
|
||||
the false arm below. */
|
||||
VARRAY_PUSH_TREE (avail_exprs_stack, NULL_TREE);
|
||||
VARRAY_PUSH_TREE (block_defs_stack, NULL_TREE);
|
||||
|
||||
/* Record any equivalences created by following this edge. */
|
||||
if (TREE_CODE_CLASS (cond_code) == '<')
|
||||
@ -986,7 +990,7 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
restore_vars_to_original_value (bd->const_and_copies,
|
||||
const_and_copies_limit,
|
||||
const_and_copies);
|
||||
restore_currdefs_to_original_value (bd->block_defs, currdefs_limit);
|
||||
restore_currdefs_to_original_value ();
|
||||
}
|
||||
|
||||
/* Similarly for the ELSE arm. */
|
||||
@ -1015,7 +1019,7 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
remove_local_expressions_from_table ();
|
||||
restore_nonzero_vars_to_original_value (bd->nonzero_vars, 0, nonzero_vars);
|
||||
restore_vars_to_original_value (bd->const_and_copies, 0, const_and_copies);
|
||||
restore_currdefs_to_original_value (bd->block_defs, 0);
|
||||
restore_currdefs_to_original_value ();
|
||||
|
||||
/* Remove VRP records associated with this basic block. They are no
|
||||
longer valid.
|
||||
@ -1075,10 +1079,9 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
even if we do not know its exact value. */
|
||||
|
||||
static void
|
||||
record_equivalences_from_phis (struct dom_walk_data *walk_data, basic_block bb)
|
||||
record_equivalences_from_phis (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
{
|
||||
struct dom_walk_block_data *bd
|
||||
= VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
|
||||
tree phi;
|
||||
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
@ -1137,7 +1140,7 @@ record_equivalences_from_phis (struct dom_walk_data *walk_data, basic_block bb)
|
||||
if (i == PHI_NUM_ARGS (phi))
|
||||
bitmap_set_bit (nonzero_vars, SSA_NAME_VERSION (PHI_RESULT (phi)));
|
||||
|
||||
register_new_def (lhs, &bd->block_defs);
|
||||
register_new_def (lhs, &block_defs_stack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2759,7 +2762,7 @@ optimize_stmt (struct dom_walk_data *walk_data, basic_block bb,
|
||||
may_optimize_p,
|
||||
ann);
|
||||
|
||||
register_definitions_for_stmt (stmt, &bd->block_defs);
|
||||
register_definitions_for_stmt (stmt);
|
||||
|
||||
/* If STMT is a COND_EXPR and it was modified, then we may know
|
||||
where it goes. If that is the case, then mark the CFG as altered.
|
||||
@ -3290,7 +3293,7 @@ avail_expr_eq (const void *p1, const void *p2)
|
||||
and CURRDEFS. */
|
||||
|
||||
static void
|
||||
register_definitions_for_stmt (tree stmt, varray_type *block_defs_p)
|
||||
register_definitions_for_stmt (tree stmt)
|
||||
{
|
||||
tree def;
|
||||
ssa_op_iter iter;
|
||||
@ -3300,7 +3303,7 @@ register_definitions_for_stmt (tree stmt, varray_type *block_defs_p)
|
||||
|
||||
/* FIXME: We shouldn't be registering new defs if the variable
|
||||
doesn't need to be renamed. */
|
||||
register_new_def (def, block_defs_p);
|
||||
register_new_def (def, &block_defs_stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user