Commit 42759f1e by Zdenek Dvorak Committed by Zdenek Dvorak

Makefile.in (tree-cfg.o): Add CFGLAYOUT_H dependency.

	* Makefile.in (tree-cfg.o): Add CFGLAYOUT_H dependency.
	* basic-block.h (get_dominated_by_region): Declare.
	* dominance.c (get_dominated_by_region): New function.
	* tree-cfg.c: Include cfglayout.h.
	(tree_duplicate_bb): Duplicate also phi nodes.
	(struct ssa_name_map_entry): New type.
	(add_phi_args_after_copy_bb, add_phi_args_after_copy,
	ssa_name_map_entry_hash, ssa_name_map_entry_eq,
	allocate_ssa_names, rewrite_to_new_ssa_names_def,
	rewrite_to_new_ssa_names_use, rewrite_to_new_ssa_names_bb,
	rewrite_to_new_ssa_names, tree_duplicate_sese_region): New functions.
	* tree-flow.h (tree_duplicate_sese_region, add_phi_args_after_copy_bb,
	add_phi_args_after_copy, rewrite_to_new_ssa_names_bb,
	rewrite_to_new_ssa_names, allocate_ssa_names,
	rewrite_into_loop_closed_ssa, verify_loop_closed_ssa): Declare.
	* tree-ssa-loop-ch.c (duplicate_blocks): Removed.
	(copy_loop_headers): Use tree_duplicate_sese_region.

	* gcc.dg/tree-ssa/copy-headers.c: Update outcome.

From-SVN: r87614
parent 2731cf24
2004-09-16 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* Makefile.in (tree-cfg.o): Add CFGLAYOUT_H dependency.
* basic-block.h (get_dominated_by_region): Declare.
* dominance.c (get_dominated_by_region): New function.
* tree-cfg.c: Include cfglayout.h.
(tree_duplicate_bb): Duplicate also phi nodes.
(struct ssa_name_map_entry): New type.
(add_phi_args_after_copy_bb, add_phi_args_after_copy,
ssa_name_map_entry_hash, ssa_name_map_entry_eq,
allocate_ssa_names, rewrite_to_new_ssa_names_def,
rewrite_to_new_ssa_names_use, rewrite_to_new_ssa_names_bb,
rewrite_to_new_ssa_names, tree_duplicate_sese_region): New functions.
* tree-flow.h (tree_duplicate_sese_region, add_phi_args_after_copy_bb,
add_phi_args_after_copy, rewrite_to_new_ssa_names_bb,
rewrite_to_new_ssa_names, allocate_ssa_names,
rewrite_into_loop_closed_ssa, verify_loop_closed_ssa): Declare.
* tree-ssa-loop-ch.c (duplicate_blocks): Removed.
(copy_loop_headers): Use tree_duplicate_sese_region.
2004-09-16 Frank Ch. Eigler <fche@redhat.com>
* profile.c (branch_prob): Restore support for USE_MAPPED_LOCATION.
......
......@@ -1667,7 +1667,8 @@ tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
diagnostic.h errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) gt-tree-cfg.h tree-pass.h
$(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) gt-tree-cfg.h tree-pass.h \
$(CFGLAYOUT_H)
tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) function.h $(TM_H) coretypes.h \
$(TREE_DUMP_H) diagnostic.h except.h tree-pass.h $(FLAGS_H) langhooks.h
......
......@@ -732,6 +732,8 @@ extern void set_immediate_dominator (enum cdi_direction, basic_block,
extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
extern bool dominated_by_p (enum cdi_direction, basic_block, basic_block);
extern int get_dominated_by (enum cdi_direction, basic_block, basic_block **);
extern unsigned get_dominated_by_region (enum cdi_direction, basic_block *,
unsigned, basic_block *);
extern void add_to_dominance_info (enum cdi_direction, basic_block);
extern void delete_from_dominance_info (enum cdi_direction, basic_block);
basic_block recount_dominator (enum cdi_direction, basic_block);
......
......@@ -738,6 +738,32 @@ get_dominated_by (enum cdi_direction dir, basic_block bb, basic_block **bbs)
return n;
}
/* Find all basic blocks that are immediately dominated (in direction DIR)
by some block between N_REGION ones stored in REGION, except for blocks
in the REGION itself. The found blocks are stored to DOMS and their number
is returned. */
unsigned
get_dominated_by_region (enum cdi_direction dir, basic_block *region,
unsigned n_region, basic_block *doms)
{
unsigned n_doms = 0, i;
basic_block dom;
for (i = 0; i < n_region; i++)
region[i]->rbi->duplicated = 1;
for (i = 0; i < n_region; i++)
for (dom = first_dom_son (dir, region[i]);
dom;
dom = next_dom_son (dir, dom))
if (!dom->rbi->duplicated)
doms[n_doms++] = dom;
for (i = 0; i < n_region; i++)
region[i]->rbi->duplicated = 0;
return n_doms;
}
/* Redirect all edges pointing to BB to TO. */
void
redirect_immediate_dominators (enum cdi_direction dir, basic_block bb,
......
2004-09-16 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* gcc.dg/tree-ssa/copy-headers.c: Update outcome.
2004-09-16 Frank Ch. Eigler <fche@redhat.com>
* gcc.misc-tests/bprob.exp, g++.dg/bprob/bprob.exp: Iterate tests
......
......@@ -11,5 +11,5 @@ void bla (void)
foo (i);
}
/* There should be a header scheduled for duplication. */
/* { dg-final { scan-tree-dump-times "Scheduled" 1 "ch"} } */
/* There should be a header duplicated. */
/* { dg-final { scan-tree-dump-times "Duplicating header" 1 "ch"} } */
......@@ -495,6 +495,13 @@ extern void clear_special_calls (void);
extern void verify_stmts (void);
extern tree tree_block_label (basic_block bb);
extern void extract_true_false_edges_from_block (basic_block, edge *, edge *);
extern bool tree_duplicate_sese_region (edge, edge, basic_block *, unsigned,
basic_block *);
extern void add_phi_args_after_copy_bb (basic_block);
extern void add_phi_args_after_copy (basic_block *, unsigned);
extern void rewrite_to_new_ssa_names_bb (basic_block, struct htab *);
extern void rewrite_to_new_ssa_names (basic_block *, unsigned, htab_t);
extern void allocate_ssa_names (bitmap, struct htab **);
extern bool tree_purge_dead_eh_edges (basic_block);
extern bool tree_purge_all_dead_eh_edges (bitmap);
extern tree gimplify_val (block_stmt_iterator *, tree, tree);
......
......@@ -98,59 +98,6 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop,
return true;
}
/* Duplicates destinations of edges in BBS_TO_DUPLICATE. */
static void
duplicate_blocks (varray_type bbs_to_duplicate)
{
unsigned i;
edge preheader_edge, e, e1;
basic_block header, new_header;
tree phi, new_phi, var;
/* TODO: It should be quite easy to keep the dominance information
up-to-date. */
free_dominance_info (CDI_DOMINATORS);
for (i = 0; i < VARRAY_ACTIVE_SIZE (bbs_to_duplicate); i++)
{
preheader_edge = VARRAY_GENERIC_PTR_NOGC (bbs_to_duplicate, i);
header = preheader_edge->dest;
gcc_assert (header->aux);
header->aux = NULL;
new_header = duplicate_block (header, preheader_edge);
/* Create the phi nodes on on entry to new_header. */
for (phi = phi_nodes (header), var = PENDING_STMT (preheader_edge);
phi;
phi = TREE_CHAIN (phi), var = TREE_CHAIN (var))
{
new_phi = create_phi_node (PHI_RESULT (phi), new_header);
add_phi_arg (&new_phi, TREE_VALUE (var), preheader_edge);
}
PENDING_STMT (preheader_edge) = NULL;
/* Add the phi arguments to the outgoing edges. */
for (e = header->succ; e; e = e->succ_next)
{
for (e1 = new_header->succ; e1->dest != e->dest; e1 = e1->succ_next)
continue;
for (phi = phi_nodes (e->dest); phi; phi = TREE_CHAIN (phi))
{
tree def = PHI_ARG_DEF_FROM_EDGE (phi, e);
add_phi_arg (&phi, def, e1);
}
}
}
calculate_dominance_info (CDI_DOMINATORS);
rewrite_ssa_into_ssa ();
}
/* Checks whether LOOP is a do-while style loop. */
static bool
......@@ -183,12 +130,14 @@ copy_loop_headers (void)
unsigned i;
struct loop *loop;
basic_block header;
edge preheader_edge;
varray_type bbs_to_duplicate = NULL;
edge exit;
basic_block *bbs;
unsigned n_bbs;
loops = loop_optimizer_init (dump_file);
if (!loops)
return;
rewrite_into_loop_closed_ssa ();
/* We do not try to keep the information about irreducible regions
up-to-date. */
......@@ -198,14 +147,15 @@ copy_loop_headers (void)
verify_loop_structure (loops);
#endif
bbs = xmalloc (sizeof (basic_block) * n_basic_blocks);
for (i = 1; i < loops->num; i++)
{
/* Copy at most 20 insns. */
int limit = 20;
loop = loops->parray[i];
preheader_edge = loop_preheader_edge (loop);
header = preheader_edge->dest;
header = loop->header;
/* If the loop is already a do-while style one (either because it was
written as such, or because jump threading transformed it into one),
......@@ -218,44 +168,56 @@ copy_loop_headers (void)
like while (a && b) {...}, where we want to have both of the conditions
copied. TODO -- handle while (a || b) - like cases, by not requiring
the header to have just a single successor and copying up to
postdominator.
We do not really copy the blocks immediately, so that we do not have
to worry about updating loop structures, and also so that we do not
have to rewrite variables out of and into ssa form for each block.
Instead we just record the block into worklist and duplicate all of
them at once. */
postdominator. */
exit = NULL;
n_bbs = 0;
while (should_duplicate_loop_header_p (header, loop, &limit))
{
if (!bbs_to_duplicate)
VARRAY_GENERIC_PTR_NOGC_INIT (bbs_to_duplicate, 10,
"bbs_to_duplicate");
VARRAY_PUSH_GENERIC_PTR_NOGC (bbs_to_duplicate, preheader_edge);
header->aux = &header->aux;
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
"Scheduled basic block %d for duplication.\n",
header->index);
/* Find a successor of header that is inside a loop; i.e. the new
header after the condition is copied. */
if (flow_bb_inside_loop_p (loop, header->succ->dest))
preheader_edge = header->succ;
exit = header->succ;
else
preheader_edge = header->succ->succ_next;
header = preheader_edge->dest;
exit = header->succ->succ_next;
bbs[n_bbs++] = header;
header = exit->dest;
}
}
loop_optimizer_finalize (loops, NULL);
if (!exit)
continue;
if (bbs_to_duplicate)
{
duplicate_blocks (bbs_to_duplicate);
VARRAY_FREE (bbs_to_duplicate);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
"Duplicating header of the loop %d up to edge %d->%d.\n",
loop->num, exit->src->index, exit->dest->index);
/* Ensure that the header will have just the latch as a predecessor
inside the loop. */
if (exit->dest->pred->pred_next)
exit = loop_split_edge_with (exit, NULL)->succ;
if (!tree_duplicate_sese_region (loop_preheader_edge (loop), exit,
bbs, n_bbs, NULL))
{
fprintf (dump_file, "Duplication failed.\n");
continue;
}
/* Ensure that the latch and the preheader is simple (we know that they
are not now, since there was the loop exit condition. */
loop_split_edge_with (loop_preheader_edge (loop), NULL);
loop_split_edge_with (loop_latch_edge (loop), NULL);
}
free (bbs);
#ifdef ENABLE_CHECKING
verify_loop_closed_ssa ();
#endif
loop_optimizer_finalize (loops, NULL);
/* Run cleanup_tree_cfg here regardless of whether we have done anything, so
that we cleanup the blocks created in order to get the loops into a
canonical shape. */
......@@ -277,7 +239,7 @@ struct tree_opt_pass pass_ch =
NULL, /* next */
0, /* static_pass_number */
TV_TREE_CH, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */
PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
......
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