mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-21 08:03:41 +08:00
flow.c (make_edge): Accept an optional 2D bitmap in which to cache edge existence.
* flow.c (make_edge): Accept an optional 2D bitmap in which to cache edge existence. Update all callers. (make_label_edge, make_eh_edge): Pass through the edge cache. (make_edges): Provide the cache. From-SVN: r29828
This commit is contained in:
parent
5da1ecf26e
commit
dbf08f94a7
@ -1,3 +1,10 @@
|
||||
Tue Oct 5 12:00:32 1999 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* flow.c (make_edge): Accept an optional 2D bitmap in which
|
||||
to cache edge existence. Update all callers.
|
||||
(make_label_edge, make_eh_edge): Pass through the edge cache.
|
||||
(make_edges): Provide the cache.
|
||||
|
||||
Tue Oct 5 12:16:49 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* mbchar.c (literal_codeset, local_mbtowc, local_mblen): Constify
|
||||
|
92
gcc/flow.c
92
gcc/flow.c
@ -280,10 +280,12 @@ static rtx find_basic_blocks_1 PROTO((rtx));
|
||||
static void create_basic_block PROTO((int, rtx, rtx, rtx));
|
||||
static void clear_edges PROTO((void));
|
||||
static void make_edges PROTO((rtx));
|
||||
static void make_edge PROTO((basic_block, basic_block, int));
|
||||
static void make_label_edge PROTO((basic_block, rtx, int));
|
||||
static void make_eh_edge PROTO((eh_nesting_info *, basic_block,
|
||||
static void make_edge PROTO((sbitmap *, basic_block,
|
||||
basic_block, int));
|
||||
static void make_label_edge PROTO((sbitmap *, basic_block,
|
||||
rtx, int));
|
||||
static void make_eh_edge PROTO((sbitmap *, eh_nesting_info *,
|
||||
basic_block, rtx, int));
|
||||
static void mark_critical_edges PROTO((void));
|
||||
static void move_stray_eh_region_notes PROTO((void));
|
||||
static void record_active_eh_regions PROTO((rtx));
|
||||
@ -879,12 +881,22 @@ make_edges (label_value_list)
|
||||
{
|
||||
int i;
|
||||
eh_nesting_info *eh_nest_info = init_eh_nesting_info ();
|
||||
sbitmap *edge_cache = NULL;
|
||||
|
||||
/* Assume no computed jump; revise as we create edges. */
|
||||
current_function_has_computed_jump = 0;
|
||||
|
||||
/* Heavy use of computed goto in machine-generated code can lead to
|
||||
nearly fully-connected CFGs. In that case we spend a significant
|
||||
amount of time searching the edge lists for duplicates. */
|
||||
if (forced_labels || label_value_list)
|
||||
{
|
||||
edge_cache = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
|
||||
sbitmap_vector_zero (edge_cache, n_basic_blocks);
|
||||
}
|
||||
|
||||
/* By nature of the way these get numbered, block 0 is always the entry. */
|
||||
make_edge (ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
|
||||
make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
|
||||
|
||||
for (i = 0; i < n_basic_blocks; ++i)
|
||||
{
|
||||
@ -920,7 +932,8 @@ make_edges (label_value_list)
|
||||
vec = XVEC (PATTERN (tmp), 1);
|
||||
|
||||
for (j = GET_NUM_ELEM (vec) - 1; j >= 0; --j)
|
||||
make_label_edge (bb, XEXP (RTVEC_ELT (vec, j), 0), 0);
|
||||
make_label_edge (edge_cache, bb,
|
||||
XEXP (RTVEC_ELT (vec, j), 0), 0);
|
||||
|
||||
/* Some targets (eg, ARM) emit a conditional jump that also
|
||||
contains the out-of-range target. Scan for these and
|
||||
@ -929,7 +942,8 @@ make_edges (label_value_list)
|
||||
&& SET_DEST (tmp) == pc_rtx
|
||||
&& GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
|
||||
&& GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
|
||||
make_label_edge (bb, XEXP (XEXP (SET_SRC (tmp), 2), 0), 0);
|
||||
make_label_edge (edge_cache, bb,
|
||||
XEXP (XEXP (SET_SRC (tmp), 2), 0), 0);
|
||||
|
||||
#ifdef CASE_DROPS_THROUGH
|
||||
/* Silly VAXen. The ADDR_VEC is going to be in the way of
|
||||
@ -945,22 +959,22 @@ make_edges (label_value_list)
|
||||
current_function_has_computed_jump = 1;
|
||||
|
||||
for (x = label_value_list; x; x = XEXP (x, 1))
|
||||
make_label_edge (bb, XEXP (x, 0), EDGE_ABNORMAL);
|
||||
make_label_edge (edge_cache, bb, XEXP (x, 0), EDGE_ABNORMAL);
|
||||
|
||||
for (x = forced_labels; x; x = XEXP (x, 1))
|
||||
make_label_edge (bb, XEXP (x, 0), EDGE_ABNORMAL);
|
||||
make_label_edge (edge_cache, bb, XEXP (x, 0), EDGE_ABNORMAL);
|
||||
}
|
||||
|
||||
/* Returns create an exit out. */
|
||||
else if (returnjump_p (insn))
|
||||
make_edge (bb, EXIT_BLOCK_PTR, 0);
|
||||
make_edge (edge_cache, bb, EXIT_BLOCK_PTR, 0);
|
||||
|
||||
/* Otherwise, we have a plain conditional or unconditional jump. */
|
||||
else
|
||||
{
|
||||
if (! JUMP_LABEL (insn))
|
||||
abort ();
|
||||
make_label_edge (bb, JUMP_LABEL (insn), 0);
|
||||
make_label_edge (edge_cache, bb, JUMP_LABEL (insn), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -975,7 +989,7 @@ make_edges (label_value_list)
|
||||
/* If there's an EH region active at the end of a block,
|
||||
add the appropriate edges. */
|
||||
if (bb->eh_end >= 0)
|
||||
make_eh_edge (eh_nest_info, bb, insn, bb->eh_end);
|
||||
make_eh_edge (edge_cache, eh_nest_info, bb, insn, bb->eh_end);
|
||||
|
||||
/* If we have asynchronous exceptions, do the same for *all*
|
||||
exception regions active in the block. */
|
||||
@ -983,7 +997,8 @@ make_edges (label_value_list)
|
||||
&& bb->eh_beg != bb->eh_end)
|
||||
{
|
||||
if (bb->eh_beg >= 0)
|
||||
make_eh_edge (eh_nest_info, bb, NULL_RTX, bb->eh_beg);
|
||||
make_eh_edge (edge_cache, eh_nest_info, bb,
|
||||
NULL_RTX, bb->eh_beg);
|
||||
|
||||
for (x = bb->head; x != bb->end; x = NEXT_INSN (x))
|
||||
if (GET_CODE (x) == NOTE
|
||||
@ -991,7 +1006,8 @@ make_edges (label_value_list)
|
||||
|| NOTE_LINE_NUMBER (x) == NOTE_INSN_EH_REGION_END))
|
||||
{
|
||||
int region = NOTE_EH_HANDLER (x);
|
||||
make_eh_edge (eh_nest_info, bb, NULL_RTX, region);
|
||||
make_eh_edge (edge_cache, eh_nest_info, bb,
|
||||
NULL_RTX, region);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1009,7 +1025,7 @@ make_edges (label_value_list)
|
||||
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
|
||||
if (!note || XINT (XEXP (note, 0), 0) >= 0)
|
||||
for (x = nonlocal_goto_handler_labels; x ; x = XEXP (x, 1))
|
||||
make_label_edge (bb, XEXP (x, 0),
|
||||
make_label_edge (edge_cache, bb, XEXP (x, 0),
|
||||
EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
|
||||
}
|
||||
}
|
||||
@ -1020,42 +1036,53 @@ make_edges (label_value_list)
|
||||
returns to one of the eh_stub labels within it. So we have to
|
||||
make additional edges in the flow graph. */
|
||||
if (i + 1 == n_basic_blocks && eh_return_stub_label != 0)
|
||||
make_label_edge (bb, eh_return_stub_label, EDGE_EH);
|
||||
make_label_edge (edge_cache, bb, eh_return_stub_label, EDGE_EH);
|
||||
|
||||
/* Find out if we can drop through to the next block. */
|
||||
insn = next_nonnote_insn (insn);
|
||||
if (!insn || (i + 1 == n_basic_blocks && force_fallthru))
|
||||
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
|
||||
make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
|
||||
else if (i + 1 < n_basic_blocks)
|
||||
{
|
||||
rtx tmp = BLOCK_HEAD (i + 1);
|
||||
if (GET_CODE (tmp) == NOTE)
|
||||
tmp = next_nonnote_insn (tmp);
|
||||
if (force_fallthru || insn == tmp)
|
||||
make_edge (bb, BASIC_BLOCK (i + 1), EDGE_FALLTHRU);
|
||||
make_edge (edge_cache, bb, BASIC_BLOCK (i + 1), EDGE_FALLTHRU);
|
||||
}
|
||||
}
|
||||
|
||||
free_eh_nesting_info (eh_nest_info);
|
||||
if (edge_cache)
|
||||
sbitmap_vector_free (edge_cache);
|
||||
}
|
||||
|
||||
/* Create an edge between two basic blocks. FLAGS are auxiliary information
|
||||
about the edge that is accumulated between calls. */
|
||||
|
||||
static void
|
||||
make_edge (src, dst, flags)
|
||||
make_edge (edge_cache, src, dst, flags)
|
||||
sbitmap *edge_cache;
|
||||
basic_block src, dst;
|
||||
int flags;
|
||||
{
|
||||
int use_edge_cache;
|
||||
edge e;
|
||||
|
||||
/* Make sure we don't add duplicate edges. */
|
||||
/* Don't bother with edge cache for ENTRY or EXIT; there aren't that
|
||||
many edges to them, and we didn't allocate memory for it. */
|
||||
use_edge_cache = (edge_cache
|
||||
&& src != ENTRY_BLOCK_PTR
|
||||
&& dst != EXIT_BLOCK_PTR);
|
||||
|
||||
for (e = src->succ; e ; e = e->succ_next)
|
||||
if (e->dest == dst)
|
||||
{
|
||||
e->flags |= flags;
|
||||
return;
|
||||
}
|
||||
/* Make sure we don't add duplicate edges. */
|
||||
if (! use_edge_cache || TEST_BIT (edge_cache[src->index], dst->index))
|
||||
for (e = src->succ; e ; e = e->succ_next)
|
||||
if (e->dest == dst)
|
||||
{
|
||||
e->flags |= flags;
|
||||
return;
|
||||
}
|
||||
|
||||
e = (edge) xcalloc (1, sizeof (*e));
|
||||
|
||||
@ -1067,12 +1094,16 @@ make_edge (src, dst, flags)
|
||||
|
||||
src->succ = e;
|
||||
dst->pred = e;
|
||||
|
||||
if (use_edge_cache)
|
||||
SET_BIT (edge_cache[src->index], dst->index);
|
||||
}
|
||||
|
||||
/* Create an edge from a basic block to a label. */
|
||||
|
||||
static void
|
||||
make_label_edge (src, label, flags)
|
||||
make_label_edge (edge_cache, src, label, flags)
|
||||
sbitmap *edge_cache;
|
||||
basic_block src;
|
||||
rtx label;
|
||||
int flags;
|
||||
@ -1088,13 +1119,14 @@ make_label_edge (src, label, flags)
|
||||
if (INSN_UID (label) == 0)
|
||||
return;
|
||||
|
||||
make_edge (src, BLOCK_FOR_INSN (label), flags);
|
||||
make_edge (edge_cache, src, BLOCK_FOR_INSN (label), flags);
|
||||
}
|
||||
|
||||
/* Create the edges generated by INSN in REGION. */
|
||||
|
||||
static void
|
||||
make_eh_edge (eh_nest_info, src, insn, region)
|
||||
make_eh_edge (edge_cache, eh_nest_info, src, insn, region)
|
||||
sbitmap *edge_cache;
|
||||
eh_nesting_info *eh_nest_info;
|
||||
basic_block src;
|
||||
rtx insn;
|
||||
@ -1107,7 +1139,7 @@ make_eh_edge (eh_nest_info, src, insn, region)
|
||||
num = reachable_handlers (region, eh_nest_info, insn, &handler_list);
|
||||
while (--num >= 0)
|
||||
{
|
||||
make_label_edge (src, handler_list[num]->handler_label,
|
||||
make_label_edge (edge_cache, src, handler_list[num]->handler_label,
|
||||
EDGE_ABNORMAL | EDGE_EH | is_call);
|
||||
}
|
||||
}
|
||||
@ -6989,5 +7021,5 @@ add_noreturn_fake_exit_edges ()
|
||||
|
||||
for (x = 0; x < n_basic_blocks; x++)
|
||||
if (BASIC_BLOCK (x)->succ == NULL)
|
||||
make_edge (BASIC_BLOCK (x), EXIT_BLOCK_PTR, EDGE_FAKE);
|
||||
make_edge (NULL, BASIC_BLOCK (x), EXIT_BLOCK_PTR, EDGE_FAKE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user