summaryrefslogtreecommitdiff
path: root/gcc/cfgbuild.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-10-20 10:04:00 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-10-20 10:04:00 +0000
commit9645fa4fafeee991361401a7ecfbbaa9b3bb2c5d (patch)
tree8b850e82487dad7507a2357d498b653cbeb1d71e /gcc/cfgbuild.c
parent1e0ef2fd0dfa941141148032c7f056f087c046f3 (diff)
downloadgcc-9645fa4fafeee991361401a7ecfbbaa9b3bb2c5d.tar.gz
* basic-block.h (find_sub_basic_blocks): Use sbitmap parameter.
* cfgbuild.c (find_bb_boundaries, compute_outgoing_frequencies): Break out from ... (find_sub_basic_blocks): ... here; (find_many_sub_basic_blocks): New. * recog.c (split_all_insns): Update find_sub_basic_blocks call. * i386.h (ASM_PREFERRED_EH_DATA_FORMAT): Define sdata4. * i386.c (ix86_va_arg): Kill indirect_p handling; fix aliasing issues.: * i386.c (split_di, split_ti): Revamp to use simplify_subreg. * timevar.def (TV_LIFE, TV_LIFE_UPDATE, TV_MODE_SWITCH): new. * flow.c (update_life_info): Measure time. * c-decl.c: Include timevar.h (c_expand_body): Measure time. * toplev.c (rest_of_compilation): Measure time of mode switching separately. * Makefile.in (c-decl.o, cfgcleanup.o): Add dependancy. * toplev.c (flag_asynchronous_unwind_tables): New global variable. (lang_independent_options): Add asynchronous-unwind-tables (toplev_main): flag_asynchronous_unwind_tables implies flag_unwind_tables. * flags.h (flag_asynchronous_unwind_tables): Declare. * dwarf2out.c (dwarf2out_stack_adjust): Take into account flag_asynchronous_unwind_tables. (output_call_frame_info): Likewise. * invoke.texi (-fasynchronous-unwind-tables): Document. * i386.c (optimization_options): Enable flag_asynchronous_unwind_tables. * i386.c (ix86_expand_setcc): Always expect target to be QImode. * i386.md (s* expanders): Destination is QImode. * toplev.c (rest_of_compilation): Do not call clear_log_links. * rtl.h (clear_log_links): Kill. * flow.c (clear_log_links): Make static; accept blocks parameter; do no clear life info. (update_life_info): Call clear_log_links. * cfganal.c (forwarder_block_p): Avoid active_insn_p calls. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46374 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgbuild.c')
-rw-r--r--gcc/cfgbuild.c170
1 files changed, 135 insertions, 35 deletions
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index b27c23966ed..ef86939d4ad 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -55,6 +55,8 @@ static void make_edges PARAMS ((rtx, int, int, int));
static void make_label_edge PARAMS ((sbitmap *, basic_block,
rtx, int));
static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
+static void find_bb_boundaries PARAMS ((basic_block));
+static void compute_outgoing_frequencies PARAMS ((basic_block));
/* Count the basic blocks of the function. */
@@ -246,7 +248,8 @@ make_edges (label_value_list, min, max, update_p)
}
/* By nature of the way these get numbered, block 0 is always the entry. */
- cached_make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
+ if (min == 0)
+ cached_make_edge (edge_cache, ENTRY_BLOCK_PTR, BASIC_BLOCK (0), EDGE_FALLTHRU);
for (i = min; i <= max; ++i)
{
@@ -663,18 +666,27 @@ find_basic_blocks (f, nregs, file)
timevar_pop (TV_CFG);
}
-/* Assume that someone emitted code with control flow instructions to the
- basic block. Update the data structure. */
-void
-find_sub_basic_blocks (bb)
+/* State of basic block as seen by find_sub_basic_blocks. */
+enum state
+ {
+ BLOCK_NEW = 0,
+ BLOCK_ORIGINAL,
+ BLOCK_TO_SPLIT
+ };
+#define STATE(bb) (enum state)(size_t)(bb)->aux
+#define SET_STATE(bb, state) (bb)->aux = (void *)(state)
+
+/* Scan basic block BB for possible BB boundaries inside the block
+ and create new basic blocks in the progress. */
+
+static void
+find_bb_boundaries (bb)
basic_block bb;
{
rtx insn = bb->head;
rtx end = bb->end;
rtx flow_transfer_insn = NULL_RTX;
edge fallthru = NULL;
- basic_block first_bb = bb;
- int i;
if (insn == bb->end)
return;
@@ -694,7 +706,7 @@ find_sub_basic_blocks (bb)
abort ();
break;
- /* On code label, split current basic block. */
+ /* On code label, split current basic block. */
case CODE_LABEL:
fallthru = split_block (bb, PREV_INSN (insn));
if (flow_transfer_insn)
@@ -725,7 +737,7 @@ find_sub_basic_blocks (bb)
{
if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
- abort();
+ abort ();
flow_transfer_insn = insn;
}
else if (code == CALL_INSN)
@@ -764,18 +776,87 @@ find_sub_basic_blocks (bb)
followed by cleanup at fallthru edge, so the outgoing edges may
be dead. */
purge_dead_edges (bb);
+}
+
+/* Assume that frequency of basic block B is known. Compute frequencies
+ and probabilities of outgoing edges. */
+
+static void
+compute_outgoing_frequencies (b)
+ basic_block b;
+{
+ edge e, f;
+ if (b->succ && b->succ->succ_next && !b->succ->succ_next->succ_next)
+ {
+ rtx note = find_reg_note (b->end, REG_BR_PROB, NULL);
+ int probability;
+
+ if (!note)
+ return;
+ probability = INTVAL (XEXP (find_reg_note (b->end,
+ REG_BR_PROB, NULL), 0));
+ e = BRANCH_EDGE (b);
+ e->probability = probability;
+ e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
+ / REG_BR_PROB_BASE);
+ f = FALLTHRU_EDGE (b);
+ f->probability = REG_BR_PROB_BASE - probability;
+ f->count = b->count - e->count;
+ }
+ if (b->succ && !b->succ->succ_next)
+ {
+ e = b->succ;
+ e->probability = REG_BR_PROB_BASE;
+ e->count = b->count;
+ }
+}
+
+/* Assume that someone emitted code with control flow instructions to the
+ basic block. Update the data structure. */
+
+void
+find_many_sub_basic_blocks (blocks)
+ sbitmap blocks;
+{
+ int i;
+ int min, max;
+
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ SET_STATE (BASIC_BLOCK (i),
+ TEST_BIT (blocks, i)
+ ? BLOCK_TO_SPLIT : BLOCK_ORIGINAL);
+ }
+
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ if (STATE (bb) == BLOCK_TO_SPLIT)
+ find_bb_boundaries (bb);
+ }
+
+ for (i = 0; i < n_basic_blocks; i++)
+ if (STATE (BASIC_BLOCK (i)) != BLOCK_ORIGINAL)
+ break;
+ min = max = i;
+ for (; i < n_basic_blocks; i++)
+ if (STATE (BASIC_BLOCK (i)) != BLOCK_ORIGINAL)
+ max = i;
/* Now re-scan and wire in all edges. This expect simple (conditional)
jumps at the end of each new basic blocks. */
- make_edges (NULL, first_bb->index, bb->index, 1);
+ make_edges (NULL, min, max, 1);
/* Update branch probabilities. Expect only (un)conditional jumps
to be created with only the forward edges. */
- for (i = first_bb->index; i <= bb->index; i++)
+ for (i = min; i <= max; i++)
{
- edge e,f;
+ edge e;
basic_block b = BASIC_BLOCK (i);
- if (b != first_bb)
+
+ if (STATE (b) == BLOCK_ORIGINAL)
+ continue;
+ if (STATE (b) == BLOCK_NEW)
{
b->count = 0;
b->frequency = 0;
@@ -785,29 +866,48 @@ find_sub_basic_blocks (bb)
b->frequency += EDGE_FREQUENCY (e);
}
}
- if (b->succ && b->succ->succ_next && !b->succ->succ_next->succ_next)
- {
- rtx note = find_reg_note (b->end, REG_BR_PROB, NULL);
- int probability;
-
- if (!note)
- continue;
- probability = INTVAL (XEXP (find_reg_note (b->end,
- REG_BR_PROB,
- NULL), 0));
- e = BRANCH_EDGE (b);
- e->probability = probability;
- e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
- / REG_BR_PROB_BASE);
- f = FALLTHRU_EDGE (b);
- f->probability = REG_BR_PROB_BASE - probability;
- f->count = b->count - e->count;
- }
- if (b->succ && !b->succ->succ_next)
+ compute_outgoing_frequencies (b);
+ }
+ for (i = 0; i < n_basic_blocks; i++)
+ SET_STATE (BASIC_BLOCK (i), 0);
+}
+
+/* Like above but for single basic block only. */
+
+void
+find_sub_basic_blocks (bb)
+ basic_block bb;
+{
+ int i;
+ int min, max;
+ basic_block next = (bb->index == n_basic_blocks - 1
+ ? NULL : BASIC_BLOCK (bb->index + 1));
+
+ min = bb->index;
+ find_bb_boundaries (bb);
+ max = (next ? next->index : n_basic_blocks) - 1;
+
+ /* Now re-scan and wire in all edges. This expect simple (conditional)
+ jumps at the end of each new basic blocks. */
+ make_edges (NULL, min, max, 1);
+
+ /* Update branch probabilities. Expect only (un)conditional jumps
+ to be created with only the forward edges. */
+ for (i = min; i <= max; i++)
+ {
+ edge e;
+ basic_block b = BASIC_BLOCK (i);
+
+ if (i != min)
{
- e = b->succ;
- e->probability = REG_BR_PROB_BASE;
- e->count = b->count;
+ b->count = 0;
+ b->frequency = 0;
+ for (e = b->pred; e; e=e->pred_next)
+ {
+ b->count += e->count;
+ b->frequency += EDGE_FREQUENCY (e);
+ }
}
+ compute_outgoing_frequencies (b);
}
}