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:
Richard Henderson 2003-02-15 13:22:56 -08:00 committed by Richard Henderson
parent b54cf83ae6
commit 99dc72775f
5 changed files with 65 additions and 10 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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. */