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
This commit is contained in:
Steven Bosscher 2007-03-10 23:33:40 +00:00
parent b2c50382fb
commit 7984c78796
4 changed files with 91 additions and 5 deletions

View File

@ -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

View File

@ -1149,8 +1149,6 @@ cfg_layout_finalize (void)
bb->il.rtl->visited = 0;
}
break_superblocks ();
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif

View File

@ -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;
}

View File

@ -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);