From: Steven Bosscher Date: Sat, 10 Mar 2007 23:33:40 +0000 (+0000) Subject: lower-subreg.c: Include except.h. X-Git-Tag: releases/gcc-4.3.0~6312 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7984c78796a81700b46059b5432fe4671e2d0917;p=thirdparty%2Fgcc.git lower-subreg.c: Include except.h. * lower-subreg.c: Include except.h. (decompose_multiword_subregs): Verify that the only control flow insns we can split are loads to multi-words pseudos. Handle breaking such blocks after splitting, instead of calling find_many_sub_basic_blocks. * loop-unroll.c (split_edge_and_insert): Don't set BB_SUPERBLOCK on the new basic block. Add a lengthy comment explaining why we thought this was necessary. * cfglayout.c (cfg_layout_finalize): Don't break superblocks. From-SVN: r122807 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fbe584fb22ed..d6e748d205e9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2007-03-11 Steven Bosscher + + * lower-subreg.c: Include except.h. + (decompose_multiword_subregs): Verify that the only control flow + insns we can split are loads to multi-words pseudos. + Handle breaking such blocks after splitting, instead of calling + find_many_sub_basic_blocks. + + * loop-unroll.c (split_edge_and_insert): Don't set BB_SUPERBLOCK + on the new basic block. Add a lengthy comment explaining why we + thought this was necessary. + * cfglayout.c (cfg_layout_finalize): Don't break superblocks. + 2007-03-10 Mark Mitchell PR c++/30924 diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index eacfd996224a..bbdd7a25b414 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -1149,8 +1149,6 @@ cfg_layout_finalize (void) bb->il.rtl->visited = 0; } - break_superblocks (); - #ifdef ENABLE_CHECKING verify_flow_info (); #endif diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c index 8fb69b85ce7c..0ef434ce8bfe 100644 --- a/gcc/loop-unroll.c +++ b/gcc/loop-unroll.c @@ -879,7 +879,37 @@ split_edge_and_insert (edge e, rtx insns) return NULL; bb = split_edge (e); emit_insn_after (insns, BB_END (bb)); - bb->flags |= BB_SUPERBLOCK; + + /* ??? We used to assume that INSNS can contain control flow insns, and + that we had to try to find sub basic blocks in BB to maintain a valid + CFG. For this purpose we used to set the BB_SUPERBLOCK flag on BB + and call break_superblocks when going out of cfglayout mode. But it + turns out that this never happens; and that if it does ever happen, + the verify_flow_info call in loop_optimizer_finalize would fail. + + There are two reasons why we expected we could have control flow insns + in INSNS. The first is when a comparison has to be done in parts, and + the second is when the number of iterations is computed for loops with + the number of iterations known at runtime. In both cases, test cases + to get control flow in INSNS appear to be impossible to construct: + + * If do_compare_rtx_and_jump needs several branches to do comparison + in a mode that needs comparison by parts, we cannot analyze the + number of iterations of the loop, and we never get to unrolling it. + + * The code in expand_divmod that was suspected to cause creation of + branching code seems to be only accessed for signed division. The + divisions used by # of iterations analysis are always unsigned. + Problems might arise on architectures that emits branching code + for some operations that may appear in the unroller (especially + for division), but we have no such architectures. + + Considering all this, it was decided that we should for now assume + that INSNS can in theory contain control flow insns, but in practice + it never does. So we don't handle the theoretical case, and should + a real failure ever show up, we have a pretty good clue for how to + fix it. */ + return bb; } diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 22a40e629b1b..e911205f460f 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -35,6 +35,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "recog.h" #include "bitmap.h" #include "expr.h" +#include "except.h" #include "regs.h" #include "tree-pass.h" @@ -1051,6 +1052,8 @@ decompose_multiword_subregs (bool update_life) int max_regno = max_reg_num (); sbitmap life_blocks; sbitmap sub_blocks; + unsigned int i; + sbitmap_iterator sbi; bitmap_iterator iter; unsigned int regno; @@ -1105,6 +1108,21 @@ decompose_multiword_subregs (bool update_life) rtx orig_insn = insn; bool cfi = control_flow_insn_p (insn); + /* We can end up splitting loads to multi-word pseudos + into separate loads to machine word size pseudos. + When this happens, we first had one load that can + throw, and after resolve_simple_move we'll have a + bunch of loads (at least two). All those loads may + trap if we can have non-call exceptions, so they + all will end the current basic block. We split the + block after the outer loop over all insns, but we + make sure here that we will be able to split the + basic block and still produce the correct control + flow graph for it. */ + gcc_assert (!cfi + || (flag_non_call_exceptions + && can_throw_internal (insn))); + insn = resolve_simple_move (set, insn); if (insn != orig_insn) { @@ -1157,8 +1175,35 @@ decompose_multiword_subregs (bool update_life) update_life_info (life_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES); - if (sbitmap_first_set_bit (sub_blocks) >= 0) - find_many_sub_basic_blocks (sub_blocks); + /* If we had insns to split that caused control flow insns in the middle + of a basic block, split those blocks now. Note that we only handle + the case where splitting a load has caused multiple possibly trapping + loads to appear. */ + EXECUTE_IF_SET_IN_SBITMAP (sub_blocks, 0, i, sbi) + { + rtx insn, end; + edge fallthru; + + bb = BASIC_BLOCK (i); + insn = BB_HEAD (bb); + end = BB_END (bb); + + while (insn != end) + { + if (control_flow_insn_p (insn)) + { + /* Split the block after insn. There will be a fallthru + edge, which is OK so we keep it. We have to create the + exception edges ourselves. */ + fallthru = split_block (bb, insn); + rtl_make_eh_edge (NULL, bb, BB_END (bb)); + bb = fallthru->dest; + insn = BB_HEAD (bb); + } + else + insn = NEXT_INSN (insn); + } + } sbitmap_free (life_blocks); sbitmap_free (sub_blocks);