critical edges handling cleanup
Jan Hubicka
jh@suse.cz
Tue Sep 11 07:14:00 GMT 2001
Hi,
this patch removes EDGE_CRITICAL flag and adds trivial EDGE_CRITICAL_P macro.
The mark_critical_edges is one of the top CPU hogs at Brand's testcase and
it is cheap enought to determine the information when needed and expensive
enought to keep it up-to-date to make this sollution superrior IMO.
Regtesting bootstrapping i686 together with previous patches.
Honza
Tue Sep 11 15:42:34 CEST 2001 Jan Hubicka <jh@suse.cz>
* basic-block.h (EDGE_CRITICAL): Remove; renumber other flags.
(EDGE_CRITICAL_P): New predicate.
* cfg.c (force_nonfallthru_and_redirect, split_edge): Kill EDGE_CRITICAL
handling.
(insert_insn_on_edge): Use EDGE_CRITICAL_P.
(dump_edge_info): Remove "crit".
* cfganal.c (mark_critical_edges): Kill.
* cfgbuild.c (find_basic_blocks): Remove mark_critical_edges call.
* cfgcleanup.c (cleanup_cfg): Likewise.
* profile.c (instrument_edges): Use EDGE_CRITICAL_P.
(find_spanning_tree): Likewise.
* reg-stack.c (convert_regs_1): Likewise.
* ssa.c (mark_regs_equivalent_over_bad_edges): Likewise.
*** basic-block.h.old Tue Sep 11 15:34:21 2001
--- basic-block.h Tue Sep 11 15:51:25 2001
*************** typedef struct edge_def {
*** 140,151 ****
} *edge;
#define EDGE_FALLTHRU 1
! #define EDGE_CRITICAL 2
! #define EDGE_ABNORMAL 4
! #define EDGE_ABNORMAL_CALL 8
! #define EDGE_EH 16
! #define EDGE_FAKE 32
! #define EDGE_DFS_BACK 64
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
--- 140,150 ----
} *edge;
#define EDGE_FALLTHRU 1
! #define EDGE_ABNORMAL 2
! #define EDGE_ABNORMAL_CALL 4
! #define EDGE_EH 8
! #define EDGE_FAKE 16
! #define EDGE_DFS_BACK 32
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
*************** struct edge_list
*** 536,541 ****
--- 535,544 ----
* (e)->probability \
+ REG_BR_PROB_BASE / 2) \
/ REG_BR_PROB_BASE)
+
+ /* Return nonzero if edge is critical. */
+ #define EDGE_CRITICAL_P(e) ((e)->src->succ->succ_next \
+ && (e)->dest->pred->pred_next)
struct edge_list * create_edge_list PARAMS ((void));
void free_edge_list PARAMS ((struct edge_list *));
*** cfg.c.old Tue Sep 11 15:36:34 2001
--- cfg.c Tue Sep 11 16:10:25 2001
*************** force_nonfallthru_and_redirect (e, targe
*** 1278,1284 ****
}
else
jump_block = e->src;
! e->flags &= ~(EDGE_FALLTHRU | EDGE_CRITICAL);
label = block_label (target);
jump_block->end = emit_jump_insn_after (gen_jump (label), jump_block->end);
JUMP_LABEL (jump_block->end) = label;
--- 1278,1284 ----
}
else
jump_block = e->src;
! e->flags &= ~EDGE_FALLTHRU;
label = block_label (target);
jump_block->end = emit_jump_insn_after (gen_jump (label), jump_block->end);
JUMP_LABEL (jump_block->end) = label;
*************** split_edge (edge_in)
*** 1530,1536 ****
COPY_REG_SET (bb->global_live_at_end, edge_in->dest->global_live_at_start);
}
- edge_in->flags &= ~EDGE_CRITICAL;
edge_out = make_single_succ_edge (bb, edge_in->dest, EDGE_FALLTHRU);
/* For non-fallthry edges, we must adjust the predecessor's
--- 1530,1535 ----
*************** insert_insn_on_edge (pattern, e)
*** 1557,1564 ****
{
/* We cannot insert instructions on an abnormal critical edge.
It will be easier to find the culprit if we die now. */
! if ((e->flags & (EDGE_ABNORMAL|EDGE_CRITICAL))
! == (EDGE_ABNORMAL|EDGE_CRITICAL))
abort ();
if (e->insns == NULL_RTX)
--- 1556,1562 ----
{
/* We cannot insert instructions on an abnormal critical edge.
It will be easier to find the culprit if we die now. */
! if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
abort ();
if (e->insns == NULL_RTX)
*************** dump_edge_info (file, e, do_succ)
*** 1835,1841 ****
if (e->flags)
{
static const char * const bitnames[] = {
! "fallthru", "crit", "ab", "abcall", "eh", "fake", "dfs_back"
};
int comma = 0;
int i, flags = e->flags;
--- 1833,1839 ----
if (e->flags)
{
static const char * const bitnames[] = {
! "fallthru", "ab", "abcall", "eh", "fake", "dfs_back"
};
int comma = 0;
int i, flags = e->flags;
*** cfganal.c.old Tue Sep 11 15:36:14 2001
--- cfganal.c Tue Sep 11 15:36:30 2001
*************** can_fallthru (src, target)
*** 89,138 ****
return next_active_insn (insn) == insn2;
}
- /* Identify critical edges and set the bits appropriately. */
-
- void
- mark_critical_edges ()
- {
- int i, n = n_basic_blocks;
- basic_block bb;
-
- /* We begin with the entry block. This is not terribly important now,
- but could be if a front end (Fortran) implemented alternate entry
- points. */
- bb = ENTRY_BLOCK_PTR;
- i = -1;
-
- while (1)
- {
- edge e;
-
- /* (1) Critical edges must have a source with multiple successors. */
- if (bb->succ && bb->succ->succ_next)
- {
- for (e = bb->succ; e; e = e->succ_next)
- {
- /* (2) Critical edges must have a destination with multiple
- predecessors. Note that we know there is at least one
- predecessor -- the edge we followed to get here. */
- if (e->dest->pred->pred_next)
- e->flags |= EDGE_CRITICAL;
- else
- e->flags &= ~EDGE_CRITICAL;
- }
- }
- else
- {
- for (e = bb->succ; e; e = e->succ_next)
- e->flags &= ~EDGE_CRITICAL;
- }
-
- if (++i >= n)
- break;
- bb = BASIC_BLOCK (i);
- }
- }
-
/* Mark the back edges in DFS traversal.
Return non-zero if a loop (natural or otherwise) is present.
Inspired by Depth_First_Search_PP described in:
--- 89,94 ----
*** cfgbuild.c.old Tue Sep 11 15:39:53 2001
--- cfgbuild.c Tue Sep 11 15:40:01 2001
*************** find_basic_blocks (f, nregs, file)
*** 659,666 ****
here and cleanup_cfg, e.g. thread_prologue_and_epilogue_insns. */
tidy_fallthru_edges ();
- mark_critical_edges ();
-
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
--- 659,664 ----
*** cfgcleanup.c.old Tue Sep 11 15:40:09 2001
--- cfgcleanup.c Tue Sep 11 15:40:17 2001
*************** cleanup_cfg (mode)
*** 1208,1216 ****
if (try_optimize_cfg (mode))
delete_unreachable_blocks (), changed = true;
- if (changed)
- mark_critical_edges ();
-
/* Kill the data we won't maintain. */
free_EXPR_LIST_list (&label_value_list);
free_EXPR_LIST_list (&tail_recursion_label_list);
--- 1208,1213 ----
*** profile.c.old Tue Sep 11 15:37:25 2001
--- profile.c Tue Sep 11 15:37:48 2001
*************** instrument_edges (el)
*** 152,158 ****
if (rtl_dump_file)
fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
e->src->index, e->dest->index,
! e->flags & EDGE_CRITICAL ? " (and split)" : "");
need_func_profiler = 1;
insert_insn_on_edge (
gen_edge_profiler (total_num_edges_instrumented
--- 152,158 ----
if (rtl_dump_file)
fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
e->src->index, e->dest->index,
! EDGE_CRITICAL_P (e) ? " (and split)" : "");
need_func_profiler = 1;
insert_insn_on_edge (
gen_edge_profiler (total_num_edges_instrumented
*************** find_spanning_tree (el)
*** 884,890 ****
for (i = 0; i < num_edges; i++)
{
edge e = INDEX_EDGE (el, i);
! if ((e->flags & EDGE_CRITICAL)
&& !EDGE_INFO (e)->ignore
&& (find_group (e->src) != find_group (e->dest)))
{
--- 884,890 ----
for (i = 0; i < num_edges; i++)
{
edge e = INDEX_EDGE (el, i);
! if ((EDGE_CRITICAL_P (e))
&& !EDGE_INFO (e)->ignore
&& (find_group (e->src) != find_group (e->dest)))
{
*** reg-stack.c.old Tue Sep 11 15:37:57 2001
--- reg-stack.c Tue Sep 11 15:39:00 2001
*************** convert_regs_1 (file, block)
*** 2660,2668 ****
beste = e;
else if (beste->count > e->count)
;
! else if ((e->flags & EDGE_CRITICAL) != (beste->flags & EDGE_CRITICAL))
{
! if (e->flags & EDGE_CRITICAL)
beste = e;
}
else if (e->src->index < beste->src->index)
--- 2660,2669 ----
beste = e;
else if (beste->count > e->count)
;
! else if ((EDGE_CRITICAL_P (e) != 0)
! != (EDGE_CRITICAL_P (beste) != 0))
{
! if (EDGE_CRITICAL_P (e))
beste = e;
}
else if (e->src->index < beste->src->index)
*** ssa.c.old Tue Sep 11 15:39:11 2001
--- ssa.c Tue Sep 11 15:39:35 2001
*************** make_regs_equivalent_over_bad_edges (bb,
*** 1498,1505 ****
/* Scan incoming abnormal critical edges. */
for (e = b->pred; e; e = e->pred_next)
! if ((e->flags & (EDGE_ABNORMAL | EDGE_CRITICAL))
! == (EDGE_ABNORMAL | EDGE_CRITICAL))
{
rtx *alt = phi_alternative (set, e->src->index);
int alt_regno;
--- 1498,1504 ----
/* Scan incoming abnormal critical edges. */
for (e = b->pred; e; e = e->pred_next)
! if ((e->flags & EDGE_ABNORMAL) && EDGE_CRITICAL_P (e))
{
rtx *alt = phi_alternative (set, e->src->index);
int alt_regno;
More information about the Gcc-patches
mailing list