2004-05-13 08:41:07 +02:00
|
|
|
/* Generic dominator tree walker
|
2008-06-06 07:42:00 +02:00
|
|
|
Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation,
|
|
|
|
Inc.
|
2004-05-13 08:41:07 +02:00
|
|
|
Contributed by Diego Novillo <dnovillo@redhat.com>
|
|
|
|
|
|
|
|
This file is part of GCC.
|
|
|
|
|
|
|
|
GCC is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2007-07-26 10:37:01 +02:00
|
|
|
the Free Software Foundation; either version 3, or (at your option)
|
2004-05-13 08:41:07 +02:00
|
|
|
any later version.
|
|
|
|
|
|
|
|
GCC is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2007-07-26 10:37:01 +02:00
|
|
|
along with GCC; see the file COPYING3. If not see
|
|
|
|
<http://www.gnu.org/licenses/>. */
|
2004-05-13 08:41:07 +02:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "coretypes.h"
|
|
|
|
#include "tm.h"
|
|
|
|
#include "basic-block.h"
|
|
|
|
#include "domwalk.h"
|
|
|
|
#include "ggc.h"
|
|
|
|
|
2009-11-25 11:55:54 +01:00
|
|
|
/* This file implements a generic walker for dominator trees.
|
2004-05-13 08:41:07 +02:00
|
|
|
|
|
|
|
To understand the dominator walker one must first have a grasp of dominators,
|
|
|
|
immediate dominators and the dominator tree.
|
|
|
|
|
|
|
|
Dominators
|
|
|
|
A block B1 is said to dominate B2 if every path from the entry to B2 must
|
|
|
|
pass through B1. Given the dominance relationship, we can proceed to
|
|
|
|
compute immediate dominators. Note it is not important whether or not
|
|
|
|
our definition allows a block to dominate itself.
|
|
|
|
|
|
|
|
Immediate Dominators:
|
|
|
|
Every block in the CFG has no more than one immediate dominator. The
|
|
|
|
immediate dominator of block BB must dominate BB and must not dominate
|
|
|
|
any other dominator of BB and must not be BB itself.
|
|
|
|
|
|
|
|
Dominator tree:
|
|
|
|
If we then construct a tree where each node is a basic block and there
|
|
|
|
is an edge from each block's immediate dominator to the block itself, then
|
|
|
|
we have a dominator tree.
|
|
|
|
|
|
|
|
|
|
|
|
[ Note this walker can also walk the post-dominator tree, which is
|
alias.c, [...]: Fix comment typos.
* alias.c, crtstuff.c, dbxout.c, domwalk.c, domwalk.h, gcc.c,
gcse.c, global.c, lambda-code.c, loop.c, mips-tdump.c,
optabs.h, predict.c, reg-stack.c, regclass.c, sched-rgn.c,
tree-optimize.c, tree-ssa-dom.c, tree-ssa-forwprop.c,
tree-ssa-operands.c, tree-ssa-phiopt.c,
tree-ssa-threadupdate.c: Fix comment typos.
From-SVN: r87707
2004-09-18 21:47:10 +02:00
|
|
|
defined in a similar manner. i.e., block B1 is said to post-dominate
|
2004-05-13 08:41:07 +02:00
|
|
|
block B2 if all paths from B2 to the exit block must pass through
|
|
|
|
B1. ]
|
|
|
|
|
|
|
|
For example, given the CFG
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
|
2
|
|
|
|
/ \
|
|
|
|
3 4
|
|
|
|
/ \
|
|
|
|
+---------->5 6
|
|
|
|
| / \ /
|
|
|
|
| +--->8 7
|
|
|
|
| | / |
|
|
|
|
| +--9 11
|
|
|
|
| / |
|
|
|
|
+--- 10 ---> 12
|
2009-11-25 11:55:54 +01:00
|
|
|
|
|
|
|
|
2004-05-13 08:41:07 +02:00
|
|
|
We have a dominator tree which looks like
|
|
|
|
|
|
|
|
1
|
|
|
|
|
|
|
|
|
2
|
|
|
|
/ \
|
|
|
|
/ \
|
|
|
|
3 4
|
|
|
|
/ / \ \
|
|
|
|
| | | |
|
|
|
|
5 6 7 12
|
|
|
|
| |
|
|
|
|
8 11
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
2009-11-25 11:55:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2004-05-13 08:41:07 +02:00
|
|
|
The dominator tree is the basis for a number of analysis, transformation
|
|
|
|
and optimization algorithms that operate on a semi-global basis.
|
2009-11-25 11:55:54 +01:00
|
|
|
|
2004-05-13 08:41:07 +02:00
|
|
|
The dominator walker is a generic routine which visits blocks in the CFG
|
|
|
|
via a depth first search of the dominator tree. In the example above
|
|
|
|
the dominator walker might visit blocks in the following order
|
|
|
|
1, 2, 3, 4, 5, 8, 9, 10, 6, 7, 11, 12.
|
2009-11-25 11:55:54 +01:00
|
|
|
|
2004-05-13 08:41:07 +02:00
|
|
|
The dominator walker has a number of callbacks to perform actions
|
|
|
|
during the walk of the dominator tree. There are two callbacks
|
|
|
|
which walk statements, one before visiting the dominator children,
|
2009-11-25 11:55:54 +01:00
|
|
|
one after visiting the dominator children. There is a callback
|
2004-05-13 08:41:07 +02:00
|
|
|
before and after each statement walk callback. In addition, the
|
|
|
|
dominator walker manages allocation/deallocation of data structures
|
|
|
|
which are local to each block visited.
|
2009-11-25 11:55:54 +01:00
|
|
|
|
2004-05-13 08:41:07 +02:00
|
|
|
The dominator walker is meant to provide a generic means to build a pass
|
|
|
|
which can analyze or transform/optimize a function based on walking
|
|
|
|
the dominator tree. One simply fills in the dominator walker data
|
|
|
|
structure with the appropriate callbacks and calls the walker.
|
2009-11-25 11:55:54 +01:00
|
|
|
|
2004-05-13 08:41:07 +02:00
|
|
|
We currently use the dominator walker to prune the set of variables
|
|
|
|
which might need PHI nodes (which can greatly improve compile-time
|
|
|
|
performance in some cases).
|
2009-11-25 11:55:54 +01:00
|
|
|
|
2004-05-13 08:41:07 +02:00
|
|
|
We also use the dominator walker to rewrite the function into SSA form
|
|
|
|
which reduces code duplication since the rewriting phase is inherently
|
|
|
|
a walk of the dominator tree.
|
|
|
|
|
i386.c, [...]: Fix comment typos.
* config/i386/i386.c, config/pa/pa.c, config/spu/spu.c,
df-problems.c, df-scan.c, domwalk.c, ebitmap.c, ebitmap.h,
fold-const.c, gcc.c, ipa-type-escape.c, omega.c, omega.h,
tree-ssa-coalesce.c, tree-ssa-live.c, tree-ssa-structalias.c,
tree-vrp.c: Fix comment typos. Follow spelling conventions.
* doc/tm.texi: Follow spelling conventions.
From-SVN: r125090
2007-05-26 15:00:47 +02:00
|
|
|
And (of course), we use the dominator walker to drive our dominator
|
2004-05-13 08:41:07 +02:00
|
|
|
optimizer, which is a semi-global optimizer.
|
|
|
|
|
|
|
|
TODO:
|
|
|
|
|
|
|
|
Walking statements is based on the block statement iterator abstraction,
|
|
|
|
which is currently an abstraction over walking tree statements. Thus
|
|
|
|
the dominator walker is currently only useful for trees. */
|
|
|
|
|
|
|
|
/* Recursively walk the dominator tree.
|
|
|
|
|
|
|
|
WALK_DATA contains a set of callbacks to perform pass-specific
|
|
|
|
actions during the dominator walk as well as a stack of block local
|
|
|
|
data maintained during the dominator walk.
|
|
|
|
|
|
|
|
BB is the basic block we are currently visiting. */
|
|
|
|
|
|
|
|
void
|
|
|
|
walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
|
|
|
|
{
|
|
|
|
void *bd = NULL;
|
|
|
|
basic_block dest;
|
2006-08-03 23:21:22 +02:00
|
|
|
basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
|
|
|
|
int sp = 0;
|
2010-05-06 11:08:57 +02:00
|
|
|
sbitmap visited = sbitmap_alloc (last_basic_block + 1);
|
|
|
|
sbitmap_zero (visited);
|
|
|
|
SET_BIT (visited, ENTRY_BLOCK_PTR->index);
|
backport: copy-prop, incremental SSA updating of FUD chains and newly exposed symbols.
Merge from tree-cleanup-branch: VRP, store CCP, store
copy-prop, incremental SSA updating of FUD chains and
newly exposed symbols.
* Makefile.in (tree-ssa-copy.o): Depend on tree-ssa-propagate.h.
(OBJS-common): Add tree-vrp.o.
(tree-vrp.o): New rule.
* basic-block.h (nearest_common_dominator_for_set): Declare.
* common.opt (ftree-store-ccp): New flag.
(ftree-copy-prop): New flag.
(ftree-vrp): New flag.
(ftree-store-copy-prop): New flag.
* dominance.c (nearest_common_dominator_for_set): New.
* domwalk.c (walk_dominator_tree): Only traverse
statements in blocks marked in walk_data->interesting_blocks.
* domwalk.h (struct dom_walk_data): Add field interesting_blocks.
* fold-const.c (fold): Handle ASSERT_EXPR.
* opts.c (decode_options): Set flag_tree_copy_prop at -O1.
Set flag_tree_store_ccp, flag_tree_store_copy_prop and
flag_tree_vrp at -O2.
* timevar.def (TV_TREE_VRP): Define.
(TV_TREE_COPY_PROP): Define.
(TV_TREE_STORE_COPY_PROP): Define.
(TV_TREE_SSA_INCREMENTAL): Define.
(TV_TREE_STORE_CCP): Define.
* tree-cfg.c (tree_can_merge_blocks_p): Remove reference
to kill_redundant_phi_nodes from comment.
(verify_expr): Handle ASSERT_EXPR.
* tree-dfa.c (mark_new_vars_to_rename): Remove second
argument. Update all users.
(mark_call_clobbered_vars_to_rename): Remove. Update all
users.
* tree-flow-inline.h (unmodifiable_var_p): New.
* tree-flow.h (enum value_range_type): Declare.
(struct value_range_def): Declare.
(value_range): Declare.
(remove_all_phi_nodes_for): Remove. Update all users.
(find_phi_node_for): Declare.
(add_type_alias): Declare.
(count_uses_and_derefs): Declare.
(kill_redundant_phi_nodes): Remove.
(rewrite_into_ssa): Remove.
(rewrite_def_def_chains): Remove.
(update_ssa, register_new_name_mapping, create_new_def_for,
need_ssa_update_p, name_registered_for_update_p,
release_ssa_name_after_update_ssa, dump_repl_tbl,
debug_repl_tbl, dump_names_replaced_by,
debug_names_replaced_by, mark_sym_for_renaming,
mark_set_for_renaming, get_current_def, set_current_def,
get_value_range, dump_value_range, debug_value_range,
dump_all_value_ranges, debug_all_value_ranges,
expr_computes_nonzero, loop_depth_of_name,
unmodifiable_var_p): Declare.
* tree-gimple.c (is_gimple_formal_tmp_rhs): Handle
ASSERT_EXPR.
* tree-into-ssa.c (block_defs_stack): Update comment.
(old_ssa_names, new_ssa_names, old_virtual_ssa_names,
syms_to_rename, names_to_release, repl_tbl,
need_to_initialize_update_ssa_p, need_to_update_vops_p,
need_to_replace_names_p): New locals.
(NAME_SETS_GROWTH_FACTOR): Define.
(struct repl_map_d): Declare.
(struct mark_def_sites_global_data): Add field
interesting_blocks.
(enum rewrite_mode): Declare.
(REGISTER_DEFS_IN_THIS_STMT): Define.
(compute_global_livein): Use last_basic_block instead of
n_basic_blocks.
(set_def_block): Remove last argument. Update all callers.
(prepare_use_operand_for_rename): Remove. Update all callers.
(prepare_def_operand_for_rename): Remove. Update all callers.
(symbol_marked_for_renaming): New.
(is_old_name): New.
(is_new_name): New.
(repl_map_hash): New.
(repl_map_eq): New.
(repl_map_free): New.
(names_replaced_by): New.
(add_to_repl_tbl): New.
(add_new_name_mapping): New.
(mark_def_sites): Assume that all the operands in the
statement are in normal form.
(find_idf): Assert that the block in the stack is valid.
(get_default_def_for): New.
(insert_phi_nodes_for): Add new argument 'update_p'.
Add documentation.
If update_p is true, add a new mapping between the LHS of
each new PHI and the name that it replaces.
(insert_phi_nodes_1): Only call find_idf if needed.
(get_reaching_def): Call get_default_def_for.
(rewrite_operand): Remove.
(rewrite_stmt): Do nothing if REGISTER_DEFS_IN_THIS_STMT
and REWRITE_THIS_STMT are false.
Assume that all the operands in the statement are in
normal form.
(rewrite_add_phi_arguments): Don't use PHI_REWRITTEN.
(rewrite_virtual_phi_arguments): Remove.
(invalidate_name_tags): Remove.
(register_new_update_single, register_new_update_set,
rewrite_update_init_block, replace_use,
rewrite_update_fini_block, rewrite_update_stmt,
rewrite_update_phi_arguments): New.
rewrite_blocks): Remove argument 'fix_virtual_phis'.
Add arguments 'entry', 'what' and 'blocks'.
Initialize the dominator walker according to 'what' and
'blocks'.
Start the dominator walk at 'entry'.
(mark_def_site_blocks): Add argument 'interesting_blocks'.
Use it to configure the dominator walker.
(rewrite_into_ssa): Remove argument 'all'.
Make internal.
(rewrite_all_into_ssa): Remove.
(rewrite_def_def_chains): Remove.
(mark_def_interesting, mark_use_interesting,
prepare_phi_args_for_update, prepare_block_for_update,
prepare_def_site_for, prepare_def_sites,
dump_names_replaced_by, debug_names_replaced_by,
dump_repl_tbl, debug_repl_tbl, init_update_ssa,
delete_update_ssa, create_new_def_for,
register_new_name_mapping, mark_sym_for_renaming,
mark_set_for_renaming, need_ssa_update_p,
name_registered_for_update_p, ssa_names_to_replace,
release_ssa_name_after_update_ssa,
insert_updated_phi_nodes_for, update_ssa): New.
* tree-loop-linear.c (linear_transform_loops): Call
update_ssa instead of rewrite_into_ssa.
* tree-optimize.c (vars_to_rename): Remove.
Update all users.
(init_tree_optimization_passes): Replace
pass_redundant_phi with pass_copy_prop.
Add pass_vrp.
Replace pass_ccp with pass_store_ccp.
Add pass_store_copy_prop after pass_store_ccp.
(execute_todo): If the TODO_ flags don't include updating
the SSA form, assert that it does not need to be updated.
Call update_ssa instead of rewrite_into_ssa and
rewrite_def_def_chains.
If TODO_verify_loops is set, call verify_loop_closed_ssa.
(tree_rest_of_compilation):
* tree-pass.h (TODO_dump_func, TODO_ggc_collect,
TODO_verify_ssa, TODO_verify_flow, TODO_verify_stmts,
TODO_cleanup_cfg): Renumber.
(TODO_verify_loops, TODO_update_ssa,
TODO_update_ssa_no_phi, TODO_update_ssa_full_phi,
TODO_update_ssa_only_virtuals): Define.
(pass_copy_prop, pass_store_ccp, pass_store_copy_prop, pass_vrp):
Declare.
* tree-phinodes.c (make_phi_node): Update documentation.
(remove_all_phi_nodes_for): Remove.
(find_phi_node_for): New.
* tree-pretty-print.c (dump_generic_node): Handle ASSERT_EXPR.
* tree-scalar-evolution.c (follow_ssa_edge_in_rhs): Likewise.
(interpret_rhs_modify_expr): Likewise.
* tree-sra.c (decide_instantiations): Mark all symbols in
SRA_CANDIDATES for renaming.
(mark_all_v_defs_1): Rename from mark_all_v_defs.
(mark_all_v_defs): New function. Update all users to call it
with the whole list of scalarized statements, not just the
first one.
* tree-ssa-alias.c (count_ptr_derefs): Make extern.
(compute_flow_insensitive_aliasing): If the tag is
unmodifiable and the variable isn't or vice-versa, don't
make them alias of each other.
(setup_pointers_and_addressables): If the type tag for
VAR is about to change, mark the old one for renaming.
(add_type_alias): New.
* tree-ssa-ccp.c: Document SSA-CCP and STORE-CCP.
(ccp_lattice_t): Rename from latticevalue.
(value): Remove. Update all users.
(const_val): New local variable.
(do_store_ccp): New local variable.
(dump_lattice_value): Handle UNINITIALIZED.
(debug_lattice_value): New.
(get_default_value): Re-write.
(set_lattice_value): Re-write.
(def_to_varying): Remove. Update all users.
(likely_value): Return VARYING for statements that make
stores when STORE_CCP is false.
Return VARYING for any statement other than MODIFY_EXPR,
COND_EXPR and SWITCH_EXPR.
(ccp_initialize): Re-write.
(replace_uses_in, replace_vuse_in, substitute_and_fold):
Move to tree-ssa-propagate.c.
(ccp_lattice_meet): Handle memory stores when
DO_STORE_CCP is true.
(ccp_visit_phi_node): Likewise.
(ccp_fold): Likewise.
(evaluate_stmt): Likewise.
(visit_assignment): Likewise.
(ccp_visit_stmt): Likewise.
(execute_ssa_ccp): Add argument 'store_ccp'. Copy it
into DO_STORE_CCP.
(do_ssa_ccp): New.
(pass_ccp): Use it.
(do_ssa_store_ccp): New.
(gate_store_ccp): New.
(pass_store_ccp): Declare.
* tree-ssa-copy.c: Include tree-ssa-propagate.h.
(may_propagate_copy): Reformat.
Don't abort if ORIG is a virtual and DEST isn't.
If NEW does not have alias information but DEST does,
copy it.
(copy_of, cached_last_copy_of, do_store_copy_prop, enum
copy_prop_kind, which_copy_prop): Declare.
(stmt_may_generate_copy, get_copy_of_val,
get_last_copy_of, set_copy_of_val, dump_copy_of,
copy_prop_visit_assignment, copy_prop_visit_cond_stmt,
copy_prop_visit_stmt, copy_prop_visit_phi_node,
init_copy_prop, fini_copy_prop, execute_copy_prop,
gate_copy_prop, do_copy_prop, gate_store_copy_prop,
store_copy_prop): New.
(pass_copy_prop, pass_store_copy_prop): Declare.
* tree-ssa-dom.c (struct opt_stats_d): Add fields
'num_const_prop' and 'num_copy_prop'.
(cprop_operand): Update them.
(dump_dominator_optimization_stats): Dump them.
(tree_ssa_dominator_optimize): Call update_ssa instead of
rewrite_into_ssa.
(loop_depth_of_name): Declare extern.
(simplify_cond_and_lookup_avail_expr): Guard against NULL
values for LOW or HIGH.
(cprop_into_successor_phis): Only propagate if NEW != ORIG.
(record_equivalences_from_stmt): Call expr_computes_nonzero.
(cprop_operand): Only propagate if VAL != OP.
* tree-ssa-dse.c (dse_optimize_stmt): Mark symbols in removed
statement for renaming.
* tree-ssa-loop-im.c (move_computations): Call update_ssa.
* tree-ssa-loop-ivopts.c (rewrite_address_base): Call
add_type_alias if necessary.
Call mark_new_vars_to_rename.
(tree_ssa_iv_optimize): If new symbols need to be renamed,
mark every statement updated, call update_ssa and
rewrite_into_loop_closed_ssa.
* tree-ssa-loop-manip.c (add_exit_phis): Do not remove DEF_BB
from LIVEIN if VAR is a virtual.
* tree-ssa-loop.c (tree_loop_optimizer_init): Call update_ssa.
* tree-ssa-operands.c (get_expr_operands): Handle ASSERT_EXPR.
(get_call_expr_operands): Reformat statement.
(add_stmt_operand): Don't create V_MAY_DEFs for read-only
symbols.
* tree-ssa-propagate.c (ssa_prop_init): Initialize
SSA_NAME_VALUE for every name.
(first_vdef, stmt_makes_single_load, stmt_makes_single_store,
get_value_loaded_by): New.
(replace_uses_in, replace_vuses_in, replace_phi_args_in,
substitute_and_fold): Move from tree-ssa-ccp.c.
* tree-ssa-propagate.h (struct prop_value_d, prop_value_t,
first_vdef, stmt_makes_single_load, stmt_makes_single_store,
get_value_loaded_by, replace_uses_in, substitute_and_fold):
Declare.
* tree-ssa.c (verify_use): Fix error message.
(propagate_into_addr, replace_immediate_uses, get_eq_name,
check_phi_redundancy, kill_redundant_phi_nodes,
pass_redundant_phi): Remove. Update all users.
* tree-vect-transform.c (vect_create_data_ref_ptr): Call
add_type_alias, if necessary.
* tree-vectorizer.h (struct _stmt_vect_info): Update
documentation for field 'memtag'.
* tree-vrp.c: New file.
* tree.def (ASSERT_EXPR): Define.
* tree.h (ASSERT_EXPR_VAR): Define.
(ASSERT_EXPR_COND): Define.
(SSA_NAME_VALUE_RANGE): Define.
(struct tree_ssa_name): Add field 'value_range'.
(PHI_REWRITTEN): Remove.
(struct tree_phi_node): Remove field 'rewritten'.
* doc/invoke.texi (-fdump-tree-storeccp, -ftree-copy-prop,
-ftree-store-copy-prop): Document.
* doc/tree-ssa.texi: Remove broken link to McCAT's compiler.
Document usage of update_ssa.
testsuite/ChangeLog
* g++.dg/tree-ssa/pr18178.C: New test.
* gcc.c-torture/execute/20030216-1.x: Ignore at -O1.
* gcc.c-torture/execute/20041019-1.c: New test.
* gcc.dg/tree-ssa/20041008-1.c: New test.
* gcc.dg/tree-ssa/ssa-ccp-12.c: New test.
* gcc.dg/tree-ssa/20030731-2.c: Update to use -fdump-tree-store_ccp.
* gcc.dg/tree-ssa/20030917-1.c: Likewise.
* gcc.dg/tree-ssa/20030917-3.c: Likewise.
* gcc.dg/tree-ssa/20040721-1.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-1.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-2.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-3.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-7.c: Likewise.
* gcc.dg/tree-ssa/ssa-ccp-9.c: Likewise.
From-SVN: r97884
2005-04-09 03:37:54 +02:00
|
|
|
|
2006-08-03 23:21:22 +02:00
|
|
|
while (true)
|
2004-05-13 08:41:07 +02:00
|
|
|
{
|
2006-08-03 23:21:22 +02:00
|
|
|
/* Don't worry about unreachable blocks. */
|
2007-09-06 11:05:58 +02:00
|
|
|
if (EDGE_COUNT (bb->preds) > 0
|
|
|
|
|| bb == ENTRY_BLOCK_PTR
|
|
|
|
|| bb == EXIT_BLOCK_PTR)
|
2004-05-13 08:41:07 +02:00
|
|
|
{
|
2006-08-03 23:21:22 +02:00
|
|
|
/* Callback to initialize the local data structure. */
|
|
|
|
if (walk_data->initialize_block_local_data)
|
|
|
|
{
|
|
|
|
bool recycled;
|
|
|
|
|
2008-07-28 16:33:56 +02:00
|
|
|
/* First get some local data, reusing any local data
|
|
|
|
pointer we may have saved. */
|
2006-08-03 23:21:22 +02:00
|
|
|
if (VEC_length (void_p, walk_data->free_block_data) > 0)
|
|
|
|
{
|
|
|
|
bd = VEC_pop (void_p, walk_data->free_block_data);
|
|
|
|
recycled = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bd = xcalloc (1, walk_data->block_local_data_size);
|
|
|
|
recycled = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Push the local data into the local data stack. */
|
|
|
|
VEC_safe_push (void_p, heap, walk_data->block_data_stack, bd);
|
|
|
|
|
|
|
|
/* Call the initializer. */
|
|
|
|
walk_data->initialize_block_local_data (walk_data, bb,
|
|
|
|
recycled);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Callback for operations to execute before we have walked the
|
|
|
|
dominator children, but before we walk statements. */
|
domwalk.h (struct dom_walk_data): Remove all callbacks except before_dom_children_before_stmts and...
2009-06-27 Paolo Bonzini <bonzini@gnu.org>
* domwalk.h (struct dom_walk_data): Remove all callbacks except
before_dom_children_before_stmts and after_dom_children_after_stmts.
Rename the two remaining callbacks to just before_dom_children and
after_dom_children. Remove other GIMPLE statement walking bits.
* domwalk.c (walk_dominator_tree): Remove now unsupported features.
* graphite.c: Do not include domwalk.h.
* tree-into-ssa.c (interesting_blocks): New global.
(struct mark_def_sites_global_data): Remove it and names_to_rename.
(mark_def_sites, rewrite_stmt, rewrite_add_phi_arguments,
rewrite_update_stmt, rewrite_update_phi_arguments): Simplify
now that they're not domwalk callbacks.
(rewrite_initialize_block): Rename to...
(rewrite_enter_block): ... this, place after called functions. Test
interesting_blocks, call rewrite_stmt and rewrite_add_phi_arguments.
(rewrite_finalize_block): Rename to...
(rewrite_leave_block): ... this, place after called functions.
(rewrite_update_init_block): Rename to...
(rewrite_update_enter_block): ... this, place after called functions.
Test interesting_blocks, call rewrite_update_stmt and
rewrite_update_phi_arguments.
(rewrite_update_fini_block): Rename to...
(rewrite_leave_block): ... this, place after called functions.
(rewrite_blocks): Remove last argument, simplify initialization of
walk_data.
(mark_def_sites_initialize_block): Rename to...
(mark_def_sites_block): ... this, call mark_def_sites.
(mark_def_sites_blocks): Remove argument, simplify initialization of
walk_data.
(rewrite_into_ssa): Adjust for interesting_blocks_being a global.
(update_ssa): Likewise.
* tree-ssa-dom.c (optimize_stmt): Simplify now that it's not a domwalk
callback.
(tree_ssa_dominator_optimize): Simplify initialization of walk_data.
(dom_opt_initialize_block): Rename to...
(dom_opt_enter_block): ... this, place after called functions. Walk
statements here, inline propagate_to_outgoing_edges.
(dom_opt_finalize_block): Rename to...
(dom_opt_leave_block): ... this, place after called functions.
* tree-ssa-dse.c (dse_optimize_stmt): Simplify now that it's not a
domwalk callback.
(dse_enter_block, dse_record_phi): New.
(dse_record_phis): Delete.
(dse_finalize_block): Rename to...
(dse_leave_block): ... this.
(tree_ssa_dse): Simplify initialization of walk_data.
* tree-ssa-loop-im.c (determine_invariantness, move_computations):
Adjust initialization of walk_data.
* tree-ssa-loop-unswitch.c: Do not include domwalk.h.
* tree-ssa-loop-phiopt.c (get_non_trapping):
Adjust initialization of walk_data.
* tree-ssa-loop-threadedge.c: Do not include domwalk.h.
* tree-ssa-uncprop.c (uncprop_into_successor_phis): Simplify now that
it's not a domwalk callback.
(uncprop_initialize_block): Rename to...
(dse_enter_block): ... this, call uncprop_into_successor_phis.
(dse_finalize_block): Rename to...
(dse_leave_block): ... this.
(tree_ssa_uncprop): Simplify initialization of walk_data.
* Makefile.in: Adjust dependencies.
From-SVN: r149008
2009-06-27 16:45:51 +02:00
|
|
|
if (walk_data->before_dom_children)
|
|
|
|
(*walk_data->before_dom_children) (walk_data, bb);
|
2006-08-03 23:21:22 +02:00
|
|
|
|
2010-05-06 11:08:57 +02:00
|
|
|
SET_BIT (visited, bb->index);
|
|
|
|
|
2006-08-03 23:21:22 +02:00
|
|
|
/* Mark the current BB to be popped out of the recursion stack
|
2008-06-06 07:42:00 +02:00
|
|
|
once children are processed. */
|
2006-08-03 23:21:22 +02:00
|
|
|
worklist[sp++] = bb;
|
|
|
|
worklist[sp++] = NULL;
|
|
|
|
|
|
|
|
for (dest = first_dom_son (walk_data->dom_direction, bb);
|
|
|
|
dest; dest = next_dom_son (walk_data->dom_direction, dest))
|
|
|
|
worklist[sp++] = dest;
|
2004-05-13 08:41:07 +02:00
|
|
|
}
|
domwalk.h (struct dom_walk_data): Remove all callbacks except before_dom_children_before_stmts and...
2009-06-27 Paolo Bonzini <bonzini@gnu.org>
* domwalk.h (struct dom_walk_data): Remove all callbacks except
before_dom_children_before_stmts and after_dom_children_after_stmts.
Rename the two remaining callbacks to just before_dom_children and
after_dom_children. Remove other GIMPLE statement walking bits.
* domwalk.c (walk_dominator_tree): Remove now unsupported features.
* graphite.c: Do not include domwalk.h.
* tree-into-ssa.c (interesting_blocks): New global.
(struct mark_def_sites_global_data): Remove it and names_to_rename.
(mark_def_sites, rewrite_stmt, rewrite_add_phi_arguments,
rewrite_update_stmt, rewrite_update_phi_arguments): Simplify
now that they're not domwalk callbacks.
(rewrite_initialize_block): Rename to...
(rewrite_enter_block): ... this, place after called functions. Test
interesting_blocks, call rewrite_stmt and rewrite_add_phi_arguments.
(rewrite_finalize_block): Rename to...
(rewrite_leave_block): ... this, place after called functions.
(rewrite_update_init_block): Rename to...
(rewrite_update_enter_block): ... this, place after called functions.
Test interesting_blocks, call rewrite_update_stmt and
rewrite_update_phi_arguments.
(rewrite_update_fini_block): Rename to...
(rewrite_leave_block): ... this, place after called functions.
(rewrite_blocks): Remove last argument, simplify initialization of
walk_data.
(mark_def_sites_initialize_block): Rename to...
(mark_def_sites_block): ... this, call mark_def_sites.
(mark_def_sites_blocks): Remove argument, simplify initialization of
walk_data.
(rewrite_into_ssa): Adjust for interesting_blocks_being a global.
(update_ssa): Likewise.
* tree-ssa-dom.c (optimize_stmt): Simplify now that it's not a domwalk
callback.
(tree_ssa_dominator_optimize): Simplify initialization of walk_data.
(dom_opt_initialize_block): Rename to...
(dom_opt_enter_block): ... this, place after called functions. Walk
statements here, inline propagate_to_outgoing_edges.
(dom_opt_finalize_block): Rename to...
(dom_opt_leave_block): ... this, place after called functions.
* tree-ssa-dse.c (dse_optimize_stmt): Simplify now that it's not a
domwalk callback.
(dse_enter_block, dse_record_phi): New.
(dse_record_phis): Delete.
(dse_finalize_block): Rename to...
(dse_leave_block): ... this.
(tree_ssa_dse): Simplify initialization of walk_data.
* tree-ssa-loop-im.c (determine_invariantness, move_computations):
Adjust initialization of walk_data.
* tree-ssa-loop-unswitch.c: Do not include domwalk.h.
* tree-ssa-loop-phiopt.c (get_non_trapping):
Adjust initialization of walk_data.
* tree-ssa-loop-threadedge.c: Do not include domwalk.h.
* tree-ssa-uncprop.c (uncprop_into_successor_phis): Simplify now that
it's not a domwalk callback.
(uncprop_initialize_block): Rename to...
(dse_enter_block): ... this, call uncprop_into_successor_phis.
(dse_finalize_block): Rename to...
(dse_leave_block): ... this.
(tree_ssa_uncprop): Simplify initialization of walk_data.
* Makefile.in: Adjust dependencies.
From-SVN: r149008
2009-06-27 16:45:51 +02:00
|
|
|
/* NULL is used to mark pop operations in the recursion stack. */
|
2006-08-03 23:21:22 +02:00
|
|
|
while (sp > 0 && !worklist[sp - 1])
|
2004-05-13 08:41:07 +02:00
|
|
|
{
|
2006-08-03 23:21:22 +02:00
|
|
|
--sp;
|
|
|
|
bb = worklist[--sp];
|
|
|
|
|
|
|
|
/* Callback for operations to execute after we have walked the
|
domwalk.h (struct dom_walk_data): Remove all callbacks except before_dom_children_before_stmts and...
2009-06-27 Paolo Bonzini <bonzini@gnu.org>
* domwalk.h (struct dom_walk_data): Remove all callbacks except
before_dom_children_before_stmts and after_dom_children_after_stmts.
Rename the two remaining callbacks to just before_dom_children and
after_dom_children. Remove other GIMPLE statement walking bits.
* domwalk.c (walk_dominator_tree): Remove now unsupported features.
* graphite.c: Do not include domwalk.h.
* tree-into-ssa.c (interesting_blocks): New global.
(struct mark_def_sites_global_data): Remove it and names_to_rename.
(mark_def_sites, rewrite_stmt, rewrite_add_phi_arguments,
rewrite_update_stmt, rewrite_update_phi_arguments): Simplify
now that they're not domwalk callbacks.
(rewrite_initialize_block): Rename to...
(rewrite_enter_block): ... this, place after called functions. Test
interesting_blocks, call rewrite_stmt and rewrite_add_phi_arguments.
(rewrite_finalize_block): Rename to...
(rewrite_leave_block): ... this, place after called functions.
(rewrite_update_init_block): Rename to...
(rewrite_update_enter_block): ... this, place after called functions.
Test interesting_blocks, call rewrite_update_stmt and
rewrite_update_phi_arguments.
(rewrite_update_fini_block): Rename to...
(rewrite_leave_block): ... this, place after called functions.
(rewrite_blocks): Remove last argument, simplify initialization of
walk_data.
(mark_def_sites_initialize_block): Rename to...
(mark_def_sites_block): ... this, call mark_def_sites.
(mark_def_sites_blocks): Remove argument, simplify initialization of
walk_data.
(rewrite_into_ssa): Adjust for interesting_blocks_being a global.
(update_ssa): Likewise.
* tree-ssa-dom.c (optimize_stmt): Simplify now that it's not a domwalk
callback.
(tree_ssa_dominator_optimize): Simplify initialization of walk_data.
(dom_opt_initialize_block): Rename to...
(dom_opt_enter_block): ... this, place after called functions. Walk
statements here, inline propagate_to_outgoing_edges.
(dom_opt_finalize_block): Rename to...
(dom_opt_leave_block): ... this, place after called functions.
* tree-ssa-dse.c (dse_optimize_stmt): Simplify now that it's not a
domwalk callback.
(dse_enter_block, dse_record_phi): New.
(dse_record_phis): Delete.
(dse_finalize_block): Rename to...
(dse_leave_block): ... this.
(tree_ssa_dse): Simplify initialization of walk_data.
* tree-ssa-loop-im.c (determine_invariantness, move_computations):
Adjust initialization of walk_data.
* tree-ssa-loop-unswitch.c: Do not include domwalk.h.
* tree-ssa-loop-phiopt.c (get_non_trapping):
Adjust initialization of walk_data.
* tree-ssa-loop-threadedge.c: Do not include domwalk.h.
* tree-ssa-uncprop.c (uncprop_into_successor_phis): Simplify now that
it's not a domwalk callback.
(uncprop_initialize_block): Rename to...
(dse_enter_block): ... this, call uncprop_into_successor_phis.
(dse_finalize_block): Rename to...
(dse_leave_block): ... this.
(tree_ssa_uncprop): Simplify initialization of walk_data.
* Makefile.in: Adjust dependencies.
From-SVN: r149008
2009-06-27 16:45:51 +02:00
|
|
|
dominator children, but before we walk statements. */
|
|
|
|
if (walk_data->after_dom_children)
|
|
|
|
(*walk_data->after_dom_children) (walk_data, bb);
|
2006-08-03 23:21:22 +02:00
|
|
|
|
|
|
|
if (walk_data->initialize_block_local_data)
|
|
|
|
{
|
|
|
|
/* And finally pop the record off the block local data stack. */
|
|
|
|
bd = VEC_pop (void_p, walk_data->block_data_stack);
|
|
|
|
/* And save the block data so that we can re-use it. */
|
|
|
|
VEC_safe_push (void_p, heap, walk_data->free_block_data, bd);
|
|
|
|
}
|
2004-05-13 08:41:07 +02:00
|
|
|
}
|
2006-08-03 23:21:22 +02:00
|
|
|
if (sp)
|
2010-05-06 11:08:57 +02:00
|
|
|
{
|
|
|
|
int spp;
|
|
|
|
spp = sp - 1;
|
|
|
|
if (walk_data->dom_direction == CDI_DOMINATORS)
|
|
|
|
/* Find the dominator son that has all its predecessors
|
|
|
|
visited and continue with that. */
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
edge_iterator ei;
|
|
|
|
edge e;
|
|
|
|
bool found = true;
|
|
|
|
bb = worklist[spp];
|
|
|
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
|
|
|
{
|
|
|
|
if (!dominated_by_p (CDI_DOMINATORS, e->src, e->dest)
|
|
|
|
&& !TEST_BIT (visited, e->src->index))
|
|
|
|
{
|
|
|
|
found = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found)
|
|
|
|
break;
|
|
|
|
/* If we didn't find a dom child with all visited
|
|
|
|
predecessors just use the candidate we were checking.
|
|
|
|
This happens for candidates in irreducible loops. */
|
|
|
|
if (!worklist[spp - 1])
|
|
|
|
break;
|
|
|
|
--spp;
|
|
|
|
}
|
|
|
|
bb = worklist[spp];
|
|
|
|
worklist[spp] = worklist[--sp];
|
|
|
|
}
|
2004-05-13 08:41:07 +02:00
|
|
|
else
|
2006-08-03 23:21:22 +02:00
|
|
|
break;
|
2004-05-13 08:41:07 +02:00
|
|
|
}
|
2006-08-03 23:21:22 +02:00
|
|
|
free (worklist);
|
2010-05-06 11:08:57 +02:00
|
|
|
sbitmap_free (visited);
|
2004-05-13 08:41:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
init_walk_dominator_tree (struct dom_walk_data *walk_data)
|
|
|
|
{
|
2005-05-28 00:43:05 +02:00
|
|
|
walk_data->free_block_data = NULL;
|
|
|
|
walk_data->block_data_stack = NULL;
|
2004-05-13 08:41:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
fini_walk_dominator_tree (struct dom_walk_data *walk_data)
|
|
|
|
{
|
|
|
|
if (walk_data->initialize_block_local_data)
|
|
|
|
{
|
2005-05-28 00:43:05 +02:00
|
|
|
while (VEC_length (void_p, walk_data->free_block_data) > 0)
|
|
|
|
free (VEC_pop (void_p, walk_data->free_block_data));
|
2004-05-13 08:41:07 +02:00
|
|
|
}
|
2005-05-28 00:43:05 +02:00
|
|
|
|
|
|
|
VEC_free (void_p, heap, walk_data->free_block_data);
|
|
|
|
VEC_free (void_p, heap, walk_data->block_data_stack);
|
2004-05-13 08:41:07 +02:00
|
|
|
}
|