OSDN Git Service

* cfgrtl.c (rtl_delete_block): Fix comment.
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 Nov 2004 11:32:24 +0000 (11:32 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 24 Nov 2004 11:32:24 +0000 (11:32 +0000)
* emit-rtl.c (remove_unnecessary_notes): Die if we see BLOCK_BEG
or BLOCK_END insn notes.
* jump.c (squeeze_notes): Likewise.
* haifa-sched.c (reemit_notes): Don't "re-emit" EH_REGION_BEG and
EH_REGION_END notes, we never have them to begin with.
* sched-deps.c (sched_analyze_insn): When updating loop notes,
verify that we have indeed only recorded loop notes.
(sched_analyze): Die if we see EH_REGION_BEG or EH_REGION_END notes.
Only record loop notes.

* cfgexpand.c (tree_expand_cfg): Fix comment.

* passes.c (rest_of_compilation): Don't do a second call to
convert_from_eh_region_ranges from here, it's already called
from cfgexpand.c.
* except.c (resolve_fixup_regions): Remove.
(remove_fixup_regions): Remove.
(convert_from_eh_region_ranges_1): Remove.
(convert_from_eh_region_ranges): Remove the case where EH is
not already lowered at the tree level.  We always lower there.

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

gcc/ChangeLog
gcc/cfgexpand.c
gcc/cfgrtl.c
gcc/emit-rtl.c
gcc/except.c
gcc/haifa-sched.c
gcc/jump.c
gcc/passes.c
gcc/sched-deps.c

index 0e96f07..e9e7ebc 100644 (file)
@@ -1,7 +1,30 @@
+2004-11-24  Steven Bosscher  <stevenb@suse.de>
+
+       * cfgrtl.c (rtl_delete_block): Fix comment.
+       * emit-rtl.c (remove_unnecessary_notes): Die if we see BLOCK_BEG
+       or BLOCK_END insn notes.
+       * jump.c (squeeze_notes): Likewise.
+       * haifa-sched.c (reemit_notes): Don't "re-emit" EH_REGION_BEG and
+       EH_REGION_END notes, we never have them to begin with.
+       * sched-deps.c (sched_analyze_insn): When updating loop notes,
+       verify that we have indeed only recorded loop notes.
+       (sched_analyze): Die if we see EH_REGION_BEG or EH_REGION_END notes.
+       Only record loop notes.
+
+       * cfgexpand.c (tree_expand_cfg): Fix comment.
+
+       * passes.c (rest_of_compilation): Don't do a second call to
+       convert_from_eh_region_ranges from here, it's already called
+       from cfgexpand.c.
+       * except.c (resolve_fixup_regions): Remove.
+       (remove_fixup_regions): Remove.
+       (convert_from_eh_region_ranges_1): Remove.
+       (convert_from_eh_region_ranges): Remove the case where EH is
+       not already lowered at the tree level.  We always lower there.
+
 2004-11-24  Paolo Bonzini  <bonzini@gnu.org>
 
        PR c++/16882
 2004-11-24  Paolo Bonzini  <bonzini@gnu.org>
 
        PR c++/16882
-
        * tree.c (make_vector_type): Move qualifiers to the vector type,
        use the inner type's main variant and build a main variant for
        the vector type if necessary.
        * tree.c (make_vector_type): Move qualifiers to the vector type,
        use the inner type's main variant and build a main variant for
        the vector type if necessary.
index df0c695..f710aed 100644 (file)
@@ -1310,8 +1310,8 @@ tree_expand_cfg (void)
   /* We're done expanding trees to RTL.  */
   currently_expanding_to_rtl = 0;
 
   /* We're done expanding trees to RTL.  */
   currently_expanding_to_rtl = 0;
 
-  /* Convert from NOTE_INSN_EH_REGION style notes, and do other
-     sorts of eh initialization.  */
+  /* Convert tree EH labels to RTL EH labels, and clean out any unreachable
+     EH regions.  */
   convert_from_eh_region_ranges ();
 
   rebuild_jump_labels (get_insns ());
   convert_from_eh_region_ranges ();
 
   rebuild_jump_labels (get_insns ());
index 0bb181a..3c2dc96 100644 (file)
@@ -368,14 +368,9 @@ rtl_delete_block (basic_block b)
   rtx insn, end, tmp;
 
   /* If the head of this block is a CODE_LABEL, then it might be the
   rtx insn, end, tmp;
 
   /* If the head of this block is a CODE_LABEL, then it might be the
-     label for an exception handler which can't be reached.
-
-     We need to remove the label from the exception_handler_label list
-     and remove the associated NOTE_INSN_EH_REGION_BEG and
-     NOTE_INSN_EH_REGION_END notes.  */
-
+     label for an exception handler which can't be reached.  We need
+     to remove the label from the exception_handler_label list.  */
   insn = BB_HEAD (b);
   insn = BB_HEAD (b);
-
   if (LABEL_P (insn))
     maybe_remove_eh_handler (insn);
 
   if (LABEL_P (insn))
     maybe_remove_eh_handler (insn);
 
index 98dec5f..fba2412 100644 (file)
@@ -3728,7 +3728,6 @@ find_line_note (rtx insn)
 void
 remove_unnecessary_notes (void)
 {
 void
 remove_unnecessary_notes (void)
 {
-  rtx block_stack = NULL_RTX;
   rtx eh_stack = NULL_RTX;
   rtx insn;
   rtx next;
   rtx eh_stack = NULL_RTX;
   rtx insn;
   rtx next;
@@ -3767,66 +3766,17 @@ remove_unnecessary_notes (void)
          break;
 
        case NOTE_INSN_BLOCK_BEG:
          break;
 
        case NOTE_INSN_BLOCK_BEG:
-         /* By now, all notes indicating lexical blocks should have
-            NOTE_BLOCK filled in.  */
-         gcc_assert (NOTE_BLOCK (insn));
-         block_stack = alloc_INSN_LIST (insn, block_stack);
-         break;
-
        case NOTE_INSN_BLOCK_END:
        case NOTE_INSN_BLOCK_END:
-         /* Too many end notes.  */
-         gcc_assert (block_stack);
-         /* Mismatched nesting.  */
-         gcc_assert (NOTE_BLOCK (XEXP (block_stack, 0)) == NOTE_BLOCK (insn));
-         tmp = block_stack;
-         block_stack = XEXP (block_stack, 1);
-         free_INSN_LIST_node (tmp);
+          /* BLOCK_END and BLOCK_BEG notes only exist in the `final' pass.  */
+          gcc_unreachable ();
 
 
-         /* Scan back to see if there are any non-note instructions
-            between INSN and the beginning of this block.  If not,
-            then there is no PC range in the generated code that will
-            actually be in this block, so there's no point in
-            remembering the existence of the block.  */
-         for (tmp = PREV_INSN (insn); tmp; tmp = PREV_INSN (tmp))
-           {
-             /* This block contains a real instruction.  Note that we
-                don't include labels; if the only thing in the block
-                is a label, then there are still no PC values that
-                lie within the block.  */
-             if (INSN_P (tmp))
-               break;
-
-             /* We're only interested in NOTEs.  */
-             if (!NOTE_P (tmp))
-               continue;
-
-             if (NOTE_LINE_NUMBER (tmp) == NOTE_INSN_BLOCK_BEG)
-               {
-                 /* We just verified that this BLOCK matches us with
-                    the block_stack check above.  Never delete the
-                    BLOCK for the outermost scope of the function; we
-                    can refer to names from that scope even if the
-                    block notes are messed up.  */
-                 if (! is_body_block (NOTE_BLOCK (insn))
-                     && (*debug_hooks->ignore_block) (NOTE_BLOCK (insn)))
-                   {
-                     remove_insn (tmp);
-                     remove_insn (insn);
-                   }
-                 break;
-               }
-             else if (NOTE_LINE_NUMBER (tmp) == NOTE_INSN_BLOCK_END)
-               /* There's a nested block.  We need to leave the
-                  current block in place since otherwise the debugger
-                  wouldn't be able to show symbols from our block in
-                  the nested block.  */
-               break;
-           }
+       default:
+         break;
        }
     }
 
        }
     }
 
-  /* Too many begin notes.  */
-  gcc_assert (!block_stack && !eh_stack);
+  /* Too many EH_REGION_BEG notes.  */
+  gcc_assert (!eh_stack);
 }
 
 \f
 }
 
 \f
index c399eb1..b906cf0 100644 (file)
@@ -260,10 +260,7 @@ static hashval_t t2r_hash (const void *);
 static void add_type_for_runtime (tree);
 static tree lookup_type_for_runtime (tree);
 
 static void add_type_for_runtime (tree);
 static tree lookup_type_for_runtime (tree);
 
-static void resolve_fixup_regions (void);
-static void remove_fixup_regions (void);
 static void remove_unreachable_regions (rtx);
 static void remove_unreachable_regions (rtx);
-static void convert_from_eh_region_ranges_1 (rtx *, int *, int);
 
 static int ttypes_filter_eq (const void *, const void *);
 static hashval_t ttypes_filter_hash (const void *);
 
 static int ttypes_filter_eq (const void *, const void *);
 static hashval_t ttypes_filter_hash (const void *);
@@ -668,123 +665,6 @@ collect_eh_region_array (void)
     }
 }
 
     }
 }
 
-static void
-resolve_one_fixup_region (struct eh_region *fixup)
-{
-  struct eh_region *cleanup, *real;
-  int j, n;
-
-  n = cfun->eh->last_region_number;
-  cleanup = 0;
-
-  for (j = 1; j <= n; ++j)
-    {
-      cleanup = cfun->eh->region_array[j];
-      if (cleanup && cleanup->type == ERT_CLEANUP
-         && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
-       break;
-    }
-  gcc_assert (j <= n);
-
-  real = cleanup->outer;
-  if (real && real->type == ERT_FIXUP)
-    {
-      if (!real->u.fixup.resolved)
-       resolve_one_fixup_region (real);
-      real = real->u.fixup.real_region;
-    }
-
-  fixup->u.fixup.real_region = real;
-  fixup->u.fixup.resolved = true;
-}
-
-static void
-resolve_fixup_regions (void)
-{
-  int i, n = cfun->eh->last_region_number;
-
-  for (i = 1; i <= n; ++i)
-    {
-      struct eh_region *fixup = cfun->eh->region_array[i];
-
-      if (!fixup || fixup->type != ERT_FIXUP || fixup->u.fixup.resolved)
-       continue;
-
-      resolve_one_fixup_region (fixup);
-    }
-}
-
-/* Now that we've discovered what region actually encloses a fixup,
-   we can shuffle pointers and remove them from the tree.  */
-
-static void
-remove_fixup_regions (void)
-{
-  int i;
-  rtx insn, note;
-  struct eh_region *fixup;
-
-  /* Walk the insn chain and adjust the REG_EH_REGION numbers
-     for instructions referencing fixup regions.  This is only
-     strictly necessary for fixup regions with no parent, but
-     doesn't hurt to do it for all regions.  */
-  for (insn = get_insns(); insn ; insn = NEXT_INSN (insn))
-    if (INSN_P (insn)
-       && (note = find_reg_note (insn, REG_EH_REGION, NULL))
-       && INTVAL (XEXP (note, 0)) > 0
-       && (fixup = cfun->eh->region_array[INTVAL (XEXP (note, 0))])
-       && fixup->type == ERT_FIXUP)
-      {
-       if (fixup->u.fixup.real_region)
-         XEXP (note, 0) = GEN_INT (fixup->u.fixup.real_region->region_number);
-       else
-         remove_note (insn, note);
-      }
-
-  /* Remove the fixup regions from the tree.  */
-  for (i = cfun->eh->last_region_number; i > 0; --i)
-    {
-      fixup = cfun->eh->region_array[i];
-      if (! fixup)
-       continue;
-
-      /* Allow GC to maybe free some memory.  */
-      if (fixup->type == ERT_CLEANUP)
-       fixup->u.cleanup.exp = NULL_TREE;
-
-      if (fixup->type != ERT_FIXUP)
-       continue;
-
-      if (fixup->inner)
-       {
-         struct eh_region *parent, *p, **pp;
-
-         parent = fixup->u.fixup.real_region;
-
-         /* Fix up the children's parent pointers; find the end of
-            the list.  */
-         for (p = fixup->inner; ; p = p->next_peer)
-           {
-             p->outer = parent;
-             if (! p->next_peer)
-               break;
-           }
-
-         /* In the tree of cleanups, only outer-inner ordering matters.
-            So link the children back in anywhere at the correct level.  */
-         if (parent)
-           pp = &parent->inner;
-         else
-           pp = &cfun->eh->region_tree;
-         p->next_peer = *pp;
-         *pp = fixup->inner;
-         fixup->inner = NULL;
-       }
-
-      remove_eh_handler (fixup);
-    }
-}
-
 /* Remove all regions whose labels are not reachable from insns.  */
 
 static void
 /* Remove all regions whose labels are not reachable from insns.  */
 
 static void
@@ -868,113 +748,23 @@ remove_unreachable_regions (rtx insns)
   free (uid_region_num);
 }
 
   free (uid_region_num);
 }
 
-/* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each
-   can_throw instruction in the region.  */
-
-static void
-convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur)
-{
-  int *sp = orig_sp;
-  rtx insn, next;
-
-  for (insn = *pinsns; insn ; insn = next)
-    {
-      next = NEXT_INSN (insn);
-      if (NOTE_P (insn))
-       {
-         int kind = NOTE_LINE_NUMBER (insn);
-         if (kind == NOTE_INSN_EH_REGION_BEG
-             || kind == NOTE_INSN_EH_REGION_END)
-           {
-             if (kind == NOTE_INSN_EH_REGION_BEG)
-               {
-                 struct eh_region *r;
-
-                 *sp++ = cur;
-                 cur = NOTE_EH_HANDLER (insn);
-
-                 r = cfun->eh->region_array[cur];
-                 if (r->type == ERT_FIXUP)
-                   {
-                     r = r->u.fixup.real_region;
-                     cur = r ? r->region_number : 0;
-                   }
-                 else if (r->type == ERT_CATCH)
-                   {
-                     r = r->outer;
-                     cur = r ? r->region_number : 0;
-                   }
-               }
-             else
-               cur = *--sp;
-
-             if (insn == *pinsns)
-               *pinsns = next;
-             remove_insn (insn);
-             continue;
-           }
-       }
-      else if (INSN_P (insn))
-       {
-         if (cur > 0
-             && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
-             /* Calls can always potentially throw exceptions, unless
-                they have a REG_EH_REGION note with a value of 0 or less.
-                Which should be the only possible kind so far.  */
-             && (CALL_P (insn)
-                 /* If we wanted exceptions for non-call insns, then
-                    any may_trap_p instruction could throw.  */
-                 || (flag_non_call_exceptions
-                     && GET_CODE (PATTERN (insn)) != CLOBBER
-                     && GET_CODE (PATTERN (insn)) != USE
-                     && may_trap_p (PATTERN (insn)))))
-           {
-             REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur),
-                                                 REG_NOTES (insn));
-           }
-       }
-    }
-
-  gcc_assert (sp == orig_sp);
-}
-
-static void
-collect_rtl_labels_from_trees (void)
-{
-  int i, n = cfun->eh->last_region_number;
-  for (i = 1; i <= n; ++i)
-    {
-      struct eh_region *reg = cfun->eh->region_array[i];
-      if (reg && reg->tree_label)
-       reg->label = DECL_RTL_IF_SET (reg->tree_label);
-    }
-}
+/* Set up EH labels for RTL.  */
 
 void
 convert_from_eh_region_ranges (void)
 {
   rtx insns = get_insns ();
 
 void
 convert_from_eh_region_ranges (void)
 {
   rtx insns = get_insns ();
+  int i, n = cfun->eh->last_region_number;
 
 
-  if (cfun->eh->region_array)
-    {
-      /* If the region array already exists, assume we're coming from
-        optimize_function_tree.  In this case all we need to do is
-        collect the rtl labels that correspond to the tree labels
-        that we allocated earlier.  */
-      collect_rtl_labels_from_trees ();
-    }
-  else
+  /* Most of the work is already done at the tree level.  All we need to
+     do is collect the rtl labels that correspond to the tree labels that
+     collect the rtl labels that correspond to the tree labels
+     we allocated earlier.  */
+  for (i = 1; i <= n; ++i)
     {
     {
-      int *stack;
-
-      collect_eh_region_array ();
-      resolve_fixup_regions ();
-
-      stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1));
-      convert_from_eh_region_ranges_1 (&insns, stack, 0);
-      free (stack);
-
-      remove_fixup_regions ();
+      struct eh_region *region = cfun->eh->region_array[i];
+      if (region && region->tree_label)
+       region->label = DECL_RTL_IF_SET (region->tree_label);
     }
 
   remove_unreachable_regions (insns);
     }
 
   remove_unreachable_regions (insns);
index d413137..9b3ed5e 100644 (file)
@@ -1648,11 +1648,6 @@ reemit_notes (rtx insn, rtx last)
 
          last = emit_note_before (note_type, last);
          remove_note (insn, note);
 
          last = emit_note_before (note_type, last);
          remove_note (insn, note);
-         note = XEXP (note, 1);
-         if (note_type == NOTE_INSN_EH_REGION_BEG
-             || note_type == NOTE_INSN_EH_REGION_END)
-           NOTE_EH_HANDLER (last) = INTVAL (XEXP (note, 0));
-         remove_note (insn, note);
        }
     }
   return retval;
        }
     }
   return retval;
index 0378cf7..85c1f6b 100644 (file)
@@ -248,6 +248,10 @@ squeeze_notes (rtx* startp, rtx* endp)
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END))
        {
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
              || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END))
        {
+         /* BLOCK_BEG or BLOCK_END notes only exist in the `final' pass.  */
+         gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_BEG
+                     && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END);
+
          if (insn == start)
            start = next;
          else
          if (insn == start)
            start = next;
          else
index 36b13d1..37e84c8 100644 (file)
@@ -1538,10 +1538,6 @@ rest_of_clean_state (void)
 static void
 rest_of_compilation (void)
 {
 static void
 rest_of_compilation (void)
 {
-  /* Convert from NOTE_INSN_EH_REGION style notes, and do other
-     sorts of eh initialization.  */
-  convert_from_eh_region_ranges ();
-
   /* If we're emitting a nested function, make sure its parent gets
      emitted as well.  Doing otherwise confuses debug info.  */
   {
   /* If we're emitting a nested function, make sure its parent gets
      emitted as well.  Doing otherwise confuses debug info.  */
   {
index 5e23a93..32d0fdb 100644 (file)
@@ -976,18 +976,14 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes)
     {
       rtx link;
 
     {
       rtx link;
 
-      /* Update loop_notes with any notes from this insn.  Also determine
-        if any of the notes on the list correspond to instruction scheduling
-        barriers (loop, eh & setjmp notes, but not range notes).  */
+      /* Update loop_notes with any notes from this insn.  */
       link = loop_notes;
       while (XEXP (link, 1))
        {
       link = loop_notes;
       while (XEXP (link, 1))
        {
-         if (INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_BEG
-             || INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END
-             || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_BEG
-             || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_END)
-           reg_pending_barrier = MOVE_BARRIER;
+         gcc_assert (INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_BEG
+                     || INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END);
 
 
+         reg_pending_barrier = MOVE_BARRIER;
          link = XEXP (link, 1);
        }
       XEXP (link, 1) = REG_NOTES (insn);
          link = XEXP (link, 1);
        }
       XEXP (link, 1) = REG_NOTES (insn);
@@ -1323,26 +1319,19 @@ sched_analyze (struct deps *deps, rtx head, rtx tail)
            deps->in_post_call_group_p = post_call;
        }
 
            deps->in_post_call_group_p = post_call;
        }
 
+      /* EH_REGION insn notes can not appear until well after we complete
+        scheduling.  */
+      if (NOTE_P (insn))
+       gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
+                   && NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END);
+
       /* See comments on reemit_notes as to why we do this.
         ??? Actually, the reemit_notes just say what is done, not why.  */
 
       if (NOTE_P (insn)
       /* See comments on reemit_notes as to why we do this.
         ??? Actually, the reemit_notes just say what is done, not why.  */
 
       if (NOTE_P (insn)
-              && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
-                  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END
-                  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
-                  || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END))
+         && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG
+             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END))
        {
        {
-         rtx rtx_region;
-
-         if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG
-             || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
-           rtx_region = GEN_INT (NOTE_EH_HANDLER (insn));
-         else
-           rtx_region = const0_rtx;
-
-         loop_notes = alloc_EXPR_LIST (REG_SAVE_NOTE,
-                                       rtx_region,
-                                       loop_notes);
          loop_notes = alloc_EXPR_LIST (REG_SAVE_NOTE,
                                        GEN_INT (NOTE_LINE_NUMBER (insn)),
                                        loop_notes);
          loop_notes = alloc_EXPR_LIST (REG_SAVE_NOTE,
                                        GEN_INT (NOTE_LINE_NUMBER (insn)),
                                        loop_notes);