Commit 8702a557 by Jeff Law Committed by Jeff Law

tree-ssa-threadupdate.c (threaded_edges): New VEC to hold edge pairs.


	* tree-ssa-threadupdate.c (threaded_edges): New VEC to
	hold edge pairs.
	(mark_threaded_blocks, register_jump_thread): New functions.
	(thread_through_all_blocks): Remove unwanted argument.  No
	longer rely on e->aux to communicate thread target info.
	Call mark_threaded_blocks.  Release the threaded_blocks
	bitmap and threaded_edges vector when complete.
	* tree-ssa-dom.c (struct edge_info): Remove redirection_target field.
	(threaded_blocks): Remove.
	(tree_ssa_dominator_optimize): Remove initialization and
	finalization of threaded_blocks.  Simplify call to
	thread_through_all_blocks.
	(thread_across_edge): Call register_jump_thread rather than
	storing thread information into e->aux.
	(free_all_edge_infos): Simplify now that e->aux is no longer
	used to communicate with thread_through_all_blocks.
	* tree-flow.h (thread_through_all_blocks): Update prototype.
	(register_jump_thread): Prototype.

From-SVN: r109602
parent 9be0cc75
2006-01-11 Jeff Law <law@redhat.com>
* tree-ssa-threadupdate.c (threaded_edges): New VEC to
hold edge pairs.
(mark_threaded_blocks, register_jump_thread): New functions.
(thread_through_all_blocks): Remove unwanted argument. No
longer rely on e->aux to communicate thread target info.
Call mark_threaded_blocks. Release the threaded_blocks
bitmap and threaded_edges vector when complete.
* tree-ssa-dom.c (struct edge_info): Remove redirection_target field.
(threaded_blocks): Remove.
(tree_ssa_dominator_optimize): Remove initialization and
finalization of threaded_blocks. Simplify call to
thread_through_all_blocks.
(thread_across_edge): Call register_jump_thread rather than
storing thread information into e->aux.
(free_all_edge_infos): Simplify now that e->aux is no longer
used to communicate with thread_through_all_blocks.
* tree-flow.h (thread_through_all_blocks): Update prototype.
(register_jump_thread): Prototype.
2006-01-11 Kazu Hirata <kazu@codesourcery.com> 2006-01-11 Kazu Hirata <kazu@codesourcery.com>
* df-core.c (df_compact_blocks, df_bb_replace): Use * df-core.c (df_compact_blocks, df_bb_replace): Use
......
...@@ -807,7 +807,8 @@ bool multiplier_allowed_in_address_p (HOST_WIDE_INT); ...@@ -807,7 +807,8 @@ bool multiplier_allowed_in_address_p (HOST_WIDE_INT);
unsigned multiply_by_cost (HOST_WIDE_INT, enum machine_mode); unsigned multiply_by_cost (HOST_WIDE_INT, enum machine_mode);
/* In tree-ssa-threadupdate.c. */ /* In tree-ssa-threadupdate.c. */
extern bool thread_through_all_blocks (bitmap); extern bool thread_through_all_blocks (void);
extern void register_jump_thread (edge, edge);
/* In gimplify.c */ /* In gimplify.c */
tree force_gimple_operand (tree, tree *, bool, tree); tree force_gimple_operand (tree, tree *, bool, tree);
......
...@@ -74,9 +74,6 @@ struct edge_info ...@@ -74,9 +74,6 @@ struct edge_info
and its maximum index rather than use a varray. */ and its maximum index rather than use a varray. */
tree *cond_equivalences; tree *cond_equivalences;
unsigned int max_cond_equivalences; unsigned int max_cond_equivalences;
/* If we can thread this edge this field records the new target. */
edge redirection_target;
}; };
...@@ -141,10 +138,6 @@ static VEC(tree,heap) *const_and_copies_stack; ...@@ -141,10 +138,6 @@ static VEC(tree,heap) *const_and_copies_stack;
know their exact value. */ know their exact value. */
static bitmap nonzero_vars; static bitmap nonzero_vars;
/* Bitmap of blocks that are scheduled to be threaded through. This
is used to communicate with thread_through_blocks. */
static bitmap threaded_blocks;
/* Stack of SSA_NAMEs which need their NONZERO_VARS property cleared /* Stack of SSA_NAMEs which need their NONZERO_VARS property cleared
when the current block is finalized. when the current block is finalized.
...@@ -326,10 +319,10 @@ free_all_edge_infos (void) ...@@ -326,10 +319,10 @@ free_all_edge_infos (void)
if (edge_info) if (edge_info)
{ {
e->aux = edge_info->redirection_target;
if (edge_info->cond_equivalences) if (edge_info->cond_equivalences)
free (edge_info->cond_equivalences); free (edge_info->cond_equivalences);
free (edge_info); free (edge_info);
e->aux = NULL;
} }
} }
} }
...@@ -372,7 +365,6 @@ tree_ssa_dominator_optimize (void) ...@@ -372,7 +365,6 @@ tree_ssa_dominator_optimize (void)
vrp_variables_stack = VEC_alloc (tree, heap, 20); vrp_variables_stack = VEC_alloc (tree, heap, 20);
stmts_to_rescan = VEC_alloc (tree, heap, 20); stmts_to_rescan = VEC_alloc (tree, heap, 20);
nonzero_vars = BITMAP_ALLOC (NULL); nonzero_vars = BITMAP_ALLOC (NULL);
threaded_blocks = BITMAP_ALLOC (NULL);
need_eh_cleanup = BITMAP_ALLOC (NULL); need_eh_cleanup = BITMAP_ALLOC (NULL);
/* Setup callbacks for the generic dominator tree walker. */ /* Setup callbacks for the generic dominator tree walker. */
...@@ -448,7 +440,7 @@ tree_ssa_dominator_optimize (void) ...@@ -448,7 +440,7 @@ tree_ssa_dominator_optimize (void)
free_all_edge_infos (); free_all_edge_infos ();
/* Thread jumps, creating duplicate blocks as needed. */ /* Thread jumps, creating duplicate blocks as needed. */
cfg_altered |= thread_through_all_blocks (threaded_blocks); cfg_altered |= thread_through_all_blocks ();
/* Removal of statements may make some EH edges dead. Purge /* Removal of statements may make some EH edges dead. Purge
such edges from the CFG as needed. */ such edges from the CFG as needed. */
...@@ -487,7 +479,6 @@ tree_ssa_dominator_optimize (void) ...@@ -487,7 +479,6 @@ tree_ssa_dominator_optimize (void)
/* Reinitialize the various tables. */ /* Reinitialize the various tables. */
bitmap_clear (nonzero_vars); bitmap_clear (nonzero_vars);
bitmap_clear (threaded_blocks);
htab_empty (avail_exprs); htab_empty (avail_exprs);
htab_empty (vrp_data); htab_empty (vrp_data);
...@@ -533,7 +524,6 @@ tree_ssa_dominator_optimize (void) ...@@ -533,7 +524,6 @@ tree_ssa_dominator_optimize (void)
/* Free nonzero_vars. */ /* Free nonzero_vars. */
BITMAP_FREE (nonzero_vars); BITMAP_FREE (nonzero_vars);
BITMAP_FREE (threaded_blocks);
BITMAP_FREE (need_eh_cleanup); BITMAP_FREE (need_eh_cleanup);
VEC_free (tree, heap, avail_exprs_stack); VEC_free (tree, heap, avail_exprs_stack);
...@@ -924,8 +914,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -924,8 +914,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
edge_info = (struct edge_info *) e->aux; edge_info = (struct edge_info *) e->aux;
else else
edge_info = allocate_edge_info (e); edge_info = allocate_edge_info (e);
edge_info->redirection_target = taken_edge; register_jump_thread (e, taken_edge);
bitmap_set_bit (threaded_blocks, e->dest->index);
} }
} }
} }
......
...@@ -147,6 +147,14 @@ struct local_info ...@@ -147,6 +147,14 @@ struct local_info
bool jumps_threaded; bool jumps_threaded;
}; };
/* Passes which use the jump threading code register jump threading
opportunities as they are discovered. We keep the registered
jump threading opportunities in this vector as edge pairs
(original_edge, target_edge). */
DEF_VEC_ALLOC_P(edge,heap);
static VEC(edge,heap) *threaded_edges;
/* Jump threading statistics. */ /* Jump threading statistics. */
struct thread_stats_d struct thread_stats_d
...@@ -802,18 +810,37 @@ thread_block (basic_block bb) ...@@ -802,18 +810,37 @@ thread_block (basic_block bb)
return local_info.jumps_threaded; return local_info.jumps_threaded;
} }
/* Walk through all blocks and thread incoming edges to the block's /* Walk through the registered jump threads and convert them into a
destinations as requested. This is the only entry point into this form convienent for this pass.
file.
Any block which has incoming edges threaded to outgoing edges
will have its entry in THREADED_BLOCK set.
Blocks which have one or more incoming edges have INCOMING_EDGE_THREADED Any threaded edge will have its new outgoing edge stored in the
set in the block's annotation. original edge's AUX field.
Each edge that should be threaded has the new destination edge stored in This form avoids the need to walk all the edges in the CFG to
the original edge's AUX field. discover blocks which need processing and avoids unnecessary
hash table lookups to map from threaded edge to new target. */
This routine (or one of its callees) will clear INCOMING_EDGE_THREADED static void
in the block annotations and the AUX field in the edges. mark_threaded_blocks (bitmap threaded_blocks)
{
unsigned int i;
for (i = 0; i < VEC_length (edge, threaded_edges); i += 2)
{
edge e = VEC_index (edge, threaded_edges, i);
edge e2 = VEC_index (edge, threaded_edges, i + 1);
e->aux = e2;
bitmap_set_bit (threaded_blocks, e->dest->index);
}
}
/* Walk through all blocks and thread incoming edges to the appropriate
outgoing edge for each edge pair recorded in THREADED_EDGES.
It is the caller's responsibility to fix the dominance information It is the caller's responsibility to fix the dominance information
and rewrite duplicated SSA_NAMEs back into SSA form. and rewrite duplicated SSA_NAMEs back into SSA form.
...@@ -821,15 +848,22 @@ thread_block (basic_block bb) ...@@ -821,15 +848,22 @@ thread_block (basic_block bb)
Returns true if one or more edges were threaded, false otherwise. */ Returns true if one or more edges were threaded, false otherwise. */
bool bool
thread_through_all_blocks (bitmap threaded_blocks) thread_through_all_blocks (void)
{ {
bool retval = false; bool retval = false;
unsigned int i; unsigned int i;
bitmap_iterator bi; bitmap_iterator bi;
bitmap threaded_blocks;
if (threaded_edges == NULL)
return false;
threaded_blocks = BITMAP_ALLOC (NULL);
rediscover_loops_after_threading = false; rediscover_loops_after_threading = false;
memset (&thread_stats, 0, sizeof (thread_stats)); memset (&thread_stats, 0, sizeof (thread_stats));
mark_threaded_blocks (threaded_blocks);
EXECUTE_IF_SET_IN_BITMAP (threaded_blocks, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (threaded_blocks, 0, i, bi)
{ {
basic_block bb = BASIC_BLOCK (i); basic_block bb = BASIC_BLOCK (i);
...@@ -842,5 +876,27 @@ thread_through_all_blocks (bitmap threaded_blocks) ...@@ -842,5 +876,27 @@ thread_through_all_blocks (bitmap threaded_blocks)
fprintf (dump_file, "\nJumps threaded: %lu\n", fprintf (dump_file, "\nJumps threaded: %lu\n",
thread_stats.num_threaded_edges); thread_stats.num_threaded_edges);
BITMAP_FREE (threaded_blocks);
threaded_blocks = NULL;
VEC_free (edge, heap, threaded_edges);
threaded_edges = NULL;
return retval; return retval;
} }
/* Register a jump threading opportunity. We queue up all the jump
threading opportunities discovered by a pass and update the CFG
and SSA form all at once.
E is the edge we can thread, E2 is the new target edge. ie, we
are effectively recording that E->dest can be changed to E2->dest
after fixing the SSA graph. */
void
register_jump_thread (edge e, edge e2)
{
if (threaded_edges == NULL)
threaded_edges = VEC_alloc (edge, heap, 10);
VEC_safe_push (edge, heap, threaded_edges, e);
VEC_safe_push (edge, heap, threaded_edges, e2);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment