OSDN Git Service

PR c++/53821
[pf3gnuchains/gcc-fork.git] / gcc / sched-deps.c
index b669cd3..33a6996 100644 (file)
@@ -2,7 +2,7 @@
    instructions.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-   2011
+   2011, 2012
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
    and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -521,9 +521,6 @@ sched_get_condition_with_rev_uncached (const_rtx insn, bool *rev)
   rtx pat = PATTERN (insn);
   rtx src;
 
-  if (pat == 0)
-    return 0;
-
   if (rev)
     *rev = false;
 
@@ -1505,6 +1502,10 @@ sd_debug_lists (rtx insn, sd_list_types_def types)
 void
 add_dependence (rtx con, rtx pro, enum reg_note dep_type)
 {
+  if (dep_type == REG_DEP_CONTROL
+      && !(current_sched_info->flags & DO_PREDICATION))
+    dep_type = REG_DEP_ANTI;
+
   /* A REG_DEP_CONTROL dependence may be eliminated through predication,
      so we must also make the insn dependent on the setter of the
      condition.  */
@@ -1727,7 +1728,8 @@ add_insn_mem_dependence (struct deps_desc *deps, bool read_p,
   if (sched_deps_info->use_cselib)
     {
       mem = shallow_copy_rtx (mem);
-      XEXP (mem, 0) = cselib_subst_to_values (XEXP (mem, 0), GET_MODE (mem));
+      XEXP (mem, 0) = cselib_subst_to_values_from_insn (XEXP (mem, 0),
+                                                       GET_MODE (mem), insn);
     }
   link = alloc_EXPR_LIST (VOIDmode, canon_rtx (mem), *mem_list);
   *mem_list = link;
@@ -2448,7 +2450,9 @@ sched_analyze_1 (struct deps_desc *deps, rtx x, rtx insn)
          t = shallow_copy_rtx (dest);
          cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
                                   GET_MODE (t), insn);
-         XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (t));
+         XEXP (t, 0)
+           = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t),
+                                               insn);
        }
       t = canon_rtx (t);
 
@@ -2608,7 +2612,9 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx insn)
            t = shallow_copy_rtx (t);
            cselib_lookup_from_insn (XEXP (t, 0), address_mode, 1,
                                     GET_MODE (t), insn);
-           XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0), GET_MODE (t));
+           XEXP (t, 0)
+             = cselib_subst_to_values_from_insn (XEXP (t, 0), GET_MODE (t),
+                                                 insn);
          }
 
        if (!DEBUG_INSN_P (insn))
@@ -2632,8 +2638,7 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx insn)
            pending_mem = deps->pending_write_mems;
            while (pending)
              {
-               if (true_dependence (XEXP (pending_mem, 0), VOIDmode,
-                                    t, rtx_varies_p)
+               if (true_dependence (XEXP (pending_mem, 0), VOIDmode, t)
                    && ! sched_insns_conditions_mutex_p (insn,
                                                         XEXP (pending, 0)))
                  note_mem_dep (t, XEXP (pending_mem, 0), XEXP (pending, 0),
@@ -2808,8 +2813,14 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
      during prologue generation and avoid marking the frame pointer setup
      as frame-related at all.  */
   if (RTX_FRAME_RELATED_P (insn))
-    deps->sched_before_next_jump
-      = alloc_INSN_LIST (insn, deps->sched_before_next_jump);
+    {
+      /* Make sure prologue insn is scheduled before next jump.  */
+      deps->sched_before_next_jump
+       = alloc_INSN_LIST (insn, deps->sched_before_next_jump);
+
+      /* Make sure epilogue insn is scheduled after preceding jumps.  */
+      add_dependence_list (insn, deps->pending_jump_insns, 1, REG_DEP_ANTI);
+    }
 
   if (code == COND_EXEC)
     {
@@ -2863,7 +2874,11 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
          else
            sched_analyze_2 (deps, XEXP (link, 0), insn);
        }
-      if (find_reg_note (insn, REG_SETJMP, NULL))
+      /* Don't schedule anything after a tail call, tail call needs
+        to use at least all call-saved registers.  */
+      if (SIBLING_CALL_P (insn))
+       reg_pending_barrier = TRUE_BARRIER;
+      else if (find_reg_note (insn, REG_SETJMP, NULL))
        reg_pending_barrier = MOVE_BARRIER;
     }