Commit bc35512f by Jan Hubicka Committed by Jan Hubicka

basic-block.h (create_basic_block, [...]): Kill.

	* basic-block.h (create_basic_block, merge_blocks_nomove): Kill.
	* cfgcleanup.c (merge_blocks): Rename to merge_blocks_move.
	(merge_blocks_move_predecessor_nojumps,
	 merge_blocks_move_successor_nojumps): Use merge_blocks.
	(try_optimize_cfg): Use merge_blocks_move.
	* cfgrtl.c (create_basic_block): Rename to rtl_create_basic_block.
	(merge_blocks_nomove): Rename to rtl_merge_blocks.
	(cfg_layout_create_basic_block): New.
	(rtl_can_merge_blocks): New.
	(cfg_layout_split_block): Do not alloc aux by hand.
	* cfghooks.h (cfg_hooks): Add create_basic_block, can_merge_blocks_p,
	merge_blocks.
	(create_basic_block, can_merge_blocks_p, merge_blocks): New macros.
	* cfglayout.c (cfg_layout_duplicate_bb): Do not allocate aux by hand.
	* cfgloopmanip.c (loop_split_edge_with): Likewise.
	* ifcvt.c (merge_if_block): Use merge_blocks_nomove.

	* basic-block.h (basic_block_def): Add field 'rbi'.
	* bb-reorder.c (find_traces, rotate_loop, mark_bb_visited,
	find_traces_1_round, copy_bb, connect_traces): Update use of rbi.
	* cfg.c (entry_exit_blocks): Add new field.
	* cfglayout.c: Include alloc-pool.h;
	(cfg_layout_pool): New.
	(record_effective_endpoints, fixup_reorder_chain,
	fixup_fallthru_exit_predecessor, cfg_layout_duplicate_bb): Update use
	of rbi.
	(cfg_layout_initialize_rbi): New function.
	(cfg_layout_initialize): Use it.
	(cfg_layout_finalize): Clear rbi fields.
	* cfglayout.h (RBI): Kill.
	(cfg_layout_initialize_rbi): Declare.
	* cfgloopmanip.c (copy_bbs): Use rbi.
	(record_exit_edges): Likewise.
	(duplicate_loop_to_header_edge): Likewise.
	* cfgrtl.c (cfg_layout_create_basic_block): Use
	cfg_layout_initialize_rbi.
	(cfg_layout_split_block): Use rbi.
	(cfg_layout_delete_block): Likewise.
	* loop-init.c (loop_optimizer_finalize): Likewise.
	* loop-unswitch.c (unswitch_loop): Likewise.
	* tracer.c (seen, tail_duplicate, layout_superblocks): Likewise.

	* cfgrtl.c: Update comments.
	(try_redirect_by_replacing_jump): New argument.
	(redirect_branch_edge): Break out from ...
	(rtl_redirect_edge_and_branch): ... this one.
	(update_cfg_after_block_merging): Break out from ...
	(rtl_merge_blocks): ... this one.
	(cfg_layout_split_edge): New.
	(cfg_layout_merge_blocks): New.
	(cfg_layout_can_merge_blocks_p): New.
	(cfg_layout_redirect_edge_and_branch): Reorganize.
	(cfg_layout_rtl_cfg_hooks): Fill in.
	(cfg_layout_delete_block): Kill barriers.
	* cfganal.c (can_fallthru): Deal with exit blocks
	* cfglayout.c (cfg_layout_function_header): New function
	(record_effective_endpoints): Record function header.
	(fixup_reorder_chain): Fixup dead jumptables; place header

	* basic-block.h (CLEANUP_CFGLAYOUT): New flag.
	* bb-reorder.c (cfg_layout_initialize): Update call.
	* cfgcleanup.c (try_optimize_cfg): Supress optimizations of fallthru
	edges in cfglayout mode.
	* cfglayout.c (cleanup_unconditional_jumps): Kill.
	(cfg_layout_initialize): Kill agrument loops; use cfgcleanup.
	* cfglayout.h (cfg_layout_initialize): Update prototype.
	* cfgloop.h (CP_INSIDE_CFGLAYOUT): Kill.
	* cfgloopmanip.c (loop_split_edge_with): Use split_edge.
	* flow.c (propagate_block): Do not crash when basic block ends
	by first insn in the chain.
	* loop-init.c (loop_optimizer_init):  First enter cfglayout mode; later
	do loop discovery.
	* tracer.c (tracer): Update call of cfg_layout_initialize.

From-SVN: r68899
parent 9b269fc7
Thu Jul 3 20:36:47 CEST 2003 Jan Hubicka <jh@suse.cz>
* basic-block.h (create_basic_block, merge_blocks_nomove): Kill.
* cfgcleanup.c (merge_blocks): Rename to merge_blocks_move.
(merge_blocks_move_predecessor_nojumps,
merge_blocks_move_successor_nojumps): Use merge_blocks.
(try_optimize_cfg): Use merge_blocks_move.
* cfgrtl.c (create_basic_block): Rename to rtl_create_basic_block.
(merge_blocks_nomove): Rename to rtl_merge_blocks.
(cfg_layout_create_basic_block): New.
(rtl_can_merge_blocks): New.
(cfg_layout_split_block): Do not alloc aux by hand.
* cfghooks.h (cfg_hooks): Add create_basic_block, can_merge_blocks_p,
merge_blocks.
(create_basic_block, can_merge_blocks_p, merge_blocks): New macros.
* cfglayout.c (cfg_layout_duplicate_bb): Do not allocate aux by hand.
* cfgloopmanip.c (loop_split_edge_with): Likewise.
* ifcvt.c (merge_if_block): Use merge_blocks_nomove.
* basic-block.h (basic_block_def): Add field 'rbi'.
* bb-reorder.c (find_traces, rotate_loop, mark_bb_visited,
find_traces_1_round, copy_bb, connect_traces): Update use of rbi.
* cfg.c (entry_exit_blocks): Add new field.
* cfglayout.c: Include alloc-pool.h;
(cfg_layout_pool): New.
(record_effective_endpoints, fixup_reorder_chain,
fixup_fallthru_exit_predecessor, cfg_layout_duplicate_bb): Update use
of rbi.
(cfg_layout_initialize_rbi): New function.
(cfg_layout_initialize): Use it.
(cfg_layout_finalize): Clear rbi fields.
* cfglayout.h (RBI): Kill.
(cfg_layout_initialize_rbi): Declare.
* cfgloopmanip.c (copy_bbs): Use rbi.
(record_exit_edges): Likewise.
(duplicate_loop_to_header_edge): Likewise.
* cfgrtl.c (cfg_layout_create_basic_block): Use
cfg_layout_initialize_rbi.
(cfg_layout_split_block): Use rbi.
(cfg_layout_delete_block): Likewise.
* loop-init.c (loop_optimizer_finalize): Likewise.
* loop-unswitch.c (unswitch_loop): Likewise.
* tracer.c (seen, tail_duplicate, layout_superblocks): Likewise.
* cfgrtl.c: Update comments.
(try_redirect_by_replacing_jump): New argument.
(redirect_branch_edge): Break out from ...
(rtl_redirect_edge_and_branch): ... this one.
(update_cfg_after_block_merging): Break out from ...
(rtl_merge_blocks): ... this one.
(cfg_layout_split_edge): New.
(cfg_layout_merge_blocks): New.
(cfg_layout_can_merge_blocks_p): New.
(cfg_layout_redirect_edge_and_branch): Reorganize.
(cfg_layout_rtl_cfg_hooks): Fill in.
(cfg_layout_delete_block): Kill barriers.
* cfganal.c (can_fallthru): Deal with exit blocks
* cfglayout.c (cfg_layout_function_header): New function
(record_effective_endpoints): Record function header.
(fixup_reorder_chain): Fixup dead jumptables; place header
* basic-block.h (CLEANUP_CFGLAYOUT): New flag.
* bb-reorder.c (cfg_layout_initialize): Update call.
* cfgcleanup.c (try_optimize_cfg): Supress optimizations of fallthru
edges in cfglayout mode.
* cfglayout.c (cleanup_unconditional_jumps): Kill.
(cfg_layout_initialize): Kill agrument loops; use cfgcleanup.
* cfglayout.h (cfg_layout_initialize): Update prototype.
* cfgloop.h (CP_INSIDE_CFGLAYOUT): Kill.
* cfgloopmanip.c (loop_split_edge_with): Use split_edge.
* flow.c (propagate_block): Do not crash when basic block ends
by first insn in the chain.
* loop-init.c (loop_optimizer_init): First enter cfglayout mode; later
do loop discovery.
* tracer.c (tracer): Update call of cfg_layout_initialize.
2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* Makefile.in: Use dependency variables in lieu of explicit
......
......@@ -241,6 +241,9 @@ typedef struct basic_block_def {
/* Various flags. See BB_* below. */
int flags;
/* Additional data maintained by cfg_layout routines. */
struct reorder_block_def *rbi;
} *basic_block;
#define BB_FREQ_MAX 10000
......@@ -362,9 +365,7 @@ extern void redirect_edge_succ PARAMS ((edge, basic_block));
extern edge redirect_edge_succ_nodup PARAMS ((edge, basic_block));
extern void redirect_edge_pred PARAMS ((edge, basic_block));
extern basic_block create_basic_block_structure PARAMS ((rtx, rtx, rtx, basic_block));
extern basic_block create_basic_block PARAMS ((rtx, rtx, basic_block));
extern void clear_bb_flags PARAMS ((void));
extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
basic_block));
extern void tidy_fallthru_edges PARAMS ((void));
......@@ -500,6 +501,7 @@ enum update_life_extent
#define CLEANUP_THREADING 64 /* Do jump threading. */
#define CLEANUP_NO_INSN_DEL 128 /* Do not try to delete trivially dead
insns. */
#define CLEANUP_CFGLAYOUT 256 /* Do cleanup in cfglayout mode. */
extern void life_analysis PARAMS ((rtx, FILE *, int));
extern int update_life_info PARAMS ((sbitmap, enum update_life_extent,
int));
......
......@@ -205,7 +205,7 @@ find_traces (int *n_traces, struct trace *traces)
basic_block bb;
fprintf (rtl_dump_file, "Trace %d (round %d): ", i + 1,
traces[i].round + 1);
for (bb = traces[i].first; bb != traces[i].last; bb = RBI (bb)->next)
for (bb = traces[i].first; bb != traces[i].last; bb = bb->rbi->next)
fprintf (rtl_dump_file, "%d [%d] ", bb->index, bb->frequency);
fprintf (rtl_dump_file, "%d [%d]\n", bb->index, bb->frequency);
}
......@@ -237,14 +237,14 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
edge e;
for (e = bb->succ; e; e = e->succ_next)
if (e->dest != EXIT_BLOCK_PTR
&& RBI (e->dest)->visited != trace_n
&& e->dest->rbi->visited != trace_n
&& (e->flags & EDGE_CAN_FALLTHRU)
&& !(e->flags & EDGE_COMPLEX))
{
if (is_preferred)
{
/* The best edge is preferred. */
if (!RBI (e->dest)->visited
if (!e->dest->rbi->visited
|| bbd[e->dest->index].start_of_trace >= 0)
{
/* The current edge E is also preferred. */
......@@ -260,7 +260,7 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
}
else
{
if (!RBI (e->dest)->visited
if (!e->dest->rbi->visited
|| bbd[e->dest->index].start_of_trace >= 0)
{
/* The current edge E is preferred. */
......@@ -283,7 +283,7 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
}
}
}
bb = RBI (bb)->next;
bb = bb->rbi->next;
}
while (bb != back_edge->dest);
......@@ -293,17 +293,17 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
the trace. */
if (back_edge->dest == trace->first)
{
trace->first = RBI (best_bb)->next;
trace->first = best_bb->rbi->next;
}
else
{
basic_block prev_bb;
for (prev_bb = trace->first;
RBI (prev_bb)->next != back_edge->dest;
prev_bb = RBI (prev_bb)->next)
prev_bb->rbi->next != back_edge->dest;
prev_bb = prev_bb->rbi->next)
;
RBI (prev_bb)->next = RBI (best_bb)->next;
prev_bb->rbi->next = best_bb->rbi->next;
/* Try to get rid of uncond jump to cond jump. */
if (prev_bb->succ && !prev_bb->succ->succ_next)
......@@ -324,7 +324,7 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
/* We have not found suitable loop tail so do no rotation. */
best_bb = back_edge->src;
}
RBI (best_bb)->next = NULL;
best_bb->rbi->next = NULL;
return best_bb;
}
......@@ -333,7 +333,7 @@ rotate_loop (edge back_edge, struct trace *trace, int trace_n)
static void
mark_bb_visited (basic_block bb, int trace)
{
RBI (bb)->visited = trace;
bb->rbi->visited = trace;
if (bbd[bb->index].heap)
{
fibheap_delete_node (bbd[bb->index].heap, bbd[bb->index].node);
......@@ -420,8 +420,8 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
if (e->dest == EXIT_BLOCK_PTR)
continue;
if (RBI (e->dest)->visited
&& RBI (e->dest)->visited != *n_traces)
if (e->dest->rbi->visited
&& e->dest->rbi->visited != *n_traces)
continue;
prob = e->probability;
......@@ -453,7 +453,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
{
if (e == best_edge
|| e->dest == EXIT_BLOCK_PTR
|| RBI (e->dest)->visited)
|| e->dest->rbi->visited)
continue;
key = bb_to_key (e->dest);
......@@ -508,7 +508,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
if (best_edge) /* Suitable successor was found. */
{
if (RBI (best_edge->dest)->visited == *n_traces)
if (best_edge->dest->rbi->visited == *n_traces)
{
/* We do nothing with one basic block loops. */
if (best_edge->dest != bb)
......@@ -528,7 +528,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
"Rotating loop %d - %d\n",
best_edge->dest->index, bb->index);
}
RBI (bb)->next = best_edge->dest;
bb->rbi->next = best_edge->dest;
bb = rotate_loop (best_edge, trace, *n_traces);
}
}
......@@ -583,7 +583,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
if (e != best_edge
&& (e->flags & EDGE_CAN_FALLTHRU)
&& !(e->flags & EDGE_COMPLEX)
&& !RBI (e->dest)->visited
&& !e->dest->rbi->visited
&& !e->dest->pred->pred_next
&& e->dest->succ
&& (e->dest->succ->flags & EDGE_CAN_FALLTHRU)
......@@ -599,7 +599,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
break;
}
RBI (bb)->next = best_edge->dest;
bb->rbi->next = best_edge->dest;
bb = best_edge->dest;
}
}
......@@ -615,7 +615,7 @@ find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
for (e = bb->succ; e; e = e->succ_next)
{
if (e->dest == EXIT_BLOCK_PTR
|| RBI (e->dest)->visited)
|| e->dest->rbi->visited)
continue;
if (bbd[e->dest->index].heap)
......@@ -656,15 +656,15 @@ copy_bb (basic_block old_bb, edge e, basic_block bb, int trace)
new_bb = cfg_layout_duplicate_bb (old_bb, e);
if (e->dest != new_bb)
abort ();
if (RBI (e->dest)->visited)
if (e->dest->rbi->visited)
abort ();
if (rtl_dump_file)
fprintf (rtl_dump_file,
"Duplicated bb %d (created bb %d)\n",
old_bb->index, new_bb->index);
RBI (new_bb)->visited = trace;
RBI (new_bb)->next = RBI (bb)->next;
RBI (bb)->next = new_bb;
new_bb->rbi->visited = trace;
new_bb->rbi->next = bb->rbi->next;
bb->rbi->next = new_bb;
if (new_bb->index >= array_size || last_basic_block > array_size)
{
......@@ -826,7 +826,7 @@ connect_traces (int n_traces, struct trace *traces)
}
if (best)
{
RBI (best->src)->next = best->dest;
best->src->rbi->next = best->dest;
t2 = bbd[best->src->index].end_of_trace;
connected[t2] = true;
if (rtl_dump_file)
......@@ -840,7 +840,7 @@ connect_traces (int n_traces, struct trace *traces)
}
if (last_trace >= 0)
RBI (traces[last_trace].last)->next = traces[t2].first;
traces[last_trace].last->rbi->next = traces[t2].first;
last_trace = t;
/* Find the successor traces. */
......@@ -876,7 +876,7 @@ connect_traces (int n_traces, struct trace *traces)
best->src->index, best->dest->index);
}
t = bbd[best->dest->index].start_of_trace;
RBI (traces[last_trace].last)->next = traces[t].first;
traces[last_trace].last->rbi->next = traces[t].first;
connected[t] = true;
last_trace = t;
}
......@@ -964,7 +964,7 @@ connect_traces (int n_traces, struct trace *traces)
if (next_bb && next_bb != EXIT_BLOCK_PTR)
{
t = bbd[next_bb->index].start_of_trace;
RBI (traces[last_trace].last)->next = traces[t].first;
traces[last_trace].last->rbi->next = traces[t].first;
connected[t] = true;
last_trace = t;
}
......@@ -982,7 +982,7 @@ connect_traces (int n_traces, struct trace *traces)
basic_block bb;
fprintf (rtl_dump_file, "Final order:\n");
for (bb = traces[0].first; bb; bb = RBI (bb)->next)
for (bb = traces[0].first; bb; bb = bb->rbi->next)
fprintf (rtl_dump_file, "%d ", bb->index);
fprintf (rtl_dump_file, "\n");
fflush (rtl_dump_file);
......@@ -1064,7 +1064,7 @@ reorder_basic_blocks (void)
if ((* targetm.cannot_modify_jumps_p) ())
return;
cfg_layout_initialize (NULL);
cfg_layout_initialize ();
set_edge_can_fallthru_flag ();
mark_dfs_back_edges ();
......
......@@ -113,7 +113,8 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* loop_father */
0, /* count */
0, /* frequency */
0 /* flags */
0, /* flags */
NULL /* rbi */
},
{
NULL, /* head */
......@@ -134,7 +135,8 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* loop_father */
0, /* count */
0, /* frequency */
0 /* flags */
0, /* flags */
NULL /* rbi */
}
};
......
......@@ -104,12 +104,12 @@ bool
can_fallthru (basic_block src, basic_block target)
{
rtx insn = src->end;
rtx insn2 = target->head;
rtx insn2 = target == EXIT_BLOCK_PTR ? NULL : target->head;
if (src->next_bb != target)
return 0;
if (!active_insn_p (insn2))
if (insn2 && !active_insn_p (insn2))
insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
......
......@@ -77,7 +77,6 @@ static bool label_is_jump_target_p (rtx, rtx);
static bool tail_recursion_label_p (rtx);
static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block);
static void merge_blocks_move_successor_nojumps (basic_block, basic_block);
static basic_block merge_blocks (edge,basic_block,basic_block, int);
static bool try_optimize_cfg (int);
static bool try_simplify_condjump (basic_block);
static bool try_forward_edges (int, basic_block);
......@@ -704,7 +703,7 @@ merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
link_block (a, b->prev_bb);
/* Now blocks A and B are contiguous. Merge them. */
merge_blocks_nomove (a, b);
merge_blocks (a, b);
}
/* Blocks A and B are to be merged into a single block. B has no outgoing
......@@ -758,7 +757,7 @@ merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
b->index, a->index);
/* Now blocks A and B are contiguous. Merge them. */
merge_blocks_nomove (a, b);
merge_blocks (a, b);
}
/* Attempt to merge basic blocks that are potentially non-adjacent.
......@@ -774,7 +773,7 @@ merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
relative ordering of these two. Hopefully it is not too common. */
static basic_block
merge_blocks (edge e, basic_block b, basic_block c, int mode)
merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
{
basic_block next;
/* If C has a tail recursion label, do not merge. There is no
......@@ -790,7 +789,7 @@ merge_blocks (edge e, basic_block b, basic_block c, int mode)
if (e->flags & EDGE_FALLTHRU)
{
int b_index = b->index, c_index = c->index;
merge_blocks_nomove (b, c);
merge_blocks (b, c);
update_forwarder_flag (b);
if (rtl_dump_file)
......@@ -1686,7 +1685,8 @@ try_optimize_cfg (int mode)
b->index);
delete_block (b);
changed = true;
if (!(mode & CLEANUP_CFGLAYOUT))
changed = true;
b = c;
}
......@@ -1712,15 +1712,24 @@ try_optimize_cfg (int mode)
{
rtx label = b->head;
b->head = NEXT_INSN (b->head);
delete_insn_chain (label, label);
/* In the case label is undeletable, move it after the
BASIC_BLOCK note. */
if (NOTE_LINE_NUMBER (b->head) == NOTE_INSN_DELETED_LABEL)
{
rtx bb_note = NEXT_INSN (b->head);
reorder_insns_nobb (label, label, bb_note);
b->head = bb_note;
}
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
b->index);
}
/* If we fall through an empty block, we can remove it. */
if (b->pred->pred_next == NULL
if (!(mode & CLEANUP_CFGLAYOUT)
&& b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& GET_CODE (b->head) != CODE_LABEL
&& FORWARDER_BLOCK_P (b)
......@@ -1746,21 +1755,39 @@ try_optimize_cfg (int mode)
&& !(s->flags & EDGE_COMPLEX)
&& (c = s->dest) != EXIT_BLOCK_PTR
&& c->pred->pred_next == NULL
&& b != c
/* If the jump insn has side effects,
we can't kill the edge. */
&& (GET_CODE (b->end) != JUMP_INSN
|| (flow2_completed
? simplejump_p (b->end)
: onlyjump_p (b->end)))
&& (next = merge_blocks (s, b, c, mode)))
{
b = next;
changed_here = true;
&& b != c)
{
/* When not in cfg_layout mode use code aware of reordering
INSN. This code possibly creates new basic blocks so it
does not fit merge_blocks interface and is kept here in
hope that it will become useless once more of compiler
is transformed to use cfg_layout mode. */
if ((mode & CLEANUP_CFGLAYOUT)
&& can_merge_blocks_p (b, c))
{
merge_blocks (b, c);
update_forwarder_flag (b);
changed_here = true;
}
else if (!(mode & CLEANUP_CFGLAYOUT)
/* If the jump insn has side effects,
we can't kill the edge. */
&& (GET_CODE (b->end) != JUMP_INSN
|| (flow2_completed
? simplejump_p (b->end)
: onlyjump_p (b->end)))
&& (next = merge_blocks_move (s, b, c, mode)))
{
b = next;
changed_here = true;
}
}
/* Simplify branch over branch. */
if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
if ((mode & CLEANUP_EXPENSIVE)
&& !(mode & CLEANUP_CFGLAYOUT)
&& try_simplify_condjump (b))
changed_here = true;
/* If B has a single outgoing edge, but uses a
......
......@@ -31,6 +31,9 @@ struct cfg_hooks
/* Basic CFG manipulation. */
/* Return new basic block */
basic_block (*create_basic_block) PARAMS ((void *head, void *end, basic_block after));
/* Redirect edge E to the given basic block B and update underlying program
representation. Returns false when edge is not easily redirectable for
whatever reason. */
......@@ -47,6 +50,12 @@ struct cfg_hooks
/* Split basic block B after specified instruction I. */
edge (*split_block) (basic_block b, void * i);
/* Return true when blocks A and B can be merged into single basic block. */
bool (*can_merge_blocks_p) PARAMS ((basic_block a, basic_block b));
/* Merge blocks A and B. */
void (*merge_blocks) PARAMS ((basic_block a, basic_block b));
/* Higher level functions representable by primitive operations above if
we didn't have some oddities in RTL and Tree representations. */
basic_block (*cfgh_split_edge) (edge);
......@@ -57,6 +66,9 @@ struct cfg_hooks
#define split_block(e,i) cfg_hooks->split_block (e,i)
#define delete_block(b) cfg_hooks->delete_block (b)
#define split_edge(e) cfg_hooks->cfgh_split_edge (e)
#define create_basic_block(h,e,a) cfg_hooks->create_basic_block (h,e,a)
#define can_merge_blocks_p(a,b) cfg_hooks->can_merge_blocks_p (a,b)
#define merge_blocks(a,b) cfg_hooks->merge_blocks (a,b)
/* Hooks containers. */
extern struct cfg_hooks rtl_cfg_hooks;
......
......@@ -33,13 +33,12 @@ typedef struct reorder_block_def
int visited;
} *reorder_block_def;
#define RBI(BB) ((reorder_block_def) (BB)->aux)
extern rtx cfg_layout_function_footer;
extern void cfg_layout_initialize (struct loops *);
extern void cfg_layout_initialize (void);
extern void cfg_layout_finalize (void);
extern bool cfg_layout_can_duplicate_bb_p (basic_block);
extern basic_block cfg_layout_duplicate_bb (basic_block, edge);
extern void insn_locators_initialize (void);
extern void reemit_insn_block_notes (void);
extern void cfg_layout_initialize_rbi (basic_block);
......@@ -294,8 +294,7 @@ extern int fix_loop_placement (struct loop *);
enum
{
CP_SIMPLE_PREHEADERS = 1,
CP_INSIDE_CFGLAYOUT = 2
CP_SIMPLE_PREHEADERS = 1
};
extern void create_preheaders (struct loops *, int);
......
......@@ -860,7 +860,7 @@ copy_bbs (basic_block *bbs, int n, edge entry, edge latch_edge,
/* Duplicate. */
bb = bbs[i];
new_bb = (*new_bbs)[i] = cfg_layout_duplicate_bb (bb, NULL);
RBI (new_bb)->duplicated = 1;
new_bb->rbi->duplicated = 1;
/* Add to loop. */
add_bb_to_loop (new_bb, bb->loop_father->copy);
add_to_dominance_info (loops->cfg.dom, new_bb);
......@@ -886,7 +886,7 @@ copy_bbs (basic_block *bbs, int n, edge entry, edge latch_edge,
{
/* For anything else than loop header, just copy it. */
dom_bb = get_immediate_dominator (loops->cfg.dom, bb);
dom_bb = RBI (dom_bb)->copy;
dom_bb = dom_bb->rbi->copy;
}
else
{
......@@ -910,7 +910,7 @@ copy_bbs (basic_block *bbs, int n, edge entry, edge latch_edge,
e_pred = e->pred_next;
if (!RBI (src)->duplicated)
if (!src->rbi->duplicated)
continue;
/* Leads to copied loop and it is not latch edge, redirect it. */
......@@ -919,24 +919,24 @@ copy_bbs (basic_block *bbs, int n, edge entry, edge latch_edge,
if (add_irreducible_flag
&& (bb->loop_father == header->loop_father
|| RBI (src)->original->loop_father == header->loop_father))
|| src->rbi->original->loop_father == header->loop_father))
e->flags |= EDGE_IRREDUCIBLE_LOOP;
}
}
/* Redirect header edge. */
bb = RBI (latch_edge->src)->copy;
bb = latch_edge->src->rbi->copy;
for (e = bb->succ; e->dest != latch_edge->dest; e = e->succ_next);
*header_edge = e;
loop_redirect_edge (*header_edge, header);
/* Redirect entry to copy of header. */
loop_redirect_edge (entry, RBI (header)->copy);
loop_redirect_edge (entry, header->rbi->copy);
*copy_header_edge = entry;
/* Clear information about duplicates. */
for (i = 0; i < n; i++)
RBI ((*new_bbs)[i])->duplicated = 0;
(*new_bbs)[i]->rbi->duplicated = 0;
}
/* Check whether LOOP's body can be duplicated. */
......@@ -995,7 +995,7 @@ record_exit_edges (edge orig, basic_block *bbs, int nbbs, edge *to_remove,
return;
}
for (e = RBI (orig->src)->copy->succ; e; e = e->succ_next)
for (e = orig->src->rbi->copy->succ; e; e = e->succ_next)
if (e->dest == orig->dest)
break;
if (!e)
......@@ -1175,7 +1175,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
copy_bbs (bbs, n, e, latch_edge, &new_bbs, loops,
&e, &he, add_irreducible_flag);
if (is_latch)
loop->latch = RBI (latch)->copy;
loop->latch = latch->rbi->copy;
/* Record exit edges in this copy. */
if (TEST_BIT (wont_exit, j + 1))
......@@ -1209,7 +1209,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
if (!first_active_latch)
{
memcpy (first_active, new_bbs, n * sizeof (basic_block));
first_active_latch = RBI (latch)->copy;
first_active_latch = latch->rbi->copy;
}
free (new_bbs);
......@@ -1217,11 +1217,11 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
/* Original loop header is dominated by latch copy
if we duplicated on its only entry edge. */
if (!is_latch && !header->pred->pred_next->pred_next)
set_immediate_dominator (loops->cfg.dom, header, RBI (latch)->copy);
set_immediate_dominator (loops->cfg.dom, header, latch->rbi->copy);
if (is_latch && j == 0)
{
/* Update edge from latch. */
for (latch_edge = RBI (header)->copy->pred;
for (latch_edge = header->rbi->copy->pred;
latch_edge->src != latch;
latch_edge = latch_edge->pred_next);
}
......@@ -1409,33 +1409,20 @@ loop_split_edge_with (edge e, rtx insns, struct loops *loops)
/* Create basic block for it. */
new_bb = create_basic_block (NULL_RTX, NULL_RTX, EXIT_BLOCK_PTR->prev_bb);
new_bb = split_edge (e);
add_to_dominance_info (loops->cfg.dom, new_bb);
add_bb_to_loop (new_bb, loop_c);
new_bb->flags = insns ? BB_SUPERBLOCK : 0;
new_e = make_edge (new_bb, dest, EDGE_FALLTHRU);
new_e->probability = REG_BR_PROB_BASE;
new_e->count = e->count;
new_e = new_bb->succ;
if (e->flags & EDGE_IRREDUCIBLE_LOOP)
{
new_bb->flags |= BB_IRREDUCIBLE_LOOP;
new_e->flags |= EDGE_IRREDUCIBLE_LOOP;
}
new_bb->count = e->count;
new_bb->frequency = EDGE_FREQUENCY (e);
redirect_edge_and_branch_force (e, new_bb);
alloc_aux_for_block (new_bb, sizeof (struct reorder_block_def));
if (insns)
{
start_sequence ();
emit_insn (insns);
insns = get_insns ();
end_sequence ();
emit_insn_after (insns, new_bb->end);
}
emit_insn_after (insns, new_bb->end);
set_immediate_dominator (loops->cfg.dom, new_bb, src);
set_immediate_dominator (loops->cfg.dom, dest,
......
......@@ -2063,7 +2063,10 @@ propagate_block (basic_block bb, regset live, regset local_set,
IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
prev = propagate_one_insn (pbi, insn);
changed |= NEXT_INSN (prev) != insn;
if (!prev)
changed |= insn != get_insns ();
else
changed |= NEXT_INSN (prev) != insn;
if (insn == bb->head)
break;
......
......@@ -2016,7 +2016,7 @@ merge_if_block (ce_info)
fallthru = block_fallthru (bb);
if (post_dominators)
delete_from_dominance_info (post_dominators, bb);
merge_blocks_nomove (combo_bb, bb);
merge_blocks (combo_bb, bb);
num_removed_blocks++;
}
while (bb != last_test_bb);
......@@ -2033,7 +2033,7 @@ merge_if_block (ce_info)
then_bb->global_live_at_end);
if (post_dominators)
delete_from_dominance_info (post_dominators, then_bb);
merge_blocks_nomove (combo_bb, then_bb);
merge_blocks (combo_bb, then_bb);
num_removed_blocks++;
}
......@@ -2044,7 +2044,7 @@ merge_if_block (ce_info)
{
if (post_dominators)
delete_from_dominance_info (post_dominators, else_bb);
merge_blocks_nomove (combo_bb, else_bb);
merge_blocks (combo_bb, else_bb);
num_removed_blocks++;
}
......@@ -2101,7 +2101,7 @@ merge_if_block (ce_info)
if (post_dominators)
delete_from_dominance_info (post_dominators, join_bb);
merge_blocks_nomove (combo_bb, join_bb);
merge_blocks (combo_bb, join_bb);
num_removed_blocks++;
}
else
......@@ -3129,7 +3129,7 @@ if_convert (x_life_data_ok)
life_data_ok = (x_life_data_ok != 0);
/* Free up basic_block_for_insn so that we don't have to keep it
up to date, either here or in merge_blocks_nomove. */
up to date, either here or in merge_blocks. */
free_basic_block_vars (1);
/* Compute postdominators if we think we'll use them. */
......
......@@ -37,6 +37,9 @@ loop_optimizer_init (dumpfile)
struct loops *loops = xcalloc (1, sizeof (struct loops));
edge e;
/* Initialize structures for layout changes. */
cfg_layout_initialize ();
/* Avoid annoying special cases of edges going to exit
block. */
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
......@@ -47,9 +50,16 @@ loop_optimizer_init (dumpfile)
if (flow_loops_find (loops, LOOP_TREE) <= 1)
{
basic_block bb;
/* No loops. */
flow_loops_free (loops);
free (loops);
/* Make chain. */
FOR_EACH_BB (bb)
if (bb->next_bb != EXIT_BLOCK_PTR)
bb->rbi->next = bb->next_bb;
cfg_layout_finalize ();
return NULL;
}
......@@ -59,11 +69,8 @@ loop_optimizer_init (dumpfile)
free (loops->cfg.dfs_order);
loops->cfg.dfs_order = NULL;
/* Initialize structures for layout changes. */
cfg_layout_initialize (loops);
/* Create pre-headers. */
create_preheaders (loops, CP_SIMPLE_PREHEADERS | CP_INSIDE_CFGLAYOUT);
create_preheaders (loops, CP_SIMPLE_PREHEADERS);
/* Force all latches to have only single successor. */
force_single_succ_latches (loops);
......@@ -94,7 +101,7 @@ loop_optimizer_finalize (loops, dumpfile)
/* Make chain. */
FOR_EACH_BB (bb)
if (bb->next_bb != EXIT_BLOCK_PTR)
RBI (bb)->next = bb->next_bb;
bb->rbi->next = bb->next_bb;
/* Another dump. */
flow_loops_dump (loops, dumpfile, NULL, 1);
......
......@@ -377,7 +377,7 @@ unswitch_loop (loops, loop, unswitch_on)
entry->flags |= irred_flag;
/* Record the block with condition we unswitch on. */
unswitch_on_alt = RBI (unswitch_on)->copy;
unswitch_on_alt = unswitch_on->rbi->copy;
/* Make a copy of the block containing the condition; we will use
it as switch to decide which loop we want to use. */
......@@ -395,14 +395,14 @@ unswitch_loop (loops, loop, unswitch_on)
switch_bb->succ->succ_next->flags &= ~EDGE_IRREDUCIBLE_LOOP;
}
add_to_dominance_info (loops->cfg.dom, switch_bb);
RBI (unswitch_on)->copy = unswitch_on_alt;
unswitch_on->rbi->copy = unswitch_on_alt;
/* Loopify from the copy of LOOP body, constructing the new loop. */
for (latch_edge = RBI (loop->latch)->copy->succ;
for (latch_edge = loop->latch->rbi->copy->succ;
latch_edge->dest != loop->header;
latch_edge = latch_edge->succ_next);
nloop = loopify (loops, latch_edge,
RBI (loop->header)->copy->pred, switch_bb);
loop->header->rbi->copy->pred, switch_bb);
/* Remove branches that are now unreachable in new loops. We rely on the
fact that cfg_layout_duplicate_bb reverses list of edges. */
......
......@@ -64,7 +64,7 @@ static int branch_ratio_cutoff;
/* Return true if BB has been seen - it is connected to some trace
already. */
#define seen(bb) (RBI (bb)->visited || RBI (bb)->next)
#define seen(bb) (bb->rbi->visited || bb->rbi->next)
/* Return true if we should ignore the basic block for purposes of tracing. */
static bool
......@@ -295,8 +295,8 @@ tail_duplicate ()
fprintf (rtl_dump_file, "Duplicated %i as %i [%i]\n",
old->index, bb2->index, bb2->frequency);
}
RBI (bb)->next = bb2;
RBI (bb2)->visited = 1;
bb->rbi->next = bb2;
bb2->rbi->visited = 1;
bb = bb2;
/* In case the trace became infrequent, stop duplicating. */
if (ignore_bb_p (bb))
......@@ -330,28 +330,28 @@ layout_superblocks ()
while (bb != EXIT_BLOCK_PTR)
{
edge e, best = NULL;
while (RBI (end)->next)
end = RBI (end)->next;
while (end->rbi->next)
end = end->rbi->next;
for (e = end->succ; e; e = e->succ_next)
if (e->dest != EXIT_BLOCK_PTR
&& e->dest != ENTRY_BLOCK_PTR->succ->dest
&& !RBI (e->dest)->visited
&& !e->dest->rbi->visited
&& (!best || EDGE_FREQUENCY (e) > EDGE_FREQUENCY (best)))
best = e;
if (best)
{
RBI (end)->next = best->dest;
RBI (best->dest)->visited = 1;
end->rbi->next = best->dest;
best->dest->rbi->visited = 1;
}
else
for (; bb != EXIT_BLOCK_PTR; bb = bb->next_bb)
{
if (!RBI (bb)->visited)
if (!bb->rbi->visited)
{
RBI (end)->next = bb;
RBI (bb)->visited = 1;
end->rbi->next = bb;
bb->rbi->visited = 1;
break;
}
}
......@@ -365,7 +365,7 @@ tracer ()
{
if (n_basic_blocks <= 1)
return;
cfg_layout_initialize (NULL);
cfg_layout_initialize ();
mark_dfs_back_edges ();
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
......
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