OSDN Git Service

Backport from mainline
[pf3gnuchains/gcc-fork.git] / gcc / cfglayout.c
index 02709d0..22d3d87 100644 (file)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfglayout.h"
 #include "cfgloop.h"
 #include "target.h"
+#include "common/common-target.h"
 #include "ggc.h"
 #include "alloc-pool.h"
 #include "flags.h"
@@ -148,6 +149,7 @@ skip_insns_after_block (basic_block bb)
            break;
          case NOTE_INSN_DELETED:
          case NOTE_INSN_DELETED_LABEL:
+         case NOTE_INSN_DELETED_DEBUG_LABEL:
            continue;
          default:
            reorder_insns (insn, insn, last_insn);
@@ -766,6 +768,7 @@ fixup_reorder_chain (void)
     {
       edge e_fall, e_taken, e;
       rtx bb_end_insn;
+      rtx ret_label = NULL_RTX;
       basic_block nb, src_bb;
       edge_iterator ei;
 
@@ -785,6 +788,7 @@ fixup_reorder_chain (void)
       bb_end_insn = BB_END (bb);
       if (JUMP_P (bb_end_insn))
        {
+         ret_label = JUMP_LABEL (bb_end_insn);
          if (any_condjump_p (bb_end_insn))
            {
              /* This might happen if the conditional jump has side
@@ -898,7 +902,7 @@ fixup_reorder_chain (void)
         Note force_nonfallthru can delete E_FALL and thus we have to
         save E_FALL->src prior to the call to force_nonfallthru.  */
       src_bb = e_fall->src;
-      nb = force_nonfallthru (e_fall);
+      nb = force_nonfallthru_and_redirect (e_fall, e_fall->dest, ret_label);
       if (nb)
        {
          nb->il.rtl->visited = 1;
@@ -912,7 +916,7 @@ fixup_reorder_chain (void)
             section boundaries).  */
          BB_COPY_PARTITION (src_bb, single_pred (bb));
          if (flag_reorder_blocks_and_partition
-             && targetm.have_named_sections
+             && targetm_common.have_named_sections
              && JUMP_P (BB_END (bb))
              && !any_condjump_p (BB_END (bb))
              && (EDGE_SUCC (bb, 0)->flags & EDGE_CROSSING))
@@ -1171,6 +1175,10 @@ duplicate_insn_chain (rtx from, rtx to)
       switch (GET_CODE (insn))
        {
        case DEBUG_INSN:
+         /* Don't duplicate label debug insns.  */
+         if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn)) == LABEL_DECL)
+           break;
+         /* FALLTHRU */
        case INSN:
        case CALL_INSN:
        case JUMP_INSN:
@@ -1194,6 +1202,9 @@ duplicate_insn_chain (rtx from, rtx to)
              break;
            }
          copy = emit_copy_of_insn_after (insn, get_last_insn ());
+         if (JUMP_P (insn) && JUMP_LABEL (insn) != NULL_RTX
+             && ANY_RETURN_P (JUMP_LABEL (insn)))
+           JUMP_LABEL (copy) = JUMP_LABEL (insn);
           maybe_copy_prologue_epilogue_insn (insn, copy);
          break;
 
@@ -1213,6 +1224,7 @@ duplicate_insn_chain (rtx from, rtx to)
 
            case NOTE_INSN_DELETED:
            case NOTE_INSN_DELETED_LABEL:
+           case NOTE_INSN_DELETED_DEBUG_LABEL:
              /* No problem to strip these.  */
            case NOTE_INSN_FUNCTION_BEG:
              /* There is always just single entry to function.  */