compare-elim.c (find_comparison_dom_walker): New class
* compare-elim.c (find_comparison_dom_walker): New class (find_comparisons_in_bb): Rename to find_comparison_dom_walker::before_dom_children (find_comparisons): Adjust * domwalk.c (walk_dominator_tree): Rename to dom_walker::walk, and adjust. (init_walk_dominator_tree, fini_walk_dominator_tree): Remove * domwalk.h (dom_walk_data): Convert it To a class dom_walker. (init_walk_dominator_tree): Remove declaration. (fini_walk_dominator_tree): Remove declaration. * fwprop.c (single_def_use_dom_walker): New class (single_def_use_enter_block): Convert to single_def_use_dom_walker::before_dom_children. (single_def_use_leave_block): Convert to single_def_use_dom_walker::after_dom_children. (build_single_def_use_links): Adjust. * gimple-ssa-strength-reduction.c (find_candidates_dom_walker): New class. (find_candidates_in_block): Convert to find_candidates_dom_walker::before_dom_children. (execute_strength_reduction): Adjust. * graphite-sese-to-poly.c (struct bsc, build_sese_conditions): Remove. (sese_dom_walker): New class. (sese_dom_walker::sese_dom_walker): New constructor. (sese_dom_walker::~sese_dom_walker): New destructor. (build_sese_conditions_before): Convert to sese_dom_walker::before_dom_children. (build_sese_conditions_after): Convert to sese_dom_walker::after_dom_children. (build_poly_scop): Adjust * tree-into-ssa.c (rewrite_dom_walker): New class (rewrite_enter_block): Convert to rewrite_dom_walker::before_dom_children. (rewrite_leave_block): Convert to rewrite_dom_walker::after_dom_children. (rewrite_update_dom_walker): New class. (rewrite_update_enter_block): Convert to rewrite_update_dom_walker::before_dom_children. (rewrite_update_leave_block): Convert to rewrite_update_dom_walker::after_dom_children. (rewrite_blocks, rewrite_into_ssa): Adjust. (mark_def_dom_walker): New class. (mark_def_dom_walker::mark_def_dom_walker): New constructor. (mark_def_dom_walker::~mark_def_dom_walker): New destructor. (mark_def_sites_blocks): Convert to mark_def_dom_walker::before_dom_children. (mark_def_site_blocks): Remove. * tree-ssa-dom.c (dom_opt_dom_walker): New class. (tree_ssa_dominator_optimize): Adjust. (dom_thread_across_edge): Convert to method dom_opt_dom_walker::thread_across_edge. (dom_opt_enter_block): Convert to member function dom_opt_dom_walker::before_dom_children. (dom_opt_leave_block): Convert to member function dom_opt_dom_walker::after_dom_children. * tree-ssa-dse.c (dse_dom_walker): New class. (dse_enter_block): Convert to member function dse_dom_walker::before_dom_children. (tree_ssa_dse): Adjust. * tree-ssa-loop-im.c (invariantness_dom_walker): New class. (determine_invariantness_stmt): Convert to method invariantness_dom_walker::before_dom_children. (determine_invariantness): Remove (move_computations_dom_walker): New class. (move_computations_stmt): Convert to method move_computations_dom_walker::before_dom_children. (move_computations, tree_ssa_lim): Adjust. * tree-ssa-phiopt.c (nontrapping_dom_walker): new class (nt_init_block): Make method notrappping_dom_walker::before_dom_children. (nt_fini_block): Make method nontrapping_dom_walker::after_dom_children. (get_non_trapping): Adjust. * tree-ssa-pre.c (eliminate_dom_walker): New class. (eliminate_bb): Make method eliminate_dom_walker::before_dom_children. (eliminate_leave_block): Make method. eliminate_dom_walker::after_dom_children. (eliminate): Adjust * tree-ssa-strlen.c (strlen_dom_walker): New class. (strlen_enter_block): Make method strlen_dom_walker::before_dom_children. (strlen_leave_block): Make method strlen_dom_walker::after_dom_children. (tree_ssa_strlen): Adjust. * tree-ssa-uncprop.c (uncprop_dom_walker): New class. (tree_ssa_uncprop): Adjust. (uncprop_leave_block): Make method uncprop_dom_walker::after_dom_children. (uncprop_leave_block): Make method uncprop_dom_walker::before_dom_children. From-SVN: r202679
This commit is contained in:
parent
3b3cc26bcc
commit
4d9192b50c
@ -1,3 +1,96 @@
|
||||
2013-09-17 Trevor Saunders <tsaunders@mozilla.com>
|
||||
|
||||
* compare-elim.c (find_comparison_dom_walker): New class
|
||||
(find_comparisons_in_bb): Rename to
|
||||
find_comparison_dom_walker::before_dom_children
|
||||
(find_comparisons): Adjust
|
||||
* domwalk.c (walk_dominator_tree): Rename to dom_walker::walk, and
|
||||
adjust.
|
||||
(init_walk_dominator_tree, fini_walk_dominator_tree): Remove
|
||||
* domwalk.h (dom_walk_data): Convert it To a class dom_walker.
|
||||
(init_walk_dominator_tree): Remove declaration.
|
||||
(fini_walk_dominator_tree): Remove declaration.
|
||||
* fwprop.c (single_def_use_dom_walker): New class
|
||||
(single_def_use_enter_block): Convert to
|
||||
single_def_use_dom_walker::before_dom_children.
|
||||
(single_def_use_leave_block): Convert to
|
||||
single_def_use_dom_walker::after_dom_children.
|
||||
(build_single_def_use_links): Adjust.
|
||||
* gimple-ssa-strength-reduction.c (find_candidates_dom_walker): New
|
||||
class.
|
||||
(find_candidates_in_block): Convert to
|
||||
find_candidates_dom_walker::before_dom_children.
|
||||
(execute_strength_reduction): Adjust.
|
||||
* graphite-sese-to-poly.c (struct bsc, build_sese_conditions): Remove.
|
||||
(sese_dom_walker): New class.
|
||||
(sese_dom_walker::sese_dom_walker): New constructor.
|
||||
(sese_dom_walker::~sese_dom_walker): New destructor.
|
||||
(build_sese_conditions_before): Convert to
|
||||
sese_dom_walker::before_dom_children.
|
||||
(build_sese_conditions_after): Convert to
|
||||
sese_dom_walker::after_dom_children.
|
||||
(build_poly_scop): Adjust
|
||||
* tree-into-ssa.c (rewrite_dom_walker): New class
|
||||
(rewrite_enter_block): Convert to
|
||||
rewrite_dom_walker::before_dom_children.
|
||||
(rewrite_leave_block): Convert to
|
||||
rewrite_dom_walker::after_dom_children.
|
||||
(rewrite_update_dom_walker): New class.
|
||||
(rewrite_update_enter_block): Convert to
|
||||
rewrite_update_dom_walker::before_dom_children.
|
||||
(rewrite_update_leave_block): Convert to
|
||||
rewrite_update_dom_walker::after_dom_children.
|
||||
(rewrite_blocks, rewrite_into_ssa): Adjust.
|
||||
(mark_def_dom_walker): New class.
|
||||
(mark_def_dom_walker::mark_def_dom_walker): New constructor.
|
||||
(mark_def_dom_walker::~mark_def_dom_walker): New destructor.
|
||||
(mark_def_sites_blocks): Convert to
|
||||
mark_def_dom_walker::before_dom_children.
|
||||
(mark_def_site_blocks): Remove.
|
||||
* tree-ssa-dom.c (dom_opt_dom_walker): New class.
|
||||
(tree_ssa_dominator_optimize): Adjust.
|
||||
(dom_thread_across_edge): Convert to method
|
||||
dom_opt_dom_walker::thread_across_edge.
|
||||
(dom_opt_enter_block): Convert to member function
|
||||
dom_opt_dom_walker::before_dom_children.
|
||||
(dom_opt_leave_block): Convert to member function
|
||||
dom_opt_dom_walker::after_dom_children.
|
||||
* tree-ssa-dse.c (dse_dom_walker): New class.
|
||||
(dse_enter_block): Convert to member function
|
||||
dse_dom_walker::before_dom_children.
|
||||
(tree_ssa_dse): Adjust.
|
||||
* tree-ssa-loop-im.c (invariantness_dom_walker): New class.
|
||||
(determine_invariantness_stmt): Convert to method
|
||||
invariantness_dom_walker::before_dom_children.
|
||||
(determine_invariantness): Remove
|
||||
(move_computations_dom_walker): New class.
|
||||
(move_computations_stmt): Convert to method
|
||||
move_computations_dom_walker::before_dom_children.
|
||||
(move_computations, tree_ssa_lim): Adjust.
|
||||
* tree-ssa-phiopt.c (nontrapping_dom_walker): new class
|
||||
(nt_init_block): Make method
|
||||
notrappping_dom_walker::before_dom_children.
|
||||
(nt_fini_block): Make
|
||||
method nontrapping_dom_walker::after_dom_children.
|
||||
(get_non_trapping): Adjust.
|
||||
* tree-ssa-pre.c (eliminate_dom_walker): New class.
|
||||
(eliminate_bb): Make method eliminate_dom_walker::before_dom_children.
|
||||
(eliminate_leave_block): Make method.
|
||||
eliminate_dom_walker::after_dom_children.
|
||||
(eliminate): Adjust
|
||||
* tree-ssa-strlen.c (strlen_dom_walker): New class.
|
||||
(strlen_enter_block): Make method
|
||||
strlen_dom_walker::before_dom_children.
|
||||
(strlen_leave_block): Make
|
||||
method strlen_dom_walker::after_dom_children.
|
||||
(tree_ssa_strlen): Adjust.
|
||||
* tree-ssa-uncprop.c (uncprop_dom_walker): New class.
|
||||
(tree_ssa_uncprop): Adjust.
|
||||
(uncprop_leave_block): Make method
|
||||
uncprop_dom_walker::after_dom_children.
|
||||
(uncprop_leave_block): Make method
|
||||
uncprop_dom_walker::before_dom_children.
|
||||
|
||||
2013-09-18 Bin Cheng <bin.cheng@arm.com>
|
||||
|
||||
* config/arm/arm.c (thumb1_reorg): Search for flag setting insn
|
||||
|
@ -243,13 +243,21 @@ find_flags_uses_in_insn (struct comparison *cmp, rtx insn)
|
||||
cmp->missing_uses = true;
|
||||
}
|
||||
|
||||
class find_comparison_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
find_comparison_dom_walker (cdi_direction direction)
|
||||
: dom_walker(direction) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
};
|
||||
|
||||
/* Identify comparison instructions within BB. If the flags from the last
|
||||
compare in the BB is live at the end of the block, install the compare
|
||||
in BB->AUX. Called via walk_dominators_tree. */
|
||||
in BB->AUX. Called via dom_walker.walk (). */
|
||||
|
||||
static void
|
||||
find_comparisons_in_bb (struct dom_walk_data *data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
find_comparison_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
struct comparison *last_cmp;
|
||||
rtx insn, next, last_clobber;
|
||||
@ -403,17 +411,10 @@ find_comparisons_in_bb (struct dom_walk_data *data ATTRIBUTE_UNUSED,
|
||||
static void
|
||||
find_comparisons (void)
|
||||
{
|
||||
struct dom_walk_data data;
|
||||
|
||||
memset (&data, 0, sizeof(data));
|
||||
data.dom_direction = CDI_DOMINATORS;
|
||||
data.before_dom_children = find_comparisons_in_bb;
|
||||
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
init_walk_dominator_tree (&data);
|
||||
walk_dominator_tree (&data, ENTRY_BLOCK_PTR);
|
||||
fini_walk_dominator_tree (&data);
|
||||
find_comparison_dom_walker (CDI_DOMINATORS)
|
||||
.walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
clear_aux_for_blocks ();
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
|
@ -144,23 +144,17 @@ cmp_bb_postorder (const void *a, const void *b)
|
||||
}
|
||||
|
||||
/* 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)
|
||||
dom_walker::walk (basic_block bb)
|
||||
{
|
||||
void *bd = NULL;
|
||||
basic_block dest;
|
||||
basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
|
||||
int sp = 0;
|
||||
int *postorder, postorder_num;
|
||||
|
||||
if (walk_data->dom_direction == CDI_DOMINATORS)
|
||||
if (dom_direction_ == CDI_DOMINATORS)
|
||||
{
|
||||
postorder = XNEWVEC (int, n_basic_blocks);
|
||||
postorder_num = inverted_post_order_compute (postorder);
|
||||
@ -177,37 +171,9 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
|
||||
|| bb == ENTRY_BLOCK_PTR
|
||||
|| bb == EXIT_BLOCK_PTR)
|
||||
{
|
||||
/* Callback to initialize the local data structure. */
|
||||
if (walk_data->initialize_block_local_data)
|
||||
{
|
||||
bool recycled;
|
||||
|
||||
/* First get some local data, reusing any local data
|
||||
pointer we may have saved. */
|
||||
if (walk_data->free_block_data.length () > 0)
|
||||
{
|
||||
bd = walk_data->free_block_data.pop ();
|
||||
recycled = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bd = xcalloc (1, walk_data->block_local_data_size);
|
||||
recycled = 0;
|
||||
}
|
||||
|
||||
/* Push the local data into the local data stack. */
|
||||
walk_data->block_data_stack.safe_push (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. */
|
||||
if (walk_data->before_dom_children)
|
||||
(*walk_data->before_dom_children) (walk_data, bb);
|
||||
/* Callback for subclasses to do custom things before we have walked
|
||||
the dominator children, but before we walk statements. */
|
||||
before_dom_children (bb);
|
||||
|
||||
/* Mark the current BB to be popped out of the recursion stack
|
||||
once children are processed. */
|
||||
@ -215,10 +181,10 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
|
||||
worklist[sp++] = NULL;
|
||||
|
||||
int saved_sp = sp;
|
||||
for (dest = first_dom_son (walk_data->dom_direction, bb);
|
||||
dest; dest = next_dom_son (walk_data->dom_direction, dest))
|
||||
for (dest = first_dom_son (dom_direction_, bb);
|
||||
dest; dest = next_dom_son (dom_direction_, dest))
|
||||
worklist[sp++] = dest;
|
||||
if (walk_data->dom_direction == CDI_DOMINATORS)
|
||||
if (dom_direction_ == CDI_DOMINATORS)
|
||||
switch (sp - saved_sp)
|
||||
{
|
||||
case 0:
|
||||
@ -235,48 +201,19 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
|
||||
--sp;
|
||||
bb = worklist[--sp];
|
||||
|
||||
/* Callback for operations to execute after we have walked the
|
||||
dominator children, but before we walk statements. */
|
||||
if (walk_data->after_dom_children)
|
||||
(*walk_data->after_dom_children) (walk_data, bb);
|
||||
|
||||
if (walk_data->initialize_block_local_data)
|
||||
{
|
||||
/* And finally pop the record off the block local data stack. */
|
||||
bd = walk_data->block_data_stack.pop ();
|
||||
/* And save the block data so that we can re-use it. */
|
||||
walk_data->free_block_data.safe_push (bd);
|
||||
}
|
||||
/* Callback allowing subclasses to do custom things after we have
|
||||
walked dominator children, but before we walk statements. */
|
||||
after_dom_children (bb);
|
||||
}
|
||||
if (sp)
|
||||
bb = worklist[--sp];
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (walk_data->dom_direction == CDI_DOMINATORS)
|
||||
if (dom_direction_ == CDI_DOMINATORS)
|
||||
{
|
||||
free (bb_postorder);
|
||||
bb_postorder = NULL;
|
||||
}
|
||||
free (worklist);
|
||||
}
|
||||
|
||||
void
|
||||
init_walk_dominator_tree (struct dom_walk_data *walk_data)
|
||||
{
|
||||
walk_data->free_block_data.create (0);
|
||||
walk_data->block_data_stack.create (0);
|
||||
}
|
||||
|
||||
void
|
||||
fini_walk_dominator_tree (struct dom_walk_data *walk_data)
|
||||
{
|
||||
if (walk_data->initialize_block_local_data)
|
||||
{
|
||||
while (walk_data->free_block_data.length () > 0)
|
||||
free (walk_data->free_block_data.pop ());
|
||||
}
|
||||
|
||||
walk_data->free_block_data.release ();
|
||||
walk_data->block_data_stack.release ();
|
||||
}
|
||||
|
@ -18,57 +18,35 @@ You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
typedef void *void_p;
|
||||
#ifndef GCC_DOM_WALK_H
|
||||
#define GCC_DOM_WALK_H
|
||||
|
||||
/* This is the main data structure for the dominator walker. It provides
|
||||
the callback hooks as well as a convenient place to hang block local
|
||||
data and pass-global data. */
|
||||
|
||||
struct dom_walk_data
|
||||
/**
|
||||
* This is the main class for the dominator walker. It is expected that
|
||||
* consumers will have a custom class inheriting from it, which will over ride
|
||||
* at least one of before_dom_children and after_dom_children to implement the
|
||||
* custom behavior.
|
||||
*/
|
||||
class dom_walker
|
||||
{
|
||||
public:
|
||||
dom_walker (cdi_direction direction) : dom_direction_ (direction) {}
|
||||
|
||||
/* Walk the dominator tree. */
|
||||
void walk (basic_block);
|
||||
|
||||
/* Function to call before the recursive walk of the dominator children. */
|
||||
virtual void before_dom_children (basic_block) {}
|
||||
|
||||
/* Function to call after the recursive walk of the dominator children. */
|
||||
virtual void after_dom_children (basic_block) {}
|
||||
|
||||
private:
|
||||
/* This is the direction of the dominator tree we want to walk. i.e.,
|
||||
if it is set to CDI_DOMINATORS, then we walk the dominator tree,
|
||||
if it is set to CDI_POST_DOMINATORS, then we walk the post
|
||||
dominator tree. */
|
||||
ENUM_BITFIELD (cdi_direction) dom_direction : 2;
|
||||
|
||||
/* Function to initialize block local data.
|
||||
|
||||
Note that the dominator walker infrastructure may provide a new
|
||||
fresh, and zero'd block local data structure, or it may re-use an
|
||||
existing block local data structure.
|
||||
|
||||
If the block local structure has items such as virtual arrays, then
|
||||
that allows your optimizer to re-use those arrays rather than
|
||||
creating new ones. */
|
||||
void (*initialize_block_local_data) (struct dom_walk_data *,
|
||||
basic_block, bool);
|
||||
|
||||
/* Function to call before the recursive walk of the dominator children. */
|
||||
void (*before_dom_children) (struct dom_walk_data *, basic_block);
|
||||
|
||||
/* Function to call after the recursive walk of the dominator children. */
|
||||
void (*after_dom_children) (struct dom_walk_data *, basic_block);
|
||||
|
||||
/* Global data for a walk through the dominator tree. */
|
||||
void *global_data;
|
||||
|
||||
/* Stack of any data we need to keep on a per-block basis.
|
||||
|
||||
If you have no local data, then BLOCK_DATA_STACK will be NULL. */
|
||||
vec<void_p> block_data_stack;
|
||||
|
||||
/* Size of the block local data. If this is zero, then it is assumed
|
||||
you have no local data and thus no BLOCK_DATA_STACK as well. */
|
||||
size_t block_local_data_size;
|
||||
|
||||
/* From here below are private data. Please do not use this
|
||||
information/data outside domwalk.c. */
|
||||
|
||||
/* Stack of available block local structures. */
|
||||
vec<void_p> free_block_data;
|
||||
const ENUM_BITFIELD (cdi_direction) dom_direction_ : 2;
|
||||
};
|
||||
|
||||
void walk_dominator_tree (struct dom_walk_data *, basic_block);
|
||||
void init_walk_dominator_tree (struct dom_walk_data *);
|
||||
void fini_walk_dominator_tree (struct dom_walk_data *);
|
||||
#endif
|
||||
|
30
gcc/fwprop.c
30
gcc/fwprop.c
@ -205,10 +205,17 @@ process_uses (df_ref *use_rec, int top_flag)
|
||||
}
|
||||
}
|
||||
|
||||
class single_def_use_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
single_def_use_dom_walker (cdi_direction direction)
|
||||
: dom_walker (direction) {}
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
};
|
||||
|
||||
static void
|
||||
single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
single_def_use_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
int bb_index = bb->index;
|
||||
struct df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index);
|
||||
@ -245,9 +252,8 @@ single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
/* Pop the definitions created in this basic block when leaving its
|
||||
dominated parts. */
|
||||
|
||||
static void
|
||||
single_def_use_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED)
|
||||
void
|
||||
single_def_use_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
|
||||
{
|
||||
df_ref saved_def;
|
||||
while ((saved_def = reg_defs_stack.pop ()) != NULL)
|
||||
@ -269,8 +275,6 @@ single_def_use_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
static void
|
||||
build_single_def_use_links (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
|
||||
/* We use the multiple definitions problem to compute our restricted
|
||||
use-def chains. */
|
||||
df_set_flags (DF_EQ_NOTES);
|
||||
@ -291,14 +295,8 @@ build_single_def_use_links (void)
|
||||
|
||||
/* Walk the dominator tree looking for single reaching definitions
|
||||
dominating the uses. This is similar to how SSA form is built. */
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = single_def_use_enter_block;
|
||||
walk_data.after_dom_children = single_def_use_leave_block;
|
||||
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
single_def_use_dom_walker (CDI_DOMINATORS)
|
||||
.walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
BITMAP_FREE (local_lr);
|
||||
BITMAP_FREE (local_md);
|
||||
|
@ -1571,11 +1571,18 @@ slsr_process_copy (gimple gs, tree rhs1, bool speed)
|
||||
add_cand_for_stmt (gs, c);
|
||||
}
|
||||
|
||||
class find_candidates_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
find_candidates_dom_walker (cdi_direction direction)
|
||||
: dom_walker (direction) {}
|
||||
virtual void before_dom_children (basic_block);
|
||||
};
|
||||
|
||||
/* Find strength-reduction candidates in block BB. */
|
||||
|
||||
static void
|
||||
find_candidates_in_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
find_candidates_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
bool speed = optimize_bb_for_speed_p (bb);
|
||||
gimple_stmt_iterator gsi;
|
||||
@ -3488,8 +3495,6 @@ analyze_candidates_and_replace (void)
|
||||
static unsigned
|
||||
execute_strength_reduction (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
|
||||
/* Create the obstack where candidates will reside. */
|
||||
gcc_obstack_init (&cand_obstack);
|
||||
|
||||
@ -3509,18 +3514,10 @@ execute_strength_reduction (void)
|
||||
back edges, and this gives us dominator information as well. */
|
||||
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
|
||||
|
||||
/* Set up callbacks for the generic dominator tree walker. */
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = find_candidates_in_block;
|
||||
walk_data.after_dom_children = NULL;
|
||||
walk_data.global_data = NULL;
|
||||
walk_data.block_local_data_size = 0;
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Walk the CFG in predominator order looking for strength reduction
|
||||
candidates. */
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
find_candidates_dom_walker (CDI_DOMINATORS)
|
||||
.walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
@ -3531,8 +3528,6 @@ execute_strength_reduction (void)
|
||||
/* Analyze costs and make appropriate replacements. */
|
||||
analyze_candidates_and_replace ();
|
||||
|
||||
/* Free resources. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
loop_optimizer_finalize ();
|
||||
base_cand_map.dispose ();
|
||||
obstack_free (&chain_obstack, NULL);
|
||||
|
@ -1191,14 +1191,6 @@ add_conditions_to_constraints (scop_p scop)
|
||||
add_conditions_to_domain (pbb);
|
||||
}
|
||||
|
||||
/* Structure used to pass data to dom_walk. */
|
||||
|
||||
struct bsc
|
||||
{
|
||||
vec<gimple> *conditions, *cases;
|
||||
sese region;
|
||||
};
|
||||
|
||||
/* Returns a COND_EXPR statement when BB has a single predecessor, the
|
||||
edge between BB and its predecessor is not a loop exit edge, and
|
||||
the last statement of the single predecessor is a COND_EXPR. */
|
||||
@ -1224,20 +1216,43 @@ single_pred_cond_non_loop_exit (basic_block bb)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class sese_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
sese_dom_walker (cdi_direction, sese);
|
||||
~sese_dom_walker ();
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
|
||||
private:
|
||||
vec<gimple> conditions_, cases_;
|
||||
sese region_;
|
||||
};
|
||||
|
||||
sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
|
||||
: dom_walker (direction), region_ (region)
|
||||
{
|
||||
conditions_.create (3);
|
||||
cases_.create (3);
|
||||
}
|
||||
|
||||
sese_dom_walker::~sese_dom_walker ()
|
||||
{
|
||||
conditions_.release ();
|
||||
cases_.release ();
|
||||
}
|
||||
|
||||
/* Call-back for dom_walk executed before visiting the dominated
|
||||
blocks. */
|
||||
|
||||
static void
|
||||
build_sese_conditions_before (struct dom_walk_data *dw_data,
|
||||
basic_block bb)
|
||||
void
|
||||
sese_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
struct bsc *data = (struct bsc *) dw_data->global_data;
|
||||
vec<gimple> *conditions = data->conditions;
|
||||
vec<gimple> *cases = data->cases;
|
||||
gimple_bb_p gbb;
|
||||
gimple stmt;
|
||||
|
||||
if (!bb_in_sese_p (bb, data->region))
|
||||
if (!bb_in_sese_p (bb, region_))
|
||||
return;
|
||||
|
||||
stmt = single_pred_cond_non_loop_exit (bb);
|
||||
@ -1246,75 +1261,39 @@ build_sese_conditions_before (struct dom_walk_data *dw_data,
|
||||
{
|
||||
edge e = single_pred_edge (bb);
|
||||
|
||||
conditions->safe_push (stmt);
|
||||
conditions_.safe_push (stmt);
|
||||
|
||||
if (e->flags & EDGE_TRUE_VALUE)
|
||||
cases->safe_push (stmt);
|
||||
cases_.safe_push (stmt);
|
||||
else
|
||||
cases->safe_push (NULL);
|
||||
cases_.safe_push (NULL);
|
||||
}
|
||||
|
||||
gbb = gbb_from_bb (bb);
|
||||
|
||||
if (gbb)
|
||||
{
|
||||
GBB_CONDITIONS (gbb) = conditions->copy ();
|
||||
GBB_CONDITION_CASES (gbb) = cases->copy ();
|
||||
GBB_CONDITIONS (gbb) = conditions_.copy ();
|
||||
GBB_CONDITION_CASES (gbb) = cases_.copy ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Call-back for dom_walk executed after visiting the dominated
|
||||
blocks. */
|
||||
|
||||
static void
|
||||
build_sese_conditions_after (struct dom_walk_data *dw_data,
|
||||
basic_block bb)
|
||||
void
|
||||
sese_dom_walker::after_dom_children (basic_block bb)
|
||||
{
|
||||
struct bsc *data = (struct bsc *) dw_data->global_data;
|
||||
vec<gimple> *conditions = data->conditions;
|
||||
vec<gimple> *cases = data->cases;
|
||||
|
||||
if (!bb_in_sese_p (bb, data->region))
|
||||
if (!bb_in_sese_p (bb, region_))
|
||||
return;
|
||||
|
||||
if (single_pred_cond_non_loop_exit (bb))
|
||||
{
|
||||
conditions->pop ();
|
||||
cases->pop ();
|
||||
conditions_.pop ();
|
||||
cases_.pop ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Record all conditions in REGION. */
|
||||
|
||||
static void
|
||||
build_sese_conditions (sese region)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
vec<gimple> conditions;
|
||||
conditions.create (3);
|
||||
vec<gimple> cases;
|
||||
cases.create (3);
|
||||
struct bsc data;
|
||||
|
||||
data.conditions = &conditions;
|
||||
data.cases = &cases;
|
||||
data.region = region;
|
||||
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = build_sese_conditions_before;
|
||||
walk_data.after_dom_children = build_sese_conditions_after;
|
||||
walk_data.global_data = &data;
|
||||
walk_data.block_local_data_size = 0;
|
||||
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
|
||||
conditions.release ();
|
||||
cases.release ();
|
||||
}
|
||||
|
||||
/* Add constraints on the possible values of parameter P from the type
|
||||
of P. */
|
||||
|
||||
@ -3179,7 +3158,8 @@ build_poly_scop (scop_p scop)
|
||||
rewrite_commutative_reductions_out_of_ssa (scop);
|
||||
|
||||
build_sese_loop_nests (region);
|
||||
build_sese_conditions (region);
|
||||
/* Record all conditions in REGION. */
|
||||
sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
|
||||
find_scop_parameters (scop);
|
||||
|
||||
max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
|
||||
|
@ -1399,14 +1399,22 @@ rewrite_add_phi_arguments (basic_block bb)
|
||||
}
|
||||
}
|
||||
|
||||
class rewrite_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
rewrite_dom_walker (cdi_direction direction) : dom_walker (direction) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
};
|
||||
|
||||
/* 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_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
rewrite_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
|
||||
@ -1444,9 +1452,8 @@ rewrite_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
/* Called after visiting all the statements in basic block BB and all
|
||||
of its dominator children. Restore CURRDEFS to its original value. */
|
||||
|
||||
static void
|
||||
rewrite_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED)
|
||||
void
|
||||
rewrite_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Restore CURRDEFS to its original state. */
|
||||
while (block_defs_stack.length () > 0)
|
||||
@ -2065,15 +2072,22 @@ rewrite_update_phi_arguments (basic_block bb)
|
||||
}
|
||||
}
|
||||
|
||||
class rewrite_update_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
rewrite_update_dom_walker (cdi_direction direction) : dom_walker (direction) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
};
|
||||
|
||||
/* Initialization of block data structures for the incremental SSA
|
||||
update pass. 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_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
rewrite_update_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
bool is_abnormal_phi;
|
||||
gimple_stmt_iterator gsi;
|
||||
@ -2146,9 +2160,8 @@ rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
unwinding must be done in the opposite order to what is done in
|
||||
register_new_update_set. */
|
||||
|
||||
static void
|
||||
rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED)
|
||||
void
|
||||
rewrite_update_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
|
||||
{
|
||||
while (block_defs_stack.length () > 0)
|
||||
{
|
||||
@ -2183,40 +2196,19 @@ rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
static void
|
||||
rewrite_blocks (basic_block entry, enum rewrite_mode what)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
|
||||
/* Rewrite all the basic blocks in the program. */
|
||||
timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
|
||||
|
||||
/* Setup callbacks for the generic dominator tree walker. */
|
||||
memset (&walk_data, 0, sizeof (walk_data));
|
||||
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
|
||||
if (what == REWRITE_ALL)
|
||||
{
|
||||
walk_data.before_dom_children = rewrite_enter_block;
|
||||
walk_data.after_dom_children = rewrite_leave_block;
|
||||
}
|
||||
else if (what == REWRITE_UPDATE)
|
||||
{
|
||||
walk_data.before_dom_children = rewrite_update_enter_block;
|
||||
walk_data.after_dom_children = rewrite_update_leave_block;
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
block_defs_stack.create (10);
|
||||
|
||||
/* Initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Recursively walk the dominator tree rewriting each statement in
|
||||
each basic block. */
|
||||
walk_dominator_tree (&walk_data, entry);
|
||||
|
||||
/* Finalize the dominator walker. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
if (what == REWRITE_ALL)
|
||||
rewrite_dom_walker (CDI_DOMINATORS).walk (entry);
|
||||
else if (what == REWRITE_UPDATE)
|
||||
rewrite_update_dom_walker (CDI_DOMINATORS).walk (entry);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
/* Debugging dumps. */
|
||||
if (dump_file && (dump_flags & TDF_STATS))
|
||||
@ -2231,69 +2223,44 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what)
|
||||
timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
|
||||
}
|
||||
|
||||
class mark_def_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
mark_def_dom_walker (cdi_direction direction);
|
||||
~mark_def_dom_walker ();
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
|
||||
private:
|
||||
/* Notice that this bitmap is indexed using variable UIDs, so it must be
|
||||
large enough to accommodate all the variables referenced in the
|
||||
function, not just the ones we are renaming. */
|
||||
bitmap kills_;
|
||||
};
|
||||
|
||||
mark_def_dom_walker::mark_def_dom_walker (cdi_direction direction)
|
||||
: dom_walker (direction), kills_ (BITMAP_ALLOC (NULL))
|
||||
{
|
||||
}
|
||||
|
||||
mark_def_dom_walker::~mark_def_dom_walker ()
|
||||
{
|
||||
BITMAP_FREE (kills_);
|
||||
}
|
||||
|
||||
/* Block processing routine for mark_def_sites. Clear the KILLS bitmap
|
||||
at the start of each block, and call mark_def_sites for each statement. */
|
||||
|
||||
static void
|
||||
mark_def_sites_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
void
|
||||
mark_def_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
struct mark_def_sites_global_data *gd;
|
||||
bitmap kills;
|
||||
gimple_stmt_iterator gsi;
|
||||
|
||||
gd = (struct mark_def_sites_global_data *) walk_data->global_data;
|
||||
kills = gd->kills;
|
||||
|
||||
bitmap_clear (kills);
|
||||
bitmap_clear (kills_);
|
||||
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||
mark_def_sites (bb, gsi_stmt (gsi), kills);
|
||||
mark_def_sites (bb, gsi_stmt (gsi), kills_);
|
||||
}
|
||||
|
||||
|
||||
/* Mark the definition site blocks for each variable, so that we know
|
||||
where the variable is actually live.
|
||||
|
||||
The INTERESTING_BLOCKS global will be filled in with all the blocks
|
||||
that should be processed by the renamer. It is assumed that the
|
||||
caller has already initialized and zeroed it. */
|
||||
|
||||
static void
|
||||
mark_def_site_blocks (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
struct mark_def_sites_global_data mark_def_sites_global_data;
|
||||
|
||||
/* Setup callbacks for the generic dominator tree walker to find and
|
||||
mark definition sites. */
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = mark_def_sites_block;
|
||||
walk_data.after_dom_children = NULL;
|
||||
|
||||
/* Notice that this bitmap is indexed using variable UIDs, so it must be
|
||||
large enough to accommodate all the variables referenced in the
|
||||
function, not just the ones we are renaming. */
|
||||
mark_def_sites_global_data.kills = BITMAP_ALLOC (NULL);
|
||||
walk_data.global_data = &mark_def_sites_global_data;
|
||||
|
||||
/* We do not have any local data. */
|
||||
walk_data.block_local_data_size = 0;
|
||||
|
||||
/* Initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Recursively walk the dominator tree. */
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
|
||||
/* Finalize the dominator walker. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* We no longer need this bitmap, clear and free it. */
|
||||
BITMAP_FREE (mark_def_sites_global_data.kills);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize internal data needed during renaming. */
|
||||
|
||||
static void
|
||||
@ -2331,8 +2298,7 @@ fini_ssa_renamer (void)
|
||||
insert PHI nodes and rename the function in dominator tree
|
||||
order.
|
||||
|
||||
2- Find and mark all the blocks that define variables
|
||||
(mark_def_site_blocks).
|
||||
2- Find and mark all the blocks that define variables.
|
||||
|
||||
3- Insert PHI nodes at dominance frontiers (insert_phi_nodes).
|
||||
|
||||
@ -2370,7 +2336,7 @@ rewrite_into_ssa (void)
|
||||
compute_dominance_frontiers (dfs);
|
||||
|
||||
/* 2- Find and mark definition sites. */
|
||||
mark_def_site_blocks ();
|
||||
mark_def_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
/* 3- Insert PHI nodes at dominance frontiers of definition blocks. */
|
||||
insert_phi_nodes (dfs);
|
||||
|
@ -244,9 +244,6 @@ static void record_equivalences_from_phis (basic_block);
|
||||
static void record_equivalences_from_incoming_edge (basic_block);
|
||||
static void eliminate_redundant_computations (gimple_stmt_iterator *);
|
||||
static void record_equivalences_from_stmt (gimple, int);
|
||||
static void dom_thread_across_edge (struct dom_walk_data *, edge);
|
||||
static void dom_opt_leave_block (struct dom_walk_data *, basic_block);
|
||||
static void dom_opt_enter_block (struct dom_walk_data *, basic_block);
|
||||
static void remove_local_expressions_from_table (void);
|
||||
static void restore_vars_to_original_value (void);
|
||||
static edge single_incoming_edge_ignoring_loop_edges (basic_block);
|
||||
@ -773,6 +770,21 @@ free_all_edge_infos (void)
|
||||
}
|
||||
}
|
||||
|
||||
class dom_opt_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
dom_opt_dom_walker (cdi_direction direction)
|
||||
: dom_walker (direction), dummy_cond_ (NULL) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
|
||||
private:
|
||||
void thread_across_edge (edge);
|
||||
|
||||
gimple dummy_cond_;
|
||||
};
|
||||
|
||||
/* Jump threading, redundancy elimination and const/copy propagation.
|
||||
|
||||
This pass may expose new symbols that need to be renamed into SSA. For
|
||||
@ -782,8 +794,6 @@ free_all_edge_infos (void)
|
||||
static unsigned int
|
||||
tree_ssa_dominator_optimize (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
|
||||
memset (&opt_stats, 0, sizeof (opt_stats));
|
||||
|
||||
/* Create our hash tables. */
|
||||
@ -792,20 +802,6 @@ tree_ssa_dominator_optimize (void)
|
||||
const_and_copies_stack.create (20);
|
||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||
|
||||
/* Setup callbacks for the generic dominator tree walker. */
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = dom_opt_enter_block;
|
||||
walk_data.after_dom_children = dom_opt_leave_block;
|
||||
/* Right now we only attach a dummy COND_EXPR to the global data pointer.
|
||||
When we attach more stuff we'll need to fill this out with a real
|
||||
structure. */
|
||||
walk_data.global_data = NULL;
|
||||
walk_data.block_local_data_size = 0;
|
||||
|
||||
/* Now initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
cfg_altered = false;
|
||||
|
||||
@ -824,7 +820,7 @@ tree_ssa_dominator_optimize (void)
|
||||
mark_dfs_back_edges ();
|
||||
|
||||
/* Recursively walk the dominator tree optimizing statements. */
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
dom_opt_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
@ -897,9 +893,6 @@ tree_ssa_dominator_optimize (void)
|
||||
/* Delete our main hashtable. */
|
||||
avail_exprs.dispose ();
|
||||
|
||||
/* And finalize the dominator walker. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Free asserted bitmaps and stacks. */
|
||||
BITMAP_FREE (need_eh_cleanup);
|
||||
|
||||
@ -1081,21 +1074,18 @@ simplify_stmt_for_jump_threading (gimple stmt,
|
||||
it handles lazily building the dummy condition and the bookkeeping
|
||||
when jump threading is successful. */
|
||||
|
||||
static void
|
||||
dom_thread_across_edge (struct dom_walk_data *walk_data, edge e)
|
||||
void
|
||||
dom_opt_dom_walker::thread_across_edge (edge e)
|
||||
{
|
||||
if (! walk_data->global_data)
|
||||
{
|
||||
gimple dummy_cond =
|
||||
if (! dummy_cond_)
|
||||
dummy_cond_ =
|
||||
gimple_build_cond (NE_EXPR,
|
||||
integer_zero_node, integer_zero_node,
|
||||
NULL, NULL);
|
||||
walk_data->global_data = dummy_cond;
|
||||
}
|
||||
|
||||
thread_across_edge ((gimple) walk_data->global_data, e, false,
|
||||
&const_and_copies_stack,
|
||||
simplify_stmt_for_jump_threading);
|
||||
::thread_across_edge (dummy_cond_, e, false,
|
||||
&const_and_copies_stack,
|
||||
simplify_stmt_for_jump_threading);
|
||||
}
|
||||
|
||||
/* PHI nodes can create equivalences too.
|
||||
@ -1864,9 +1854,8 @@ record_edge_info (basic_block bb)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
dom_opt_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
|
||||
@ -1903,8 +1892,8 @@ dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
any finalization actions in preparation for leaving this node in
|
||||
the dominator tree. */
|
||||
|
||||
static void
|
||||
dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
void
|
||||
dom_opt_dom_walker::after_dom_children (basic_block bb)
|
||||
{
|
||||
gimple last;
|
||||
|
||||
@ -1919,7 +1908,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
/* Push a marker on the stack, which thread_across_edge expects
|
||||
and will remove. */
|
||||
const_and_copies_stack.safe_push (NULL_TREE);
|
||||
dom_thread_across_edge (walk_data, single_succ_edge (bb));
|
||||
thread_across_edge (single_succ_edge (bb));
|
||||
}
|
||||
else if ((last = last_stmt (bb))
|
||||
&& gimple_code (last) == GIMPLE_COND
|
||||
@ -1964,7 +1953,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
record_cond (eq);
|
||||
}
|
||||
|
||||
dom_thread_across_edge (walk_data, true_edge);
|
||||
thread_across_edge (true_edge);
|
||||
|
||||
/* And restore the various tables to their state before
|
||||
we threaded this edge. */
|
||||
@ -1999,7 +1988,7 @@ dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
}
|
||||
|
||||
/* Now thread the edge. */
|
||||
dom_thread_across_edge (walk_data, false_edge);
|
||||
thread_across_edge (false_edge);
|
||||
|
||||
/* No need to remove local expressions from our tables
|
||||
or restore vars to their original value as that will
|
||||
|
@ -68,7 +68,6 @@ static bitmap need_eh_cleanup;
|
||||
|
||||
static bool gate_dse (void);
|
||||
static unsigned int tree_ssa_dse (void);
|
||||
static void dse_enter_block (struct dom_walk_data *, basic_block);
|
||||
|
||||
|
||||
/* A helper of dse_optimize_stmt.
|
||||
@ -292,9 +291,16 @@ dse_optimize_stmt (gimple_stmt_iterator *gsi)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dse_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
class dse_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
dse_dom_walker (cdi_direction direction) : dom_walker (direction) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
};
|
||||
|
||||
void
|
||||
dse_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
|
||||
@ -313,8 +319,6 @@ dse_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
static unsigned int
|
||||
tree_ssa_dse (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
|
||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||
|
||||
renumber_gimple_stmt_uids ();
|
||||
@ -328,22 +332,7 @@ tree_ssa_dse (void)
|
||||
|
||||
/* Dead store elimination is fundamentally a walk of the post-dominator
|
||||
tree and a backwards walk of statements within each block. */
|
||||
walk_data.dom_direction = CDI_POST_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = dse_enter_block;
|
||||
walk_data.after_dom_children = NULL;
|
||||
|
||||
walk_data.block_local_data_size = 0;
|
||||
walk_data.global_data = NULL;
|
||||
|
||||
/* Initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Recursively walk the dominator tree. */
|
||||
walk_dominator_tree (&walk_data, EXIT_BLOCK_PTR);
|
||||
|
||||
/* Finalize the dominator walker. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
dse_dom_walker (CDI_POST_DOMINATORS).walk (cfun->cfg->x_exit_block_ptr);
|
||||
|
||||
/* Removal of stores may make some EH edges dead. Purge such edges from
|
||||
the CFG as needed. */
|
||||
|
@ -1040,14 +1040,25 @@ rewrite_bittest (gimple_stmt_iterator *bsi)
|
||||
return stmt;
|
||||
}
|
||||
|
||||
/* For each statement determines the outermost loop in that it is invariant,
|
||||
- statements on whose motion it depends and the cost of the computation.
|
||||
- This information is stored to the LIM_DATA structure associated with
|
||||
- each statement. */
|
||||
class invariantness_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
invariantness_dom_walker (cdi_direction direction)
|
||||
: dom_walker (direction) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
};
|
||||
|
||||
/* Determine the outermost loops in that statements in basic block BB are
|
||||
invariant, and record them to the LIM_DATA associated with the statements.
|
||||
Callback for walk_dominator_tree. */
|
||||
Callback for dom_walker. */
|
||||
|
||||
static void
|
||||
determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
invariantness_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
enum move_pos pos;
|
||||
gimple_stmt_iterator bsi;
|
||||
@ -1177,32 +1188,23 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
|
||||
}
|
||||
}
|
||||
|
||||
/* For each statement determines the outermost loop in that it is invariant,
|
||||
statements on whose motion it depends and the cost of the computation.
|
||||
This information is stored to the LIM_DATA structure associated with
|
||||
each statement. */
|
||||
|
||||
static void
|
||||
determine_invariantness (void)
|
||||
class move_computations_dom_walker : public dom_walker
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
public:
|
||||
move_computations_dom_walker (cdi_direction direction)
|
||||
: dom_walker (direction), todo_ (0) {}
|
||||
|
||||
memset (&walk_data, 0, sizeof (struct dom_walk_data));
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.before_dom_children = determine_invariantness_stmt;
|
||||
virtual void before_dom_children (basic_block);
|
||||
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
}
|
||||
unsigned int todo_;
|
||||
};
|
||||
|
||||
/* Hoist the statements in basic block BB out of the loops prescribed by
|
||||
data stored in LIM_DATA structures associated with each statement. Callback
|
||||
for walk_dominator_tree. */
|
||||
|
||||
static void
|
||||
move_computations_stmt (struct dom_walk_data *dw_data,
|
||||
basic_block bb)
|
||||
void
|
||||
move_computations_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
struct loop *level;
|
||||
gimple_stmt_iterator bsi;
|
||||
@ -1266,7 +1268,7 @@ move_computations_stmt (struct dom_walk_data *dw_data,
|
||||
gimple_phi_result (stmt),
|
||||
t, arg0, arg1);
|
||||
SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt;
|
||||
*((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg;
|
||||
todo_ |= TODO_cleanup_cfg;
|
||||
}
|
||||
gsi_insert_on_edge (loop_preheader_edge (level), new_stmt);
|
||||
remove_phi_node (&bsi, false);
|
||||
@ -1337,23 +1339,14 @@ move_computations_stmt (struct dom_walk_data *dw_data,
|
||||
static unsigned int
|
||||
move_computations (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
unsigned int todo = 0;
|
||||
|
||||
memset (&walk_data, 0, sizeof (struct dom_walk_data));
|
||||
walk_data.global_data = &todo;
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.before_dom_children = move_computations_stmt;
|
||||
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
move_computations_dom_walker walker (CDI_DOMINATORS);
|
||||
walker.walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
gsi_commit_edge_inserts ();
|
||||
if (need_ssa_update_p (cfun))
|
||||
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
|
||||
|
||||
return todo;
|
||||
return walker.todo_;
|
||||
}
|
||||
|
||||
/* Checks whether the statement defining variable *INDEX can be hoisted
|
||||
@ -2632,7 +2625,8 @@ tree_ssa_lim (void)
|
||||
|
||||
/* For each statement determine the outermost loop in that it is
|
||||
invariant and cost for computing the invariant. */
|
||||
determine_invariantness ();
|
||||
invariantness_dom_walker (CDI_DOMINATORS)
|
||||
.walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
/* Execute store motion. Force the necessary invariants to be moved
|
||||
out of the loops as well. */
|
||||
|
@ -1264,9 +1264,6 @@ struct ssa_names_hasher : typed_free_remove <name_to_bb>
|
||||
Hash entries with phase < nt_call_phase are invalid. */
|
||||
static unsigned int nt_call_phase;
|
||||
|
||||
/* The set of MEM_REFs which can't trap. */
|
||||
static struct pointer_set_t *nontrap_set;
|
||||
|
||||
/* The hash function. */
|
||||
|
||||
inline hashval_t
|
||||
@ -1378,9 +1375,22 @@ nonfreeing_call_p (gimple call)
|
||||
return false;
|
||||
}
|
||||
|
||||
class nontrapping_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
nontrapping_dom_walker (cdi_direction direction, pointer_set_t *ps)
|
||||
: dom_walker (direction), nontrapping_ (ps) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
|
||||
private:
|
||||
pointer_set_t *nontrapping_;
|
||||
};
|
||||
|
||||
/* Called by walk_dominator_tree, when entering the block BB. */
|
||||
static void
|
||||
nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
|
||||
void
|
||||
nontrapping_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
@ -1406,15 +1416,15 @@ nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
|
||||
nt_call_phase++;
|
||||
else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
|
||||
{
|
||||
add_or_mark_expr (bb, gimple_assign_lhs (stmt), nontrap_set, true);
|
||||
add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), nontrap_set, false);
|
||||
add_or_mark_expr (bb, gimple_assign_lhs (stmt), nontrapping_, true);
|
||||
add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), nontrapping_, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by walk_dominator_tree, when basic block BB is exited. */
|
||||
static void
|
||||
nt_fini_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
|
||||
void
|
||||
nontrapping_dom_walker::after_dom_children (basic_block bb)
|
||||
{
|
||||
/* This BB isn't on the path to dominator root anymore. */
|
||||
bb->aux = (void*)2;
|
||||
@ -1427,28 +1437,16 @@ nt_fini_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
|
||||
static struct pointer_set_t *
|
||||
get_non_trapping (void)
|
||||
{
|
||||
struct pointer_set_t *nontrap;
|
||||
struct dom_walk_data walk_data;
|
||||
|
||||
nt_call_phase = 0;
|
||||
nontrap = pointer_set_create ();
|
||||
pointer_set_t *nontrap = pointer_set_create ();
|
||||
seen_ssa_names.create (128);
|
||||
/* We're going to do a dominator walk, so ensure that we have
|
||||
dominance information. */
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
/* Setup callbacks for the generic dominator tree walker. */
|
||||
nontrap_set = nontrap;
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = nt_init_block;
|
||||
walk_data.after_dom_children = nt_fini_block;
|
||||
walk_data.global_data = NULL;
|
||||
walk_data.block_local_data_size = 0;
|
||||
nontrapping_dom_walker (CDI_DOMINATORS, nontrap)
|
||||
.walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
seen_ssa_names.dispose ();
|
||||
|
||||
clear_aux_for_blocks ();
|
||||
|
@ -4051,10 +4051,19 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val)
|
||||
return res;
|
||||
}
|
||||
|
||||
class eliminate_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
eliminate_dom_walker (cdi_direction direction) : dom_walker (direction) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
};
|
||||
|
||||
/* Perform elimination for the basic-block B during the domwalk. */
|
||||
|
||||
static void
|
||||
eliminate_bb (dom_walk_data *, basic_block b)
|
||||
void
|
||||
eliminate_dom_walker::before_dom_children (basic_block b)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
gimple stmt;
|
||||
@ -4403,8 +4412,8 @@ eliminate_bb (dom_walk_data *, basic_block b)
|
||||
|
||||
/* Make no longer available leaders no longer available. */
|
||||
|
||||
static void
|
||||
eliminate_leave_block (dom_walk_data *, basic_block)
|
||||
void
|
||||
eliminate_dom_walker::after_dom_children (basic_block)
|
||||
{
|
||||
tree entry;
|
||||
while ((entry = el_avail_stack.pop ()) != NULL_TREE)
|
||||
@ -4416,7 +4425,6 @@ eliminate_leave_block (dom_walk_data *, basic_block)
|
||||
static unsigned int
|
||||
eliminate (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
gimple_stmt_iterator gsi;
|
||||
gimple stmt;
|
||||
unsigned i;
|
||||
@ -4430,15 +4438,7 @@ eliminate (void)
|
||||
el_avail.create (0);
|
||||
el_avail_stack.create (0);
|
||||
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = eliminate_bb;
|
||||
walk_data.after_dom_children = eliminate_leave_block;
|
||||
walk_data.global_data = NULL;
|
||||
walk_data.block_local_data_size = 0;
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
eliminate_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
el_avail.release ();
|
||||
el_avail_stack.release ();
|
||||
|
@ -1926,12 +1926,20 @@ do_invalidate (basic_block dombb, gimple phi, bitmap visited, int *count)
|
||||
}
|
||||
}
|
||||
|
||||
class strlen_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
strlen_dom_walker (cdi_direction direction) : dom_walker (direction) {}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
};
|
||||
|
||||
/* Callback for walk_dominator_tree. Attempt to optimize various
|
||||
string ops by remembering string lenths pointed by pointer SSA_NAMEs. */
|
||||
|
||||
static void
|
||||
strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
strlen_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
|
||||
@ -2014,9 +2022,8 @@ strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
/* Callback for walk_dominator_tree. Free strinfo vector if it is
|
||||
owned by the current bb, clear bb->aux. */
|
||||
|
||||
static void
|
||||
strlen_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
strlen_dom_walker::after_dom_children (basic_block bb)
|
||||
{
|
||||
if (bb->aux)
|
||||
{
|
||||
@ -2040,8 +2047,6 @@ strlen_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
static unsigned int
|
||||
tree_ssa_strlen (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
|
||||
ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
|
||||
max_stridx = 1;
|
||||
strinfo_pool = create_alloc_pool ("strinfo_struct pool",
|
||||
@ -2051,21 +2056,7 @@ tree_ssa_strlen (void)
|
||||
|
||||
/* String length optimization is implemented as a walk of the dominator
|
||||
tree and a forward walk of statements within each block. */
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = strlen_enter_block;
|
||||
walk_data.after_dom_children = strlen_leave_block;
|
||||
walk_data.block_local_data_size = 0;
|
||||
walk_data.global_data = NULL;
|
||||
|
||||
/* Initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Recursively walk the dominator tree. */
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
|
||||
/* Finalize the dominator walker. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
strlen_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
ssa_ver_to_stridx.release ();
|
||||
free_alloc_pool (strinfo_pool);
|
||||
|
@ -259,11 +259,6 @@ associate_equivalences_with_edges (void)
|
||||
so with each value we have a list of SSA_NAMEs that have the
|
||||
same value. */
|
||||
|
||||
/* As we enter each block we record the value for any edge equivalency
|
||||
leading to this block. If no such edge equivalency exists, then we
|
||||
record NULL. These equivalences are live until we leave the dominator
|
||||
subtree rooted at the block where we record the equivalency. */
|
||||
static vec<tree> equiv_stack;
|
||||
|
||||
/* Main structure for recording equivalences into our hash table. */
|
||||
struct equiv_hash_elt
|
||||
@ -316,8 +311,6 @@ val_ssa_equiv_hasher::remove (value_type *elt)
|
||||
able to reuse tree-vn for this code. */
|
||||
static hash_table <val_ssa_equiv_hasher> val_ssa_equiv;
|
||||
|
||||
static void uncprop_enter_block (struct dom_walk_data *, basic_block);
|
||||
static void uncprop_leave_block (struct dom_walk_data *, basic_block);
|
||||
static void uncprop_into_successor_phis (basic_block);
|
||||
|
||||
/* Remove the most recently recorded equivalency for VALUE. */
|
||||
@ -361,47 +354,54 @@ record_equiv (tree value, tree equivalence)
|
||||
an_equiv_elt_p->equivalences.safe_push (equivalence);
|
||||
}
|
||||
|
||||
class uncprop_dom_walker : public dom_walker
|
||||
{
|
||||
public:
|
||||
uncprop_dom_walker (cdi_direction direction)
|
||||
: dom_walker (direction)
|
||||
{
|
||||
equiv_stack_.create (2);
|
||||
}
|
||||
~uncprop_dom_walker ()
|
||||
{
|
||||
equiv_stack_.release ();
|
||||
}
|
||||
|
||||
virtual void before_dom_children (basic_block);
|
||||
virtual void after_dom_children (basic_block);
|
||||
|
||||
private:
|
||||
|
||||
/* As we enter each block we record the value for any edge equivalency
|
||||
leading to this block. If no such edge equivalency exists, then we
|
||||
record NULL. These equivalences are live until we leave the dominator
|
||||
subtree rooted at the block where we record the equivalency. */
|
||||
vec<tree> equiv_stack_;
|
||||
};
|
||||
|
||||
/* Main driver for un-cprop. */
|
||||
|
||||
static unsigned int
|
||||
tree_ssa_uncprop (void)
|
||||
{
|
||||
struct dom_walk_data walk_data;
|
||||
basic_block bb;
|
||||
|
||||
associate_equivalences_with_edges ();
|
||||
|
||||
/* Create our global data structures. */
|
||||
val_ssa_equiv.create (1024);
|
||||
equiv_stack.create (2);
|
||||
|
||||
/* We're going to do a dominator walk, so ensure that we have
|
||||
dominance information. */
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
/* Setup callbacks for the generic dominator tree walker. */
|
||||
walk_data.dom_direction = CDI_DOMINATORS;
|
||||
walk_data.initialize_block_local_data = NULL;
|
||||
walk_data.before_dom_children = uncprop_enter_block;
|
||||
walk_data.after_dom_children = uncprop_leave_block;
|
||||
walk_data.global_data = NULL;
|
||||
walk_data.block_local_data_size = 0;
|
||||
|
||||
/* Now initialize the dominator walker. */
|
||||
init_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Recursively walk the dominator tree undoing unprofitable
|
||||
constant/copy propagations. */
|
||||
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
|
||||
uncprop_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
|
||||
|
||||
/* Finalize and clean up. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* EQUIV_STACK should already be empty at this point, so we just
|
||||
need to empty elements out of the hash table, free EQUIV_STACK,
|
||||
and cleanup the AUX field on the edges. */
|
||||
/* we just need to empty elements out of the hash table, and cleanup the
|
||||
AUX field on the edges. */
|
||||
val_ssa_equiv.dispose ();
|
||||
equiv_stack.release ();
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
edge e;
|
||||
@ -424,12 +424,11 @@ tree_ssa_uncprop (void)
|
||||
any finalization actions in preparation for leaving this node in
|
||||
the dominator tree. */
|
||||
|
||||
static void
|
||||
uncprop_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb ATTRIBUTE_UNUSED)
|
||||
void
|
||||
uncprop_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* Pop the topmost value off the equiv stack. */
|
||||
tree value = equiv_stack.pop ();
|
||||
tree value = equiv_stack_.pop ();
|
||||
|
||||
/* If that value was non-null, then pop the topmost equivalency off
|
||||
its equivalency stack. */
|
||||
@ -547,9 +546,8 @@ single_incoming_edge_ignoring_loop_edges (basic_block bb)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
uncprop_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
void
|
||||
uncprop_dom_walker::before_dom_children (basic_block bb)
|
||||
{
|
||||
basic_block parent;
|
||||
edge e;
|
||||
@ -568,13 +566,13 @@ uncprop_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
|
||||
|
||||
record_equiv (equiv->rhs, equiv->lhs);
|
||||
equiv_stack.safe_push (equiv->rhs);
|
||||
equiv_stack_.safe_push (equiv->rhs);
|
||||
recorded = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!recorded)
|
||||
equiv_stack.safe_push (NULL_TREE);
|
||||
equiv_stack_.safe_push (NULL_TREE);
|
||||
|
||||
uncprop_into_successor_phis (bb);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user