/* 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
+ This vector 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:
current block.
- This varray is also used when rewriting an SSA_NAME which has multiple
+ This vector is also used when rewriting an SSA_NAME which has multiple
definition sites into multiple SSA_NAMEs. In that context entries come
in pairs.
with the current block. */
static VEC(tree_on_heap) *block_defs_stack;
-/* FIXME: The other stacks should also be VEC(tree_on_heap). */
+/* Basic block vectors used in this file ought to be allocated in the heap. */
+DEF_VEC_MALLOC_P(basic_block);
/* Global data to attach to the main dominator walk structure. */
struct mark_def_sites_global_data
static void rewrite_stmt (struct dom_walk_data *, basic_block,
block_stmt_iterator);
static inline void rewrite_operand (use_operand_p);
-static void insert_phi_nodes_for (tree, bitmap *, varray_type *);
+static void insert_phi_nodes_for (tree, bitmap *, VEC(basic_block) *);
static tree get_reaching_def (tree);
static hashval_t def_blocks_hash (const void *);
static int def_blocks_eq (const void *, const void *);
/* Helper for insert_phi_nodes. If VAR needs PHI nodes, insert them
at the dominance frontier (DFS) of blocks defining VAR.
- WORK_STACK is the varray used to implement the worklist of basic
+ WORK_STACK is the vector used to implement the worklist of basic
blocks. */
static inline
-void insert_phi_nodes_1 (tree var, bitmap *dfs, varray_type *work_stack)
+void insert_phi_nodes_1 (tree var, bitmap *dfs, VEC(basic_block) *work_stack)
{
if (get_phi_state (var) != NEED_PHI_STATE_NO)
insert_phi_nodes_for (var, dfs, work_stack);
insert_phi_nodes (bitmap *dfs, bitmap names_to_rename)
{
unsigned i;
- varray_type work_stack;
+ VEC(basic_block) *work_stack;
bitmap_iterator bi;
timevar_push (TV_TREE_INSERT_PHI_NODES);
- /* Array WORK_STACK is a stack of CFG blocks. Each block that contains
+ /* Vector WORK_STACK is a stack of CFG blocks. Each block that contains
an assignment or PHI node will be pushed to this stack. */
- VARRAY_GENERIC_PTR_NOGC_INIT (work_stack, last_basic_block, "work_stack");
+ work_stack = VEC_alloc (basic_block, last_basic_block);
/* Iterate over all variables in VARS_TO_RENAME. For each variable, add
to the work list all the blocks that have a definition for the
EXECUTE_IF_SET_IN_BITMAP (names_to_rename, 0, i, bi)
{
if (ssa_name (i))
- insert_phi_nodes_1 (ssa_name (i), dfs, &work_stack);
+ insert_phi_nodes_1 (ssa_name (i), dfs, work_stack);
}
}
else if (vars_to_rename)
EXECUTE_IF_SET_IN_BITMAP (vars_to_rename, 0, i, bi)
{
- insert_phi_nodes_1 (referenced_var (i), dfs, &work_stack);
+ insert_phi_nodes_1 (referenced_var (i), dfs, work_stack);
}
else
for (i = 0; i < num_referenced_vars; i++)
- insert_phi_nodes_1 (referenced_var (i), dfs, &work_stack);
+ insert_phi_nodes_1 (referenced_var (i), dfs, work_stack);
- VARRAY_FREE (work_stack);
+ VEC_free (basic_block, work_stack);
timevar_pop (TV_TREE_INSERT_PHI_NODES);
}
/* Insert PHI nodes for variable VAR using the dominance frontier
- information given in DFS. WORK_STACK is the varray used to
+ information given in DFS. WORK_STACK is the vector used to
implement the worklist of basic blocks. */
static void
-insert_phi_nodes_for (tree var, bitmap *dfs, varray_type *work_stack)
+insert_phi_nodes_for (tree var, bitmap *dfs, VEC(basic_block) *work_stack)
{
struct def_blocks_d *def_map;
bitmap phi_insertion_points;
EXECUTE_IF_SET_IN_BITMAP (def_map->def_blocks, 0, bb_index, bi)
{
- VARRAY_PUSH_GENERIC_PTR_NOGC (*work_stack, BASIC_BLOCK (bb_index));
+ VEC_quick_push (basic_block, work_stack, BASIC_BLOCK (bb_index));
}
/* Pop a block off the worklist, add every block that appears in
determine if fully pruned or semi pruned SSA form was appropriate.
We now always use fully pruned SSA form. */
- while (VARRAY_ACTIVE_SIZE (*work_stack) > 0)
+ while (VEC_length (basic_block, work_stack) > 0)
{
unsigned dfs_index;
bitmap_iterator bi;
- bb = VARRAY_TOP_GENERIC_PTR_NOGC (*work_stack);
+ bb = VEC_pop (basic_block, work_stack);
bb_index = bb->index;
-
- VARRAY_POP (*work_stack);
EXECUTE_IF_AND_COMPL_IN_BITMAP (dfs[bb_index],
phi_insertion_points,
{
basic_block bb = BASIC_BLOCK (dfs_index);
- VARRAY_PUSH_GENERIC_PTR_NOGC (*work_stack, bb);
+ VEC_quick_push (basic_block, work_stack, bb);
bitmap_set_bit (phi_insertion_points, dfs_index);
}
}
(null). When we finish processing the block, we pop off entries and
remove the expressions from the global hash table until we hit the
marker. */
-static varray_type avail_exprs_stack;
+static VEC(tree_on_heap) *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.
A NULL node is used to mark the last node associated with the
current block. */
-VEC(tree_on_heap) *block_defs_stack;
-
-/* FIXME: The other stacks should also be VEC(tree_on_heap). */
+static VEC(tree_on_heap) *block_defs_stack;
/* Stack of statements we need to rescan during finalization for newly
exposed variables.
expressions are removed from AVAIL_EXPRS. Else we may change the
hash code for an expression and be unable to find/remove it from
AVAIL_EXPRS. */
-varray_type stmts_to_rescan;
+static VEC(tree_on_heap) *stmts_to_rescan;
/* Structure for entries in the expression hash table.
A NULL entry is used to mark the end of pairs which need to be
restored during finalization of this block. */
-static varray_type const_and_copies_stack;
+static VEC(tree_on_heap) *const_and_copies_stack;
/* Bitmap of SSA_NAMEs known to have a nonzero value, even if we do not
know their exact value. */
A NULL entry is used to mark the end of names needing their
entry in NONZERO_VARS cleared during finalization of this block. */
-static varray_type nonzero_vars_stack;
+static VEC(tree_on_heap) *nonzero_vars_stack;
/* Track whether or not we have changed the control flow graph. */
static bool cfg_altered;
/* An entry in the VRP_DATA hash table. We record the variable and a
varray of VRP_ELEMENT records associated with that variable. */
-
struct vrp_hash_elt
{
tree var;
list to determine which variables need their VRP data updated.
A NULL entry marks the end of the SSA_NAMEs associated with this block. */
-static varray_type vrp_variables_stack;
+static VEC(tree_on_heap) *vrp_variables_stack;
struct eq_expr_value
{
/* Create our hash tables. */
avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
vrp_data = htab_create (ceil_log2 (num_ssa_names), vrp_hash, vrp_eq, free);
- VARRAY_TREE_INIT (avail_exprs_stack, 20, "Available expression stack");
+ avail_exprs_stack = VEC_alloc (tree_on_heap, 20);
block_defs_stack = VEC_alloc (tree_on_heap, 20);
- 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");
- VARRAY_TREE_INIT (stmts_to_rescan, 20, "Statements to rescan");
+ const_and_copies_stack = VEC_alloc (tree_on_heap, 20);
+ nonzero_vars_stack = VEC_alloc (tree_on_heap, 20);
+ vrp_variables_stack = VEC_alloc (tree_on_heap, 20);
+ stmts_to_rescan = VEC_alloc (tree_on_heap, 20);
nonzero_vars = BITMAP_XMALLOC ();
need_eh_cleanup = BITMAP_XMALLOC ();
}
VEC_free (tree_on_heap, block_defs_stack);
- block_defs_stack = NULL;
+ VEC_free (tree_on_heap, avail_exprs_stack);
+ VEC_free (tree_on_heap, const_and_copies_stack);
+ VEC_free (tree_on_heap, nonzero_vars_stack);
+ VEC_free (tree_on_heap, vrp_variables_stack);
+ VEC_free (tree_on_heap, stmts_to_rescan);
}
static bool
/* 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);
+ VEC_safe_push (tree_on_heap, avail_exprs_stack, NULL_TREE);
VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
- VARRAY_PUSH_TREE (const_and_copies_stack, NULL_TREE);
- VARRAY_PUSH_TREE (nonzero_vars_stack, NULL_TREE);
- VARRAY_PUSH_TREE (vrp_variables_stack, NULL_TREE);
+ VEC_safe_push (tree_on_heap, const_and_copies_stack, NULL_TREE);
+ VEC_safe_push (tree_on_heap, nonzero_vars_stack, NULL_TREE);
+ VEC_safe_push (tree_on_heap, vrp_variables_stack, NULL_TREE);
record_equivalences_from_incoming_edge (bb);
remove_local_expressions_from_table (void)
{
/* Remove all the expressions made available in this block. */
- while (VARRAY_ACTIVE_SIZE (avail_exprs_stack) > 0)
+ while (VEC_length (tree_on_heap, avail_exprs_stack) > 0)
{
struct expr_hash_elt element;
- tree expr = VARRAY_TOP_TREE (avail_exprs_stack);
- VARRAY_POP (avail_exprs_stack);
+ tree expr = VEC_pop (tree_on_heap, avail_exprs_stack);
if (expr == NULL_TREE)
break;
static void
restore_nonzero_vars_to_original_value (void)
{
- while (VARRAY_ACTIVE_SIZE (nonzero_vars_stack) > 0)
+ while (VEC_length (tree_on_heap, nonzero_vars_stack) > 0)
{
- tree name = VARRAY_TOP_TREE (nonzero_vars_stack);
- VARRAY_POP (nonzero_vars_stack);
+ tree name = VEC_pop (tree_on_heap, nonzero_vars_stack);
if (name == NULL)
break;
static void
restore_vars_to_original_value (void)
{
- while (VARRAY_ACTIVE_SIZE (const_and_copies_stack) > 0)
+ while (VEC_length (tree_on_heap, const_and_copies_stack) > 0)
{
tree prev_value, dest;
- dest = VARRAY_TOP_TREE (const_and_copies_stack);
- VARRAY_POP (const_and_copies_stack);
+ dest = VEC_pop (tree_on_heap, const_and_copies_stack);
if (dest == NULL)
break;
- prev_value = VARRAY_TOP_TREE (const_and_copies_stack);
- VARRAY_POP (const_and_copies_stack);
-
+ prev_value = VEC_pop (tree_on_heap, const_and_copies_stack);
SSA_NAME_VALUE (dest) = prev_value;
}
}
/* 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);
+ VEC_safe_push (tree_on_heap, avail_exprs_stack, NULL_TREE);
VEC_safe_push (tree_on_heap, block_defs_stack, NULL_TREE);
- VARRAY_PUSH_TREE (const_and_copies_stack, NULL_TREE);
+ VEC_safe_push (tree_on_heap, const_and_copies_stack, NULL_TREE);
edge_info = true_edge->aux;
To be efficient, we note which variables have had their values
constrained in this block. So walk over each variable in the
VRP_VARIABLEs array. */
- while (VARRAY_ACTIVE_SIZE (vrp_variables_stack) > 0)
+ while (VEC_length (tree_on_heap, vrp_variables_stack) > 0)
{
- tree var = VARRAY_TOP_TREE (vrp_variables_stack);
+ tree var = VEC_pop (tree_on_heap, vrp_variables_stack);
struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p;
void **slot;
we are done. */
varray_type var_vrp_records;
- VARRAY_POP (vrp_variables_stack);
-
if (var == NULL)
break;
/* If we queued any statements to rescan in this block, then
go ahead and rescan them now. */
- while (VARRAY_ACTIVE_SIZE (stmts_to_rescan) > 0)
+ while (VEC_length (tree_on_heap, stmts_to_rescan) > 0)
{
- tree stmt = VARRAY_TOP_TREE (stmts_to_rescan);
+ tree stmt = VEC_last (tree_on_heap, stmts_to_rescan);
basic_block stmt_bb = bb_for_stmt (stmt);
if (stmt_bb != bb)
break;
- VARRAY_POP (stmts_to_rescan);
+ VEC_pop (tree_on_heap, stmts_to_rescan);
mark_new_vars_to_rename (stmt, vars_to_rename);
}
}
/* Record this SSA_NAME so that we can reset the global table
when we leave this block. */
- VARRAY_PUSH_TREE (nonzero_vars_stack, var);
+ VEC_safe_push (tree_on_heap, nonzero_vars_stack, var);
}
/* Enter a statement into the true/false expression hash table indicating
if (*slot == NULL)
{
*slot = (void *) element;
- VARRAY_PUSH_TREE (avail_exprs_stack, cond);
+ VEC_safe_push (tree_on_heap, avail_exprs_stack, cond);
}
else
free (element);
{
SSA_NAME_VALUE (x) = y;
- VARRAY_PUSH_TREE (const_and_copies_stack, prev_x);
- VARRAY_PUSH_TREE (const_and_copies_stack, x);
+ VEC_safe_push (tree_on_heap, const_and_copies_stack, prev_x);
+ VEC_safe_push (tree_on_heap, const_and_copies_stack, x);
}
/* Record that X is equal to Y in const_and_copies. Record undo
- information in the block-local varray. */
+ information in the block-local vector. */
static void
record_const_or_copy (tree x, tree y)
}
if (may_have_exposed_new_symbols)
- VARRAY_PUSH_TREE (stmts_to_rescan, bsi_stmt (si));
+ VEC_safe_push (tree_on_heap, stmts_to_rescan, bsi_stmt (si));
}
/* Replace the RHS of STMT with NEW_RHS. If RHS can be found in the
We know the call in optimize_stmt did not find an existing entry
in the hash table, so a new entry was created. At the same time
- this statement was pushed onto the BLOCK_AVAIL_EXPRS varray.
+ this statement was pushed onto the AVAIL_EXPRS_STACK vector.
If this call failed to find an existing entry on the hash table,
then the new version of this statement was entered into the
for the second time. So there are two copies on BLOCK_AVAIL_EXPRs
If this call succeeded, we still have one copy of this statement
- on the BLOCK_AVAIL_EXPRs varray.
+ on the BLOCK_AVAIL_EXPRs vector.
For both cases, we need to pop the most recent entry off the
- BLOCK_AVAIL_EXPRs varray. For the case where we never found this
+ BLOCK_AVAIL_EXPRs vector. For the case where we never found this
statement in the hash tables, that will leave precisely one
copy of this statement on BLOCK_AVAIL_EXPRs. For the case where
we found a copy of this statement in the second hash table lookup
we want _no_ copies of this statement in BLOCK_AVAIL_EXPRs. */
if (insert)
- VARRAY_POP (avail_exprs_stack);
+ VEC_pop (tree_on_heap, avail_exprs_stack);
/* And make sure we record the fact that we modified this
statement. */
if (*slot == NULL)
{
*slot = (void *) element;
- VARRAY_PUSH_TREE (avail_exprs_stack, stmt ? stmt : element->rhs);
+ VEC_safe_push (tree_on_heap, avail_exprs_stack,
+ stmt ? stmt : element->rhs);
return NULL_TREE;
}
VARRAY_GENERIC_PTR_INIT (*vrp_records_p, 2, "vrp records");
VARRAY_PUSH_GENERIC_PTR (*vrp_records_p, element);
- VARRAY_PUSH_TREE (vrp_variables_stack, TREE_OPERAND (cond, 0));
+ VEC_safe_push (tree_on_heap, vrp_variables_stack, TREE_OPERAND (cond, 0));
}
}