Commit 66f97d31 by Zdenek Dvorak Committed by Zdenek Dvorak

cfgloopmanip.c (remove_path, [...]): Change dom_bbs to vector.

	* cfgloopmanip.c (remove_path, loopify, duplicate_loop_to_header_edge):
	Change dom_bbs to vector.  Add argument to iterate_fix_dominators call.
	* loop-unroll.c (unroll_loop_runtime_iterations): Ditto.
	* tree-cfg.c (tree_duplicate_sese_region): Change doms to vector.
	Add argument to iterate_fix_dominators call.
	(remove_edge_and_dominated_blocks): Pass vector to bbs_to_fix_dom.
	* gcse.c (hoist_code): Change domby to vector.
	* cfghooks.c (make_forwarder_block): Change doms_to_fix to vector.
	Add argument to iterate_fix_dominators call.
	* loop-doloop.c (doloop_modify): Changed recount_dominator to
	recompute_dominator.
	* lambda-code.c (perfect_nestify): Ditto.
	* cfgloopanal.c: Include graphds.h.
	(struct edge, struct vertex, struct graph, dump_graph, new_graph,
	add_edge, dfs, for_each_edge, free_graph): Moved to graphds.c.
	(mark_irreducible_loops): Use graphds_scc.  Remove argument from
	add_edge call.
	* graphds.c: New file.
	* graphds.h: New file.
	* dominance.c: Include vecprim.h, pointer-set.h and graphds.h.
	(get_dominated_by, get_dominated_by_region): Change return type to
	vector.
	(verify_dominators): Recompute all dominators and compare the results.
	(recount_dominator): Renamed to ...
	(recompute_dominator): ... this.  Do not check that the block is
	dominated by entry.
	(iterate_fix_dominators): Reimplemented.
	(prune_bbs_to_update_dominators, root_of_dom_tree,
	determine_dominators_for_sons): New functions.
	* et-forest.c (et_root): New function.
	* et-forest.h (et_root): Declare.
	* Makefile.in (graphds.o): Add.
	(cfgloopanal.o): Add graphds.h dependency.
	(dominance.o): Add graphds.h, vecprim.h and pointer-set.h dependency.
	* basic-block.h (get_dominated_by, get_dominated_by_region,
	iterate_fix_dominators): Declaration changed.
	(recount_dominator): Renamed to ...
	(recompute_dominator): ... this.
	* tree-ssa-threadupdate.c (thread_block): Free dominance info.
	(thread_through_all_blocks): Do not free dominance info.

From-SVN: r125297
parent b6a9c30c
2007-06-03 Zdenek Dvorak <dvorakz@suse.cz>
* cfgloopmanip.c (remove_path, loopify, duplicate_loop_to_header_edge):
Change dom_bbs to vector. Add argument to iterate_fix_dominators call.
* loop-unroll.c (unroll_loop_runtime_iterations): Ditto.
* tree-cfg.c (tree_duplicate_sese_region): Change doms to vector.
Add argument to iterate_fix_dominators call.
(remove_edge_and_dominated_blocks): Pass vector to bbs_to_fix_dom.
* gcse.c (hoist_code): Change domby to vector.
* cfghooks.c (make_forwarder_block): Change doms_to_fix to vector.
Add argument to iterate_fix_dominators call.
* loop-doloop.c (doloop_modify): Changed recount_dominator to
recompute_dominator.
* lambda-code.c (perfect_nestify): Ditto.
* cfgloopanal.c: Include graphds.h.
(struct edge, struct vertex, struct graph, dump_graph, new_graph,
add_edge, dfs, for_each_edge, free_graph): Moved to graphds.c.
(mark_irreducible_loops): Use graphds_scc. Remove argument from
add_edge call.
* graphds.c: New file.
* graphds.h: New file.
* dominance.c: Include vecprim.h, pointer-set.h and graphds.h.
(get_dominated_by, get_dominated_by_region): Change return type to
vector.
(verify_dominators): Recompute all dominators and compare the results.
(recount_dominator): Renamed to ...
(recompute_dominator): ... this. Do not check that the block is
dominated by entry.
(iterate_fix_dominators): Reimplemented.
(prune_bbs_to_update_dominators, root_of_dom_tree,
determine_dominators_for_sons): New functions.
* et-forest.c (et_root): New function.
* et-forest.h (et_root): Declare.
* Makefile.in (graphds.o): Add.
(cfgloopanal.o): Add graphds.h dependency.
(dominance.o): Add graphds.h, vecprim.h and pointer-set.h dependency.
* basic-block.h (get_dominated_by, get_dominated_by_region,
iterate_fix_dominators): Declaration changed.
(recount_dominator): Renamed to ...
(recompute_dominator): ... this.
* tree-ssa-threadupdate.c (thread_block): Free dominance info.
(thread_through_all_blocks): Do not free dominance info.
2007-06-03 Andreas Schwab <schwab@suse.de> 2007-06-03 Andreas Schwab <schwab@suse.de>
* config/m68k/m68k.c (override_options): Don't override * config/m68k/m68k.c (override_options): Don't override
......
...@@ -1009,6 +1009,7 @@ OBJS-common = \ ...@@ -1009,6 +1009,7 @@ OBJS-common = \
gimplify.o \ gimplify.o \
global.o \ global.o \
graph.o \ graph.o \
graphds.o \
gtype-desc.o \ gtype-desc.o \
haifa-sched.o \ haifa-sched.o \
hooks.o \ hooks.o \
...@@ -2556,7 +2557,9 @@ cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \ ...@@ -2556,7 +2557,9 @@ cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \
$(GGC_H) $(GGC_H)
cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(EXPR_H) coretypes.h $(TM_H) \
$(OBSTACK_H) output.h $(OBSTACK_H) output.h graphds.h
graphds.o : graphds.c graphds.h $(CONFIG_H) $(SYSTEM_H) bitmap.h $(OBSTACK_H) \
coretypes.h vec.h vecprim.h
struct-equiv.o : struct-equiv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ struct-equiv.o : struct-equiv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \ $(RTL_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \
insn-config.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \ insn-config.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \
...@@ -2582,7 +2585,8 @@ loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \ ...@@ -2582,7 +2585,8 @@ loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \ output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) \
$(OBSTACK_H) $(OBSTACK_H)
dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) toplev.h $(TIMEVAR_H) hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) toplev.h \
$(TIMEVAR_H) graphds.h vecprim.h pointer-set.h
et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
et-forest.h alloc-pool.h $(BASIC_BLOCK_H) et-forest.h alloc-pool.h $(BASIC_BLOCK_H)
combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
......
...@@ -959,15 +959,17 @@ extern void set_immediate_dominator (enum cdi_direction, basic_block, ...@@ -959,15 +959,17 @@ extern void set_immediate_dominator (enum cdi_direction, basic_block,
basic_block); basic_block);
extern basic_block get_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 bool dominated_by_p (enum cdi_direction, basic_block, basic_block);
extern int get_dominated_by (enum cdi_direction, basic_block, basic_block **); extern VEC (basic_block, heap) *get_dominated_by (enum cdi_direction, basic_block);
extern unsigned get_dominated_by_region (enum cdi_direction, basic_block *, extern VEC (basic_block, heap) *get_dominated_by_region (enum cdi_direction,
unsigned, basic_block *); basic_block *,
unsigned);
extern void add_to_dominance_info (enum cdi_direction, basic_block); extern void add_to_dominance_info (enum cdi_direction, basic_block);
extern void delete_from_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); basic_block recompute_dominator (enum cdi_direction, basic_block);
extern void redirect_immediate_dominators (enum cdi_direction, basic_block, extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
basic_block); basic_block);
extern void iterate_fix_dominators (enum cdi_direction, basic_block *, int); extern void iterate_fix_dominators (enum cdi_direction,
VEC (basic_block, heap) *, bool);
extern void verify_dominators (enum cdi_direction); extern void verify_dominators (enum cdi_direction);
extern basic_block first_dom_son (enum cdi_direction, basic_block); extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block); extern basic_block next_dom_son (enum cdi_direction, basic_block);
......
...@@ -735,11 +735,11 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), ...@@ -735,11 +735,11 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge),
if (dom_info_available_p (CDI_DOMINATORS)) if (dom_info_available_p (CDI_DOMINATORS))
{ {
basic_block doms_to_fix[2]; VEC (basic_block, heap) *doms_to_fix = VEC_alloc (basic_block, heap, 2);
VEC_quick_push (basic_block, doms_to_fix, dummy);
doms_to_fix[0] = dummy; VEC_quick_push (basic_block, doms_to_fix, bb);
doms_to_fix[1] = bb; iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, false);
iterate_fix_dominators (CDI_DOMINATORS, doms_to_fix, 2); VEC_free (basic_block, heap, doms_to_fix);
} }
if (current_loops != NULL) if (current_loops != NULL)
......
...@@ -29,6 +29,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ...@@ -29,6 +29,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "cfgloop.h" #include "cfgloop.h"
#include "expr.h" #include "expr.h"
#include "output.h" #include "output.h"
#include "graphds.h"
/* Checks whether BB is executed exactly once in each LOOP iteration. */ /* Checks whether BB is executed exactly once in each LOOP iteration. */
...@@ -50,157 +51,6 @@ just_once_each_iteration_p (const struct loop *loop, basic_block bb) ...@@ -50,157 +51,6 @@ just_once_each_iteration_p (const struct loop *loop, basic_block bb)
return true; return true;
} }
/* Structure representing edge of a graph. */
struct edge
{
int src, dest; /* Source and destination. */
struct edge *pred_next, *succ_next;
/* Next edge in predecessor and successor lists. */
void *data; /* Data attached to the edge. */
};
/* Structure representing vertex of a graph. */
struct vertex
{
struct edge *pred, *succ;
/* Lists of predecessors and successors. */
int component; /* Number of dfs restarts before reaching the
vertex. */
int post; /* Postorder number. */
};
/* Structure representing a graph. */
struct graph
{
int n_vertices; /* Number of vertices. */
struct vertex *vertices;
/* The vertices. */
};
/* Dumps graph G into F. */
extern void dump_graph (FILE *, struct graph *);
void
dump_graph (FILE *f, struct graph *g)
{
int i;
struct edge *e;
for (i = 0; i < g->n_vertices; i++)
{
if (!g->vertices[i].pred
&& !g->vertices[i].succ)
continue;
fprintf (f, "%d (%d)\t<-", i, g->vertices[i].component);
for (e = g->vertices[i].pred; e; e = e->pred_next)
fprintf (f, " %d", e->src);
fprintf (f, "\n");
fprintf (f, "\t->");
for (e = g->vertices[i].succ; e; e = e->succ_next)
fprintf (f, " %d", e->dest);
fprintf (f, "\n");
}
}
/* Creates a new graph with N_VERTICES vertices. */
static struct graph *
new_graph (int n_vertices)
{
struct graph *g = XNEW (struct graph);
g->n_vertices = n_vertices;
g->vertices = XCNEWVEC (struct vertex, n_vertices);
return g;
}
/* Adds an edge from F to T to graph G, with DATA attached. */
static void
add_edge (struct graph *g, int f, int t, void *data)
{
struct edge *e = xmalloc (sizeof (struct edge));
e->src = f;
e->dest = t;
e->data = data;
e->pred_next = g->vertices[t].pred;
g->vertices[t].pred = e;
e->succ_next = g->vertices[f].succ;
g->vertices[f].succ = e;
}
/* Runs dfs search over vertices of G, from NQ vertices in queue QS.
The vertices in postorder are stored into QT. If FORWARD is false,
backward dfs is run. */
static void
dfs (struct graph *g, int *qs, int nq, int *qt, bool forward)
{
int i, tick = 0, v, comp = 0, top;
struct edge *e;
struct edge **stack = xmalloc (sizeof (struct edge *) * g->n_vertices);
for (i = 0; i < g->n_vertices; i++)
{
g->vertices[i].component = -1;
g->vertices[i].post = -1;
}
#define FST_EDGE(V) (forward ? g->vertices[(V)].succ : g->vertices[(V)].pred)
#define NEXT_EDGE(E) (forward ? (E)->succ_next : (E)->pred_next)
#define EDGE_SRC(E) (forward ? (E)->src : (E)->dest)
#define EDGE_DEST(E) (forward ? (E)->dest : (E)->src)
for (i = 0; i < nq; i++)
{
v = qs[i];
if (g->vertices[v].post != -1)
continue;
g->vertices[v].component = comp++;
e = FST_EDGE (v);
top = 0;
while (1)
{
while (e && g->vertices[EDGE_DEST (e)].component != -1)
e = NEXT_EDGE (e);
if (!e)
{
if (qt)
qt[tick] = v;
g->vertices[v].post = tick++;
if (!top)
break;
e = stack[--top];
v = EDGE_SRC (e);
e = NEXT_EDGE (e);
continue;
}
stack[top++] = e;
v = EDGE_DEST (e);
e = FST_EDGE (v);
g->vertices[v].component = comp - 1;
}
}
free (stack);
}
/* Marks the edge E in graph G irreducible if it connects two vertices in the /* Marks the edge E in graph G irreducible if it connects two vertices in the
same scc. */ same scc. */
...@@ -221,38 +71,6 @@ check_irred (struct graph *g, struct edge *e) ...@@ -221,38 +71,6 @@ check_irred (struct graph *g, struct edge *e)
real->src->flags |= BB_IRREDUCIBLE_LOOP; real->src->flags |= BB_IRREDUCIBLE_LOOP;
} }
/* Runs CALLBACK for all edges in G. */
static void
for_each_edge (struct graph *g,
void (callback) (struct graph *, struct edge *))
{
struct edge *e;
int i;
for (i = 0; i < g->n_vertices; i++)
for (e = g->vertices[i].succ; e; e = e->succ_next)
callback (g, e);
}
/* Releases the memory occupied by G. */
static void
free_graph (struct graph *g)
{
struct edge *e, *n;
int i;
for (i = 0; i < g->n_vertices; i++)
for (e = g->vertices[i].succ; e; e = n)
{
n = e->succ_next;
free (e);
}
free (g->vertices);
free (g);
}
/* Marks blocks and edges that are part of non-recognized loops; i.e. we /* Marks blocks and edges that are part of non-recognized loops; i.e. we
throw away all latch edges and mark blocks inside any remaining cycle. throw away all latch edges and mark blocks inside any remaining cycle.
Everything is a bit complicated due to fact we do not want to do this Everything is a bit complicated due to fact we do not want to do this
...@@ -271,15 +89,11 @@ mark_irreducible_loops (void) ...@@ -271,15 +89,11 @@ mark_irreducible_loops (void)
basic_block act; basic_block act;
edge e; edge e;
edge_iterator ei; edge_iterator ei;
int i, src, dest; int src, dest;
unsigned depth;
struct graph *g; struct graph *g;
int num = number_of_loops (); int num = number_of_loops ();
int *queue1 = XNEWVEC (int, last_basic_block + num); struct loop *cloop;
int *queue2 = XNEWVEC (int, last_basic_block + num);
int nq;
unsigned depth;
struct loop *cloop, *loop;
loop_iterator li;
gcc_assert (current_loops != NULL); gcc_assert (current_loops != NULL);
...@@ -332,34 +146,16 @@ mark_irreducible_loops (void) ...@@ -332,34 +146,16 @@ mark_irreducible_loops (void)
src = LOOP_REPR (cloop); src = LOOP_REPR (cloop);
} }
add_edge (g, src, dest, e); add_edge (g, src, dest)->data = e;
}
/* Find the strongly connected components. Use the algorithm of Tarjan --
first determine the postorder dfs numbering in reversed graph, then
run the dfs on the original graph in the order given by decreasing
numbers assigned by the previous pass. */
nq = 0;
FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
{
queue1[nq++] = BB_REPR (act);
} }
FOR_EACH_LOOP (li, loop, 0) /* Find the strongly connected components. */
{ graphds_scc (g, NULL);
queue1[nq++] = LOOP_REPR (loop);
}
dfs (g, queue1, nq, queue2, false);
for (i = 0; i < nq; i++)
queue1[i] = queue2[nq - i - 1];
dfs (g, queue1, nq, NULL, true);
/* Mark the irreducible loops. */ /* Mark the irreducible loops. */
for_each_edge (g, check_irred); for_each_edge (g, check_irred);
free_graph (g); free_graph (g);
free (queue1);
free (queue2);
current_loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS; current_loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
} }
......
...@@ -276,8 +276,9 @@ bool ...@@ -276,8 +276,9 @@ bool
remove_path (edge e) remove_path (edge e)
{ {
edge ae; edge ae;
basic_block *rem_bbs, *bord_bbs, *dom_bbs, from, bb; basic_block *rem_bbs, *bord_bbs, from, bb;
int i, nrem, n_bord_bbs, n_dom_bbs, nreml; VEC (basic_block, heap) *dom_bbs;
int i, nrem, n_bord_bbs, nreml;
sbitmap seen; sbitmap seen;
bool irred_invalidated = false; bool irred_invalidated = false;
struct loop **deleted_loop; struct loop **deleted_loop;
...@@ -338,7 +339,7 @@ remove_path (edge e) ...@@ -338,7 +339,7 @@ remove_path (edge e)
/* Remove the path. */ /* Remove the path. */
from = e->src; from = e->src;
remove_branch (e); remove_branch (e);
dom_bbs = XCNEWVEC (basic_block, n_basic_blocks); dom_bbs = NULL;
/* Cancel loops contained in the path. */ /* Cancel loops contained in the path. */
deleted_loop = XNEWVEC (struct loop *, nrem); deleted_loop = XNEWVEC (struct loop *, nrem);
...@@ -355,7 +356,6 @@ remove_path (edge e) ...@@ -355,7 +356,6 @@ remove_path (edge e)
free (deleted_loop); free (deleted_loop);
/* Find blocks whose dominators may be affected. */ /* Find blocks whose dominators may be affected. */
n_dom_bbs = 0;
sbitmap_zero (seen); sbitmap_zero (seen);
for (i = 0; i < n_bord_bbs; i++) for (i = 0; i < n_bord_bbs; i++)
{ {
...@@ -370,14 +370,14 @@ remove_path (edge e) ...@@ -370,14 +370,14 @@ remove_path (edge e)
ldom; ldom;
ldom = next_dom_son (CDI_DOMINATORS, ldom)) ldom = next_dom_son (CDI_DOMINATORS, ldom))
if (!dominated_by_p (CDI_DOMINATORS, from, ldom)) if (!dominated_by_p (CDI_DOMINATORS, from, ldom))
dom_bbs[n_dom_bbs++] = ldom; VEC_safe_push (basic_block, heap, dom_bbs, ldom);
} }
free (seen); free (seen);
/* Recount dominators. */ /* Recount dominators. */
iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs); iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, true);
free (dom_bbs); VEC_free (basic_block, heap, dom_bbs);
free (bord_bbs); free (bord_bbs);
/* Fix placements of basic blocks inside loops and the placement of /* Fix placements of basic blocks inside loops and the placement of
...@@ -472,8 +472,9 @@ loopify (edge latch_edge, edge header_edge, ...@@ -472,8 +472,9 @@ loopify (edge latch_edge, edge header_edge,
{ {
basic_block succ_bb = latch_edge->dest; basic_block succ_bb = latch_edge->dest;
basic_block pred_bb = header_edge->src; basic_block pred_bb = header_edge->src;
basic_block *dom_bbs, *body; basic_block *body;
unsigned n_dom_bbs, i; VEC (basic_block, heap) *dom_bbs;
unsigned i;
sbitmap seen; sbitmap seen;
struct loop *loop = alloc_loop (); struct loop *loop = alloc_loop ();
struct loop *outer = loop_outer (succ_bb->loop_father); struct loop *outer = loop_outer (succ_bb->loop_father);
...@@ -528,8 +529,7 @@ loopify (edge latch_edge, edge header_edge, ...@@ -528,8 +529,7 @@ loopify (edge latch_edge, edge header_edge,
scale_loop_frequencies (succ_bb->loop_father, true_scale, REG_BR_PROB_BASE); scale_loop_frequencies (succ_bb->loop_father, true_scale, REG_BR_PROB_BASE);
/* Update dominators of blocks outside of LOOP. */ /* Update dominators of blocks outside of LOOP. */
dom_bbs = XCNEWVEC (basic_block, n_basic_blocks); dom_bbs = NULL;
n_dom_bbs = 0;
seen = sbitmap_alloc (last_basic_block); seen = sbitmap_alloc (last_basic_block);
sbitmap_zero (seen); sbitmap_zero (seen);
body = get_loop_body (loop); body = get_loop_body (loop);
...@@ -547,15 +547,15 @@ loopify (edge latch_edge, edge header_edge, ...@@ -547,15 +547,15 @@ loopify (edge latch_edge, edge header_edge,
if (!TEST_BIT (seen, ldom->index)) if (!TEST_BIT (seen, ldom->index))
{ {
SET_BIT (seen, ldom->index); SET_BIT (seen, ldom->index);
dom_bbs[n_dom_bbs++] = ldom; VEC_safe_push (basic_block, heap, dom_bbs, ldom);
} }
} }
iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs); iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, false);
free (body); free (body);
free (seen); free (seen);
free (dom_bbs); VEC_free (basic_block, heap, dom_bbs);
return loop; return loop;
} }
...@@ -1054,23 +1054,23 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, ...@@ -1054,23 +1054,23 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
/* Update dominators of outer blocks if affected. */ /* Update dominators of outer blocks if affected. */
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
basic_block dominated, dom_bb, *dom_bbs; basic_block dominated, dom_bb;
int n_dom_bbs,j; VEC (basic_block, heap) *dom_bbs;
unsigned j;
bb = bbs[i]; bb = bbs[i];
bb->aux = 0; bb->aux = 0;
n_dom_bbs = get_dominated_by (CDI_DOMINATORS, bb, &dom_bbs); dom_bbs = get_dominated_by (CDI_DOMINATORS, bb);
for (j = 0; j < n_dom_bbs; j++) for (j = 0; VEC_iterate (basic_block, dom_bbs, j, dominated); j++)
{ {
dominated = dom_bbs[j];
if (flow_bb_inside_loop_p (loop, dominated)) if (flow_bb_inside_loop_p (loop, dominated))
continue; continue;
dom_bb = nearest_common_dominator ( dom_bb = nearest_common_dominator (
CDI_DOMINATORS, first_active[i], first_active_latch); CDI_DOMINATORS, first_active[i], first_active_latch);
set_immediate_dominator (CDI_DOMINATORS, dominated, dom_bb); set_immediate_dominator (CDI_DOMINATORS, dominated, dom_bb);
} }
free (dom_bbs); VEC_free (basic_block, heap, dom_bbs);
} }
free (first_active); free (first_active);
......
...@@ -747,3 +747,20 @@ et_below (struct et_node *down, struct et_node *up) ...@@ -747,3 +747,20 @@ et_below (struct et_node *down, struct et_node *up)
return !d->next || d->next->min + d->depth >= 0; return !d->next || d->next->min + d->depth >= 0;
} }
/* Returns the root of the tree that contains NODE. */
struct et_node *
et_root (struct et_node *node)
{
struct et_occ *occ = node->rightmost_occ, *r;
/* The root of the tree corresponds to the rightmost occurence in the
represented path. */
et_splay (occ);
for (r = occ; r->next; r = r->next)
continue;
et_splay (r);
return r->of;
}
...@@ -79,6 +79,7 @@ void et_set_father (struct et_node *, struct et_node *); ...@@ -79,6 +79,7 @@ void et_set_father (struct et_node *, struct et_node *);
void et_split (struct et_node *); void et_split (struct et_node *);
struct et_node *et_nca (struct et_node *, struct et_node *); struct et_node *et_nca (struct et_node *, struct et_node *);
bool et_below (struct et_node *, struct et_node *); bool et_below (struct et_node *, struct et_node *);
struct et_node *et_root (struct et_node *);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -4829,8 +4829,7 @@ static void ...@@ -4829,8 +4829,7 @@ static void
hoist_code (void) hoist_code (void)
{ {
basic_block bb, dominated; basic_block bb, dominated;
basic_block *domby; VEC (basic_block, heap) *domby;
unsigned int domby_len;
unsigned int i,j; unsigned int i,j;
struct expr **index_map; struct expr **index_map;
struct expr *expr; struct expr *expr;
...@@ -4852,7 +4851,7 @@ hoist_code (void) ...@@ -4852,7 +4851,7 @@ hoist_code (void)
int found = 0; int found = 0;
int insn_inserted_p; int insn_inserted_p;
domby_len = get_dominated_by (CDI_DOMINATORS, bb, &domby); domby = get_dominated_by (CDI_DOMINATORS, bb);
/* Examine each expression that is very busy at the exit of this /* Examine each expression that is very busy at the exit of this
block. These are the potentially hoistable expressions. */ block. These are the potentially hoistable expressions. */
for (i = 0; i < hoist_vbeout[bb->index]->n_bits; i++) for (i = 0; i < hoist_vbeout[bb->index]->n_bits; i++)
...@@ -4865,9 +4864,8 @@ hoist_code (void) ...@@ -4865,9 +4864,8 @@ hoist_code (void)
/* We've found a potentially hoistable expression, now /* We've found a potentially hoistable expression, now
we look at every block BB dominates to see if it we look at every block BB dominates to see if it
computes the expression. */ computes the expression. */
for (j = 0; j < domby_len; j++) for (j = 0; VEC_iterate (basic_block, domby, j, dominated); j++)
{ {
dominated = domby[j];
/* Ignore self dominance. */ /* Ignore self dominance. */
if (bb == dominated) if (bb == dominated)
continue; continue;
...@@ -4906,7 +4904,7 @@ hoist_code (void) ...@@ -4906,7 +4904,7 @@ hoist_code (void)
/* If we found nothing to hoist, then quit now. */ /* If we found nothing to hoist, then quit now. */
if (! found) if (! found)
{ {
free (domby); VEC_free (basic_block, heap, domby);
continue; continue;
} }
...@@ -4923,9 +4921,8 @@ hoist_code (void) ...@@ -4923,9 +4921,8 @@ hoist_code (void)
/* We've found a potentially hoistable expression, now /* We've found a potentially hoistable expression, now
we look at every block BB dominates to see if it we look at every block BB dominates to see if it
computes the expression. */ computes the expression. */
for (j = 0; j < domby_len; j++) for (j = 0; VEC_iterate (basic_block, domby, j, dominated); j++)
{ {
dominated = domby[j];
/* Ignore self dominance. */ /* Ignore self dominance. */
if (bb == dominated) if (bb == dominated)
continue; continue;
...@@ -4976,7 +4973,7 @@ hoist_code (void) ...@@ -4976,7 +4973,7 @@ hoist_code (void)
} }
} }
} }
free (domby); VEC_free (basic_block, heap, domby);
} }
free (index_map); free (index_map);
......
This diff is collapsed. Click to expand it.
/* Graph representation.
Copyright (C) 2007
Free Software Foundation, Inc.
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 the Free
Software Foundation; either version 2, or (at your option) 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
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */
/* Structure representing edge of a graph. */
struct edge
{
int src, dest; /* Source and destination. */
struct edge *pred_next, *succ_next;
/* Next edge in predecessor and successor lists. */
void *data; /* Data attached to the edge. */
};
/* Structure representing vertex of a graph. */
struct vertex
{
struct edge *pred, *succ;
/* Lists of predecessors and successors. */
int component; /* Number of dfs restarts before reaching the
vertex. */
int post; /* Postorder number. */
void *data; /* Data attached to the vertex. */
};
/* Structure representing a graph. */
struct graph
{
int n_vertices; /* Number of vertices. */
struct vertex *vertices;
/* The vertices. */
};
struct graph *new_graph (int);
void dump_graph (FILE *, struct graph *);
struct edge *add_edge (struct graph *, int, int);
void identify_vertices (struct graph *, int, int);
int graphds_dfs (struct graph *, int *, int,
VEC (int, heap) **, bool, bitmap);
int graphds_scc (struct graph *, bitmap);
void graphds_domtree (struct graph *, int, int *, int *, int *);
typedef void (*graphds_edge_callback) (struct graph *, struct edge *);
void for_each_edge (struct graph *, graphds_edge_callback);
void free_graph (struct graph *g);
...@@ -2521,7 +2521,7 @@ perfect_nestify (struct loop *loop, ...@@ -2521,7 +2521,7 @@ perfect_nestify (struct loop *loop,
single_exit (loop)->src); single_exit (loop)->src);
set_immediate_dominator (CDI_DOMINATORS, latchbb, bodybb); set_immediate_dominator (CDI_DOMINATORS, latchbb, bodybb);
set_immediate_dominator (CDI_DOMINATORS, olddest, set_immediate_dominator (CDI_DOMINATORS, olddest,
recount_dominator (CDI_DOMINATORS, olddest)); recompute_dominator (CDI_DOMINATORS, olddest));
/* Create the new iv. */ /* Create the new iv. */
oldivvar = VEC_index (tree, loopivs, 0); oldivvar = VEC_index (tree, loopivs, 0);
ivvar = create_tmp_var (TREE_TYPE (oldivvar), "perfectiv"); ivvar = create_tmp_var (TREE_TYPE (oldivvar), "perfectiv");
......
...@@ -422,12 +422,12 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, ...@@ -422,12 +422,12 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
emit_insn_after (sequence, BB_END (set_zero)); emit_insn_after (sequence, BB_END (set_zero));
set_immediate_dominator (CDI_DOMINATORS, set_zero, set_immediate_dominator (CDI_DOMINATORS, set_zero,
recount_dominator (CDI_DOMINATORS, recompute_dominator (CDI_DOMINATORS,
set_zero)); set_zero));
} }
set_immediate_dominator (CDI_DOMINATORS, new_preheader, set_immediate_dominator (CDI_DOMINATORS, new_preheader,
recount_dominator (CDI_DOMINATORS, recompute_dominator (CDI_DOMINATORS,
new_preheader)); new_preheader));
} }
......
...@@ -953,8 +953,8 @@ unroll_loop_runtime_iterations (struct loop *loop) ...@@ -953,8 +953,8 @@ unroll_loop_runtime_iterations (struct loop *loop)
{ {
rtx old_niter, niter, init_code, branch_code, tmp; rtx old_niter, niter, init_code, branch_code, tmp;
unsigned i, j, p; unsigned i, j, p;
basic_block preheader, *body, *dom_bbs, swtch, ezc_swtch; basic_block preheader, *body, swtch, ezc_swtch;
unsigned n_dom_bbs; VEC (basic_block, heap) *dom_bbs;
sbitmap wont_exit; sbitmap wont_exit;
int may_exit_copy; int may_exit_copy;
unsigned n_peel; unsigned n_peel;
...@@ -972,21 +972,20 @@ unroll_loop_runtime_iterations (struct loop *loop) ...@@ -972,21 +972,20 @@ unroll_loop_runtime_iterations (struct loop *loop)
opt_info = analyze_insns_in_loop (loop); opt_info = analyze_insns_in_loop (loop);
/* Remember blocks whose dominators will have to be updated. */ /* Remember blocks whose dominators will have to be updated. */
dom_bbs = XCNEWVEC (basic_block, n_basic_blocks); dom_bbs = NULL;
n_dom_bbs = 0;
body = get_loop_body (loop); body = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++) for (i = 0; i < loop->num_nodes; i++)
{ {
unsigned nldom; VEC (basic_block, heap) *ldom;
basic_block *ldom; basic_block bb;
nldom = get_dominated_by (CDI_DOMINATORS, body[i], &ldom); ldom = get_dominated_by (CDI_DOMINATORS, body[i]);
for (j = 0; j < nldom; j++) for (j = 0; VEC_iterate (basic_block, ldom, j, bb); j++)
if (!flow_bb_inside_loop_p (loop, ldom[j])) if (!flow_bb_inside_loop_p (loop, bb))
dom_bbs[n_dom_bbs++] = ldom[j]; VEC_safe_push (basic_block, heap, dom_bbs, bb);
free (ldom); VEC_free (basic_block, heap, ldom);
} }
free (body); free (body);
...@@ -1105,7 +1104,7 @@ unroll_loop_runtime_iterations (struct loop *loop) ...@@ -1105,7 +1104,7 @@ unroll_loop_runtime_iterations (struct loop *loop)
} }
/* Recount dominators for outer blocks. */ /* Recount dominators for outer blocks. */
iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs); iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, false);
/* And unroll loop. */ /* And unroll loop. */
...@@ -1177,8 +1176,7 @@ unroll_loop_runtime_iterations (struct loop *loop) ...@@ -1177,8 +1176,7 @@ unroll_loop_runtime_iterations (struct loop *loop)
"in runtime, %i insns\n", "in runtime, %i insns\n",
max_unroll, num_loop_insns (loop)); max_unroll, num_loop_insns (loop));
if (dom_bbs) VEC_free (basic_block, heap, dom_bbs);
free (dom_bbs);
} }
/* Decide whether to simply peel LOOP and how much. */ /* Decide whether to simply peel LOOP and how much. */
......
...@@ -4336,11 +4336,11 @@ tree_duplicate_sese_region (edge entry, edge exit, ...@@ -4336,11 +4336,11 @@ tree_duplicate_sese_region (edge entry, edge exit,
basic_block *region, unsigned n_region, basic_block *region, unsigned n_region,
basic_block *region_copy) basic_block *region_copy)
{ {
unsigned i, n_doms; unsigned i;
bool free_region_copy = false, copying_header = false; bool free_region_copy = false, copying_header = false;
struct loop *loop = entry->dest->loop_father; struct loop *loop = entry->dest->loop_father;
edge exit_copy; edge exit_copy;
basic_block *doms; VEC (basic_block, heap) *doms;
edge redirected; edge redirected;
int total_freq = 0, entry_freq = 0; int total_freq = 0, entry_freq = 0;
gcov_type total_count = 0, entry_count = 0; gcov_type total_count = 0, entry_count = 0;
...@@ -4392,10 +4392,10 @@ tree_duplicate_sese_region (edge entry, edge exit, ...@@ -4392,10 +4392,10 @@ tree_duplicate_sese_region (edge entry, edge exit,
/* Record blocks outside the region that are dominated by something /* Record blocks outside the region that are dominated by something
inside. */ inside. */
doms = XNEWVEC (basic_block, n_basic_blocks); doms = NULL;
initialize_original_copy_tables (); initialize_original_copy_tables ();
n_doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region, doms); doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region);
if (entry->dest->count) if (entry->dest->count)
{ {
...@@ -4451,8 +4451,8 @@ tree_duplicate_sese_region (edge entry, edge exit, ...@@ -4451,8 +4451,8 @@ tree_duplicate_sese_region (edge entry, edge exit,
region, but was dominated by something inside needs recounting as region, but was dominated by something inside needs recounting as
well. */ well. */
set_immediate_dominator (CDI_DOMINATORS, entry->dest, entry->src); set_immediate_dominator (CDI_DOMINATORS, entry->dest, entry->src);
doms[n_doms++] = get_bb_original (entry->dest); VEC_safe_push (basic_block, heap, doms, get_bb_original (entry->dest));
iterate_fix_dominators (CDI_DOMINATORS, doms, n_doms); iterate_fix_dominators (CDI_DOMINATORS, doms, false);
free (doms); free (doms);
/* Add the other PHI node arguments. */ /* Add the other PHI node arguments. */
...@@ -5476,9 +5476,7 @@ remove_edge_and_dominated_blocks (edge e) ...@@ -5476,9 +5476,7 @@ remove_edge_and_dominated_blocks (edge e)
VEC_safe_push (basic_block, heap, bbs_to_fix_dom, dbb); VEC_safe_push (basic_block, heap, bbs_to_fix_dom, dbb);
} }
iterate_fix_dominators (CDI_DOMINATORS, iterate_fix_dominators (CDI_DOMINATORS, bbs_to_fix_dom, true);
VEC_address (basic_block, bbs_to_fix_dom),
VEC_length (basic_block, bbs_to_fix_dom));
BITMAP_FREE (df); BITMAP_FREE (df);
BITMAP_FREE (df_idom); BITMAP_FREE (df_idom);
......
...@@ -577,6 +577,9 @@ thread_block (basic_block bb, bool noloop_only) ...@@ -577,6 +577,9 @@ thread_block (basic_block bb, bool noloop_only)
lookup_redirection_data (e, NULL, NO_INSERT)->do_not_duplicate = true; lookup_redirection_data (e, NULL, NO_INSERT)->do_not_duplicate = true;
} }
/* We do not update dominance info. */
free_dominance_info (CDI_DOMINATORS);
/* Now create duplicates of BB. /* Now create duplicates of BB.
Note that for a block with a high outgoing degree we can waste Note that for a block with a high outgoing degree we can waste
...@@ -1057,9 +1060,6 @@ thread_through_all_blocks (bool may_peel_loop_headers) ...@@ -1057,9 +1060,6 @@ thread_through_all_blocks (bool may_peel_loop_headers)
retval |= thread_through_loop_header (loop, may_peel_loop_headers); retval |= thread_through_loop_header (loop, may_peel_loop_headers);
} }
if (retval)
free_dominance_info (CDI_DOMINATORS);
if (dump_file && (dump_flags & TDF_STATS)) if (dump_file && (dump_flags & TDF_STATS))
fprintf (dump_file, "\nJumps threaded: %lu\n", fprintf (dump_file, "\nJumps threaded: %lu\n",
thread_stats.num_threaded_edges); thread_stats.num_threaded_edges);
......
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