OSDN Git Service

* lower-subreg.c: Include except.h.
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Mar 2007 23:33:40 +0000 (23:33 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Mar 2007 23:33:40 +0000 (23:33 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122807 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfglayout.c
gcc/loop-unroll.c
gcc/lower-subreg.c

index fbe584f..d6e748d 100644 (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
 2007-03-10  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/30924
index eacfd99..bbdd7a2 100644 (file)
@@ -1149,8 +1149,6 @@ cfg_layout_finalize (void)
     bb->il.rtl->visited = 0;
   }
 
     bb->il.rtl->visited = 0;
   }
 
-  break_superblocks ();
-
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
 #endif
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
 #endif
index 8fb69b8..0ef434c 100644 (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));
     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;
 }
 
   return bb;
 }
 
index 22a40e6..e911205 100644 (file)
@@ -35,6 +35,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "recog.h"
 #include "bitmap.h"
 #include "expr.h"
 #include "recog.h"
 #include "bitmap.h"
 #include "expr.h"
+#include "except.h"
 #include "regs.h"
 #include "tree-pass.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;
       int max_regno = max_reg_num ();
       sbitmap life_blocks;
       sbitmap sub_blocks;
+      unsigned int i;
+      sbitmap_iterator sbi;
       bitmap_iterator iter;
       unsigned int regno;
 
       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);
 
                      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)
                        {
                      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);
 
        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);
 
       sbitmap_free (life_blocks);
       sbitmap_free (sub_blocks);