lower-subreg.c (move_eh_region_note): New static function.
authorIan Lance Taylor <iant@google.com>
Fri, 16 Feb 2007 00:42:11 +0000 (00:42 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 16 Feb 2007 00:42:11 +0000 (00:42 +0000)
./: * lower-subreg.c (move_eh_region_note): New static function.
(resolve_simple_move): Call it.
(decompose_multiword_subregs): Track blocks for which we resolve a
simple move which is also a control flow insn.  Pass them to
find_many_sub_basic_blocks.
(pass_lower_subreg): Add TODO_verify_flow.
(pass_lower_subreg2): Likewise.
testsuite/:
* g++.dg/eh/subreg-1.C: New test.

From-SVN: r122025

gcc/ChangeLog
gcc/lower-subreg.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/eh/subreg-1.C [new file with mode: 0644]

index 22af3fd..f36c288 100644 (file)
@@ -1,3 +1,13 @@
+2007-02-15  Ian Lance Taylor  <iant@google.com>
+
+       * lower-subreg.c (move_eh_region_note): New static function.
+       (resolve_simple_move): Call it.
+       (decompose_multiword_subregs): Track blocks for which we resolve a
+       simple move which is also a control flow insn.  Pass them to
+       find_many_sub_basic_blocks.
+       (pass_lower_subreg): Add TODO_verify_flow.
+       (pass_lower_subreg2): Likewise.
+
 2007-02-15  Sandra Loosemore  <sandra@codesourcery.com>
            Brooks Moses  <brooks.moses@codesourcery.com>
            Lee Millward  <lee.millward@codesourcery.com>
index 908b10e..22a40e6 100644 (file)
@@ -521,6 +521,31 @@ resolve_subreg_use (rtx *px, void *data)
   return 0;
 }
 
+/* We are deleting INSN.  Move any EH_REGION notes to INSNS.  */
+
+static void
+move_eh_region_note (rtx insn, rtx insns)
+{
+  rtx note, p;
+
+  note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+  if (note == NULL_RTX)
+    return;
+
+  gcc_assert (CALL_P (insn)
+             || (flag_non_call_exceptions && may_trap_p (PATTERN (insn))));
+
+  for (p = insns; p != NULL_RTX; p = NEXT_INSN (p))
+    {
+      if (CALL_P (p)
+         || (flag_non_call_exceptions
+             && INSN_P (p)
+             && may_trap_p (PATTERN (p))))
+       REG_NOTES (p) = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0),
+                                          REG_NOTES (p));
+    }
+}
+
 /* If there is a REG_LIBCALL note on OLD_START, move it to NEW_START,
    and link the corresponding REG_RETVAL note to NEW_START.  */
 
@@ -837,6 +862,8 @@ resolve_simple_move (rtx set, rtx insn)
   insns = get_insns ();
   end_sequence ();
 
+  move_eh_region_note (insn, insns);
+
   emit_insn_before (insns, insn);
 
   move_libcall_note (insn, insns);
@@ -1022,15 +1049,18 @@ decompose_multiword_subregs (bool update_life)
     {
       int hold_no_new_pseudos = no_new_pseudos;
       int max_regno = max_reg_num ();
-      sbitmap blocks;
+      sbitmap life_blocks;
+      sbitmap sub_blocks;
       bitmap_iterator iter;
       unsigned int regno;
 
       propagate_pseudo_copies ();
 
       no_new_pseudos = 0;
-      blocks = sbitmap_alloc (last_basic_block);
-      sbitmap_zero (blocks);
+      life_blocks = sbitmap_alloc (last_basic_block);
+      sbitmap_zero (life_blocks);
+      sub_blocks = sbitmap_alloc (last_basic_block);
+      sbitmap_zero (sub_blocks);
 
       EXECUTE_IF_SET_IN_BITMAP (decomposable_context, 0, regno, iter)
        decompose_register (regno);
@@ -1073,6 +1103,7 @@ decompose_multiword_subregs (bool update_life)
                  if (set)
                    {
                      rtx orig_insn = insn;
+                     bool cfi = control_flow_insn_p (insn);
 
                      insn = resolve_simple_move (set, insn);
                      if (insn != orig_insn)
@@ -1081,6 +1112,9 @@ decompose_multiword_subregs (bool update_life)
 
                          recog_memoized (insn);
                          extract_insn (insn);
+
+                         if (cfi)
+                           SET_BIT (sub_blocks, bb->index);
                        }
                    }
 
@@ -1111,7 +1145,7 @@ decompose_multiword_subregs (bool update_life)
 
              if (changed)
                {
-                 SET_BIT (blocks, bb->index);
+                 SET_BIT (life_blocks, bb->index);
                  reg_scan_update (insn, next, max_regno);
                }
            }
@@ -1120,10 +1154,14 @@ decompose_multiword_subregs (bool update_life)
       no_new_pseudos = hold_no_new_pseudos;
 
       if (update_life)
-       update_life_info (blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
+       update_life_info (life_blocks, UPDATE_LIFE_GLOBAL_RM_NOTES,
                          PROP_DEATH_NOTES);
 
-      sbitmap_free (blocks);
+      if (sbitmap_first_set_bit (sub_blocks) >= 0)
+       find_many_sub_basic_blocks (sub_blocks);
+
+      sbitmap_free (life_blocks);
+      sbitmap_free (sub_blocks);
     }
 
   {
@@ -1181,7 +1219,8 @@ struct tree_opt_pass pass_lower_subreg =
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
   TODO_dump_func |
-  TODO_ggc_collect,                     /* todo_flags_finish */
+  TODO_ggc_collect |
+  TODO_verify_flow,                     /* todo_flags_finish */
   'u'                                   /* letter */
 };
 
@@ -1199,6 +1238,7 @@ struct tree_opt_pass pass_lower_subreg2 =
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
   TODO_dump_func |
-  TODO_ggc_collect,                     /* todo_flags_finish */
+  TODO_ggc_collect |
+  TODO_verify_flow,                     /* todo_flags_finish */
   'U'                                   /* letter */
 };
index 67076ea..191cb00 100644 (file)
@@ -1,3 +1,7 @@
+2007-02-15  Ian Lance Taylor  <iant@google.com>
+
+       * g++.dg/eh/subreg-1.C: New test.
+
 2007-02-15  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>
 
        PR c/26494
diff --git a/gcc/testsuite/g++.dg/eh/subreg-1.C b/gcc/testsuite/g++.dg/eh/subreg-1.C
new file mode 100644 (file)
index 0000000..1ac976d
--- /dev/null
@@ -0,0 +1,41 @@
+/* The lower-subreg pass would ICE on this test case with
+   TODO_verify_flow on 32-bit PowerPC.  It didn't handle REG_EH_REGION
+   notes correctly.  This is reduced from interpret.cc in libjava.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fnon-call-exceptions" } */
+
+union _Jv_word
+{
+  double *o;
+  int i;
+  int ia[1];
+};
+union _Jv_word2
+{
+  int ia[2];
+  double d;
+};
+
+class _Jv_InterpMethod
+{
+  static void run_debug (_Jv_word *);
+};
+
+void
+_Jv_InterpMethod::run_debug (_Jv_word *sp)
+{
+  try
+  {
+    {
+      int index = ((int) (--sp)->i);
+      double *arr = (double *) ((--sp)->o);
+      _Jv_word2 w2;
+      w2.d = arr[index];
+      (sp++)->ia[0] = w2.ia[0];
+    }
+  }
+  catch (int * ex)
+  {
+  }
+}