bb-reorder.c (find_traces_1_round): Don't connect easy to copy successors with multiple predecessors.
* bb-reorder.c (find_traces_1_round): Don't connect easy to copy successors with multiple predecessors. (connect_traces): Try harder to copy traces of length 1. * function.h (struct function): Add computed_goto_common_label, computed_goto_common_reg. * function.c (free_after_compilation): Zap them. * stmt.c (expand_computed_goto): Use them to produce one indirect branch per function. From-SVN: r62944
This commit is contained in:
parent
b54cf83ae6
commit
99dc72775f
@ -38,6 +38,18 @@
|
||||
* config/rs6000/rs64.md: New file.
|
||||
[Some DFA descriptions based on work by Michael Hayes]
|
||||
|
||||
2003-02-15 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* bb-reorder.c (find_traces_1_round): Don't connect easy to copy
|
||||
successors with multiple predecessors.
|
||||
(connect_traces): Try harder to copy traces of length 1.
|
||||
|
||||
* function.h (struct function): Add computed_goto_common_label,
|
||||
computed_goto_common_reg.
|
||||
* function.c (free_after_compilation): Zap them.
|
||||
* stmt.c (expand_computed_goto): Use them to produce one
|
||||
indirect branch per function.
|
||||
|
||||
2003-02-15 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* cfgcleanup.c: Include params.h.
|
||||
|
@ -448,6 +448,12 @@ find_traces_1_round (branch_th, exec_th, count_th, traces, n_traces, round,
|
||||
|| prob < branch_th || freq < exec_th || e->count < count_th)
|
||||
continue;
|
||||
|
||||
/* If the destination has multiple precessesors, and can be
|
||||
duplicated cheaper than a jump, don't allow it to be added
|
||||
to a trace. We'll duplicate it when connecting traces. */
|
||||
if (e->dest->pred->pred_next && copy_bb_p (e->dest, 0))
|
||||
continue;
|
||||
|
||||
if (better_edge_p (bb, e, prob, freq, best_prob, best_freq))
|
||||
{
|
||||
best_edge = e;
|
||||
@ -905,19 +911,27 @@ connect_traces (n_traces, traces)
|
||||
/* Try to connect the traces by duplication of 1 block. */
|
||||
edge e2;
|
||||
basic_block next_bb = NULL;
|
||||
bool try_copy = false;
|
||||
|
||||
for (e = traces[t].last->succ; e; e = e->succ_next)
|
||||
if (e->dest != EXIT_BLOCK_PTR
|
||||
&& (e->flags & EDGE_CAN_FALLTHRU)
|
||||
&& !(e->flags & EDGE_COMPLEX)
|
||||
&& (EDGE_FREQUENCY (e) >= freq_threshold)
|
||||
&& (e->count >= count_threshold)
|
||||
&& (!best
|
||||
|| e->probability > best->probability))
|
||||
&& (!best || e->probability > best->probability))
|
||||
{
|
||||
edge best2 = NULL;
|
||||
int best2_len = 0;
|
||||
|
||||
/* If the destination trace is only one block
|
||||
long, then no need to search the successor
|
||||
blocks of the trace. Accept it. */
|
||||
if (traces[bbd[e->dest->index].start_of_trace].length == 1)
|
||||
{
|
||||
best = e;
|
||||
try_copy = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (e2 = e->dest->succ; e2; e2 = e2->succ_next)
|
||||
{
|
||||
int di = e2->dest->index;
|
||||
@ -942,10 +956,18 @@ connect_traces (n_traces, traces)
|
||||
else
|
||||
best2_len = INT_MAX;
|
||||
next_bb = e2->dest;
|
||||
try_copy = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best && next_bb && copy_bb_p (best->dest, !optimize_size))
|
||||
|
||||
/* Copy tiny blocks always; copy larger blocks only when the
|
||||
edge is traversed frequently enough. */
|
||||
if (try_copy
|
||||
&& copy_bb_p (best->dest,
|
||||
!optimize_size
|
||||
&& EDGE_FREQUENCY (best) >= freq_threshold
|
||||
&& best->count >= count_threshold))
|
||||
{
|
||||
basic_block new_bb;
|
||||
|
||||
@ -953,7 +975,9 @@ connect_traces (n_traces, traces)
|
||||
{
|
||||
fprintf (rtl_dump_file, "Connection: %d %d ",
|
||||
traces[t].last->index, best->dest->index);
|
||||
if (next_bb == EXIT_BLOCK_PTR)
|
||||
if (!next_bb)
|
||||
fputc ('\n', rtl_dump_file);
|
||||
else if (next_bb == EXIT_BLOCK_PTR)
|
||||
fprintf (rtl_dump_file, "exit\n");
|
||||
else
|
||||
fprintf (rtl_dump_file, "%d\n", next_bb->index);
|
||||
@ -961,7 +985,7 @@ connect_traces (n_traces, traces)
|
||||
|
||||
new_bb = copy_bb (best->dest, best, traces[t].last, t);
|
||||
traces[t].last = new_bb;
|
||||
if (next_bb != EXIT_BLOCK_PTR)
|
||||
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;
|
||||
|
@ -452,6 +452,8 @@ free_after_compilation (f)
|
||||
f->x_nonlocal_goto_stack_level = NULL;
|
||||
f->x_cleanup_label = NULL;
|
||||
f->x_return_label = NULL;
|
||||
f->computed_goto_common_label = NULL;
|
||||
f->computed_goto_common_reg = NULL;
|
||||
f->x_save_expr_regs = NULL;
|
||||
f->x_stack_slot_list = NULL;
|
||||
f->x_rtl_expr_chain = NULL;
|
||||
|
@ -268,6 +268,10 @@ struct function GTY(())
|
||||
on machines which require execution of the epilogue on all returns. */
|
||||
rtx x_return_label;
|
||||
|
||||
/* Label and register for unswitching computed gotos. */
|
||||
rtx computed_goto_common_label;
|
||||
rtx computed_goto_common_reg;
|
||||
|
||||
/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
|
||||
So we can mark them all live at the end of the function, if nonopt. */
|
||||
rtx x_save_expr_regs;
|
||||
|
19
gcc/stmt.c
19
gcc/stmt.c
@ -539,10 +539,23 @@ expand_computed_goto (exp)
|
||||
#endif
|
||||
|
||||
emit_queue ();
|
||||
do_pending_stack_adjust ();
|
||||
emit_indirect_jump (x);
|
||||
|
||||
current_function_has_computed_jump = 1;
|
||||
if (! cfun->computed_goto_common_label)
|
||||
{
|
||||
cfun->computed_goto_common_reg = copy_to_mode_reg (Pmode, x);
|
||||
cfun->computed_goto_common_label = gen_label_rtx ();
|
||||
emit_label (cfun->computed_goto_common_label);
|
||||
|
||||
do_pending_stack_adjust ();
|
||||
emit_indirect_jump (cfun->computed_goto_common_reg);
|
||||
|
||||
current_function_has_computed_jump = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_move_insn (cfun->computed_goto_common_reg, x);
|
||||
emit_jump (cfun->computed_goto_common_label);
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle goto statements and the labels that they can go to. */
|
||||
|
Loading…
Reference in New Issue
Block a user