OSDN Git Service

* doc/invoke.texi (C++ Dialect Options): Update -fabi-version=6
[pf3gnuchains/gcc-fork.git] / gcc / sel-sched-ir.c
index 4fa2837..a93cd68 100644 (file)
@@ -1745,6 +1745,11 @@ update_target_availability (expr_t to, expr_t from, insn_t split_point)
           else
             EXPR_TARGET_AVAILABLE (to) = -1;
         }
+      else if (EXPR_TARGET_AVAILABLE (from) == 0
+              && EXPR_LHS (from)
+              && REG_P (EXPR_LHS (from))
+              && REGNO (EXPR_LHS (to)) != REGNO (EXPR_LHS (from)))
+       EXPR_TARGET_AVAILABLE (to) = -1;
       else
         EXPR_TARGET_AVAILABLE (to) &= EXPR_TARGET_AVAILABLE (from);
     }
@@ -3227,7 +3232,8 @@ has_dependence_note_reg_use (int regno)
          pro_spec_checked_ds = INSN_SPEC_CHECKED_DS (has_dependence_data.pro);
          pro_spec_checked_ds = ds_get_max_dep_weak (pro_spec_checked_ds);
 
-         if (pro_spec_checked_ds != 0)
+         if (pro_spec_checked_ds != 0
+             && bitmap_bit_p (INSN_REG_SETS (has_dependence_data.pro), regno))
            /* Merge BE_IN_SPEC bits into *DSP.  */
            *dsp = ds_full_merge (*dsp, pro_spec_checked_ds,
                                  NULL_RTX, NULL_RTX);
@@ -3940,9 +3946,39 @@ sel_luid_for_non_insn (rtx x)
   return -1;
 }
 
-/* Return seqno of the only predecessor of INSN.  */
+/*  Find the proper seqno for inserting at INSN by successors.
+    Return -1 if no successors with positive seqno exist.  */
 static int
-get_seqno_of_a_pred (insn_t insn)
+get_seqno_by_succs (rtx insn)
+{
+  basic_block bb = BLOCK_FOR_INSN (insn);
+  rtx tmp = insn, end = BB_END (bb);
+  int seqno;
+  insn_t succ = NULL;
+  succ_iterator si;
+
+  while (tmp != end)
+    {
+      tmp = NEXT_INSN (tmp);
+      if (INSN_P (tmp))
+        return INSN_SEQNO (tmp);
+    }
+
+  seqno = INT_MAX;
+
+  FOR_EACH_SUCC_1 (succ, si, end, SUCCS_NORMAL)
+    if (INSN_SEQNO (succ) > 0)
+      seqno = MIN (seqno, INSN_SEQNO (succ));
+
+  if (seqno == INT_MAX)
+    return -1;
+
+  return seqno;
+}
+
+/* Compute seqno for INSN by its preds or succs.  */
+static int
+get_seqno_for_a_jump (insn_t insn)
 {
   int seqno;
 
@@ -3982,14 +4018,24 @@ get_seqno_of_a_pred (insn_t insn)
          int n;
 
          cfg_preds (BLOCK_FOR_INSN (insn), &preds, &n);
-         gcc_assert (n == 1);
 
-         seqno = INSN_SEQNO (preds[0]);
+         gcc_assert (n > 0);
+         /* For one predecessor, use simple method.  */
+         if (n == 1)
+           seqno = INSN_SEQNO (preds[0]);
+         else
+           seqno = get_seqno_by_preds (insn);
 
          free (preds);
        }
     }
 
+  /* We were unable to find a good seqno among preds.  */
+  if (seqno < 0)
+    seqno = get_seqno_by_succs (insn);
+
+  gcc_assert (seqno >= 0);
+
   return seqno;
 }
 
@@ -4004,10 +4050,11 @@ get_seqno_by_preds (rtx insn)
   int n, i, seqno;
 
   while (tmp != head)
-    if (INSN_P (tmp))
-      return INSN_SEQNO (tmp);
-    else
+    {
       tmp = PREV_INSN (tmp);
+      if (INSN_P (tmp))
+        return INSN_SEQNO (tmp);
+    }
 
   cfg_preds (bb, &preds, &n);
   for (i = 0, seqno = -1; i < n; i++)
@@ -4179,7 +4226,7 @@ init_simplejump_data (insn_t insn)
   init_expr (INSN_EXPR (insn), vinsn_create (insn, false), 0,
             REG_BR_PROB_BASE, 0, 0, 0, 0, 0, 0, NULL, true, false, false,
             false, true);
-  INSN_SEQNO (insn) = get_seqno_of_a_pred (insn);
+  INSN_SEQNO (insn) = get_seqno_for_a_jump (insn);
   init_first_time_insn_data (insn);
 }
 
@@ -5676,7 +5723,7 @@ create_vinsn_from_insn_rtx (rtx insn_rtx, bool force_unique_p)
 rtx
 create_copy_of_insn_rtx (rtx insn_rtx)
 {
-  rtx res;
+  rtx res, link;
 
   if (DEBUG_INSN_P (insn_rtx))
     return create_insn_rtx_from_pattern (copy_rtx (PATTERN (insn_rtx)),
@@ -5686,6 +5733,22 @@ create_copy_of_insn_rtx (rtx insn_rtx)
 
   res = create_insn_rtx_from_pattern (copy_rtx (PATTERN (insn_rtx)),
                                       NULL_RTX);
+
+  /* Copy all REG_NOTES except REG_EQUAL/REG_EQUIV and REG_LABEL_OPERAND
+     since mark_jump_label will make them.  REG_LABEL_TARGETs are created
+     there too, but are supposed to be sticky, so we copy them.  */
+  for (link = REG_NOTES (insn_rtx); link; link = XEXP (link, 1))
+    if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND
+       && REG_NOTE_KIND (link) != REG_EQUAL
+       && REG_NOTE_KIND (link) != REG_EQUIV)
+      {
+       if (GET_CODE (link) == EXPR_LIST)
+         add_reg_note (res, REG_NOTE_KIND (link),
+                       copy_insn_1 (XEXP (link, 0)));
+       else
+         add_reg_note (res, REG_NOTE_KIND (link), XEXP (link, 0));
+      }
+
   return res;
 }