aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2007-03-10 23:33:40 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2007-03-10 23:33:40 +0000
commit7984c78796a81700b46059b5432fe4671e2d0917 (patch)
treebcc7bb1636a815612ac3bc51f2f41069c2317a4c
parentb2c50382fbaa050248b5d3952e2682f91fed4ede (diff)
downloadgcc-7984c78796a81700b46059b5432fe4671e2d0917.zip
gcc-7984c78796a81700b46059b5432fe4671e2d0917.tar.gz
gcc-7984c78796a81700b46059b5432fe4671e2d0917.tar.bz2
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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cfglayout.c2
-rw-r--r--gcc/loop-unroll.c32
-rw-r--r--gcc/lower-subreg.c49
4 files changed, 91 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fbe584f..d6e748d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2007-03-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * 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 <mark@codesourcery.com>
PR c++/30924
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index eacfd99..bbdd7a2 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 8fb69b8..0ef434c 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 22a40e6..e911205 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);