diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-10-20 10:04:00 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-10-20 10:04:00 +0000 |
commit | 9645fa4fafeee991361401a7ecfbbaa9b3bb2c5d (patch) | |
tree | 8b850e82487dad7507a2357d498b653cbeb1d71e /gcc/cfgbuild.c | |
parent | 1e0ef2fd0dfa941141148032c7f056f087c046f3 (diff) | |
download | gcc-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.c | 170 |
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); } } |