diff options
author | J"orn Rennecke <joern.rennecke@superh.com> | 2002-05-30 18:58:31 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2002-05-30 19:58:31 +0100 |
commit | 81b40b72d1e15987d2a04ecead8e14de4694a5dd (patch) | |
tree | ed3abb74f12d0028246c8852eee1f0196a4f7ce8 /gcc/lcm.c | |
parent | b1c12c4ba10fc0ee9c8eea601790e2e33290aa44 (diff) | |
download | gcc-81b40b72d1e15987d2a04ecead8e14de4694a5dd.zip gcc-81b40b72d1e15987d2a04ecead8e14de4694a5dd.tar.gz gcc-81b40b72d1e15987d2a04ecead8e14de4694a5dd.tar.bz2 |
lcm.c (output.h): #include.
* lcm.c (output.h): #include.
(compute_earliest): Remove hack to treat renumbered EXIT_BLOCK
as an ordinary block.
(optimize_mode_switching): Don't pretend that the exit block is
an ordinary block, or handle sucessors of entry block specially.
Instead, split edges from entry block and to exit block, and
put a computing definition on the thus gained post-entry-block,
and a need on the pre-exit-block.
From-SVN: r54064
Diffstat (limited to 'gcc/lcm.c')
-rw-r--r-- | gcc/lcm.c | 159 |
1 files changed, 52 insertions, 107 deletions
@@ -59,6 +59,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "insn-config.h" #include "recog.h" #include "basic-block.h" +#include "output.h" #include "tm_p.h" /* We want target macros for the mode switching code to be able to refer @@ -207,11 +208,7 @@ compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest) sbitmap_copy (earliest[x], antin[succ->index]); else { - /* We refer to the EXIT_BLOCK index, instead of testing for - EXIT_BLOCK_PTR, so that EXIT_BLOCK_PTR's index can be - changed so as to pretend it's a regular block, so that - its antin can be taken into account. */ - if (succ->index == EXIT_BLOCK) + if (succ == EXIT_BLOCK_PTR) sbitmap_zero (earliest[x]); else { @@ -1027,43 +1024,54 @@ optimize_mode_switching (file) int n_entities; int max_num_modes = 0; bool emited = false; + basic_block post_entry, pre_exit ATTRIBUTE_UNUSED; clear_bb_flags (); -#ifdef NORMAL_MODE - /* Increment last_basic_block before allocating bb_info. */ - last_basic_block++; -#endif for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--) if (OPTIMIZE_MODE_SWITCHING (e)) { - /* Create the list of segments within each basic block. */ + int entry_exit_extra = 0; + + /* Create the list of segments within each basic block. + If NORMAL_MODE is defined, allow for two extra + blocks split from the entry and exit block. */ +#ifdef NORMAL_MODE + entry_exit_extra = 2; +#endif bb_info[n_entities] - = (struct bb_info *) xcalloc (last_basic_block, sizeof **bb_info); + = (struct bb_info *) xcalloc (last_basic_block + entry_exit_extra, + sizeof **bb_info); entity_map[n_entities++] = e; if (num_modes[e] > max_num_modes) max_num_modes = num_modes[e]; } -#ifdef NORMAL_MODE - /* Decrement it back in case we return below. */ - last_basic_block--; -#endif - if (! n_entities) return 0; #ifdef NORMAL_MODE - /* We're going to pretend the EXIT_BLOCK is a regular basic block, - so that switching back to normal mode when entering the - EXIT_BLOCK isn't optimized away. We do this by incrementing the - basic block count, growing the VARRAY of basic_block_info and - appending the EXIT_BLOCK_PTR to it. */ - last_basic_block++; - if (VARRAY_SIZE (basic_block_info) < last_basic_block) - VARRAY_GROW (basic_block_info, last_basic_block); - BASIC_BLOCK (last_basic_block - 1) = EXIT_BLOCK_PTR; - EXIT_BLOCK_PTR->index = last_basic_block - 1; + { + /* Split the edge from the entry block and the fallthrough edge to the + exit block, so that we can note that there NORMAL_MODE is supplied / + required. */ + edge eg; + post_entry = split_edge (ENTRY_BLOCK_PTR->succ); + /* The only non-call predecessor at this stage is a block with a + fallthrough edge; there can be at most one, but there could be + none at all, e.g. when exit is called. */ + for (pre_exit = 0, eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next) + if (eg->flags & EDGE_FALLTHRU) + { + regset live_at_end = eg->src->global_live_at_end; + + if (pre_exit) + abort (); + pre_exit = split_edge (eg); + COPY_REG_SET (pre_exit->global_live_at_start, live_at_end); + COPY_REG_SET (pre_exit->global_live_at_end, live_at_end); + } + } #endif /* Create the bitmap vectors. */ @@ -1124,7 +1132,7 @@ optimize_mode_switching (file) /* Check for blocks without ANY mode requirements. */ if (last_mode == no_mode) { - ptr = new_seginfo (no_mode, insn, bb->index, live_now); + ptr = new_seginfo (no_mode, bb->end, bb->index, live_now); add_seginfo (info + bb->index, ptr); } } @@ -1134,36 +1142,21 @@ optimize_mode_switching (file) if (mode != no_mode) { - edge eg; + bb = post_entry; - for (eg = ENTRY_BLOCK_PTR->succ; eg; eg = eg->succ_next) - { - bb = eg->dest; - - /* By always making this nontransparent, we save - an extra check in make_preds_opaque. We also - need this to avoid confusing pre_edge_lcm when - antic is cleared but transp and comp are set. */ - RESET_BIT (transp[bb->index], j); - - /* If the block already has MODE, pretend it - has none (because we don't need to set it), - but retain whatever mode it computes. */ - if (info[bb->index].seginfo->mode == mode) - info[bb->index].seginfo->mode = no_mode; - - /* Insert a fake computing definition of MODE into entry - blocks which compute no mode. This represents the mode on - entry. */ - else if (info[bb->index].computing == no_mode) - { - info[bb->index].computing = mode; - info[bb->index].seginfo->mode = no_mode; - } - } + /* By always making this nontransparent, we save + an extra check in make_preds_opaque. We also + need this to avoid confusing pre_edge_lcm when + antic is cleared but transp and comp are set. */ + RESET_BIT (transp[bb->index], j); - bb = EXIT_BLOCK_PTR; - info[bb->index].seginfo->mode = mode; + /* Insert a fake computing definition of MODE into entry + blocks which compute no mode. This represents the mode on + entry. */ + info[bb->index].computing = mode; + + if (pre_exit) + info[pre_exit->index].seginfo->mode = mode; } } #endif /* NORMAL_MODE */ @@ -1288,63 +1281,11 @@ optimize_mode_switching (file) free_edge_list (edge_list); } -#ifdef NORMAL_MODE - /* Restore the special status of EXIT_BLOCK. */ - last_basic_block--; - VARRAY_POP (basic_block_info); - EXIT_BLOCK_PTR->index = EXIT_BLOCK; -#endif - /* Now output the remaining mode sets in all the segments. */ for (j = n_entities - 1; j >= 0; j--) { int no_mode = num_modes[entity_map[j]]; -#ifdef NORMAL_MODE - if (bb_info[j][last_basic_block].seginfo->mode != no_mode) - { - edge eg; - struct seginfo *ptr = bb_info[j][last_basic_block].seginfo; - - for (eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next) - { - rtx mode_set; - - if (bb_info[j][eg->src->index].computing == ptr->mode) - continue; - - start_sequence (); - EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live); - mode_set = gen_sequence (); - end_sequence (); - - /* Do not bother to insert empty sequence. */ - if (GET_CODE (mode_set) == SEQUENCE - && !XVECLEN (mode_set, 0)) - continue; - - /* If this is an abnormal edge, we'll insert at the end of the - previous block. */ - if (eg->flags & EDGE_ABNORMAL) - { - emited = true; - if (GET_CODE (eg->src->end) == JUMP_INSN) - emit_insn_before (mode_set, eg->src->end); - else if (GET_CODE (eg->src->end) == INSN) - emit_insn_after (mode_set, eg->src->end); - else - abort (); - } - else - { - need_commit = 1; - insert_insn_on_edge (mode_set, eg); - } - } - - } -#endif - FOR_EACH_BB_REVERSE (bb) { struct seginfo *ptr, *next; @@ -1393,8 +1334,12 @@ optimize_mode_switching (file) if (need_commit) commit_edge_insertions (); +#ifdef NORMAL_MODE + cleanup_cfg (CLEANUP_NO_INSN_DEL); +#else if (!need_commit && !emited) return 0; +#endif max_regno = max_reg_num (); allocate_reg_info (max_regno, FALSE, FALSE); |