asan.c (handle_builtin_alloca): Deal with all alloca variants.
[gcc.git] / gcc / sched-deps.c
index dc46351ccd278305f3bc716000a1cc3142f62f74..a64e4e17bbc8115982d253d041032243e9506802 100644 (file)
@@ -1,6 +1,6 @@
 /* Instruction scheduling pass.  This file computes dependencies between
    instructions.
-   Copyright (C) 1992-2016 Free Software Foundation, Inc.
+   Copyright (C) 1992-2017 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
    and currently maintained by, Jim Wilson (wilson@cygnus.com)
 
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "df.h"
 #include "insn-config.h"
 #include "regs.h"
+#include "memmodel.h"
 #include "ira.h"
 #include "ira-int.h"
 #include "insn-attr.h"
@@ -2307,7 +2308,7 @@ sched_analyze_reg (struct deps_desc *deps, int regno, machine_mode mode,
      If so, mark all of them just like the first.  */
   if (regno < FIRST_PSEUDO_REGISTER)
     {
-      int i = hard_regno_nregs[regno][mode];
+      int i = hard_regno_nregs (regno, mode);
       if (ref == SET)
        {
          while (--i >= 0)
@@ -2418,7 +2419,7 @@ sched_analyze_1 (struct deps_desc *deps, rtx x, rtx_insn *insn)
     {
       if (GET_CODE (dest) == STRICT_LOW_PART
         || GET_CODE (dest) == ZERO_EXTRACT
-        || df_read_modify_subreg_p (dest))
+        || read_modify_subreg_p (dest))
         {
          /* These both read and modify the result.  We must handle
              them as writes to get proper dependencies for following
@@ -2833,34 +2834,30 @@ static void
 sched_macro_fuse_insns (rtx_insn *insn)
 {
   rtx_insn *prev;
-
+  prev = prev_nonnote_nondebug_insn (insn);
+  if (!prev)
+    return;
   if (any_condjump_p (insn))
     {
       unsigned int condreg1, condreg2;
       rtx cc_reg_1;
       targetm.fixed_condition_code_regs (&condreg1, &condreg2);
       cc_reg_1 = gen_rtx_REG (CCmode, condreg1);
-      prev = prev_nonnote_nondebug_insn (insn);
-      if (!reg_referenced_p (cc_reg_1, PATTERN (insn))
-          || !prev
-          || !modified_in_p (cc_reg_1, prev))
-        return;
+      if (reg_referenced_p (cc_reg_1, PATTERN (insn))
+         && modified_in_p (cc_reg_1, prev))
+       {
+         if (targetm.sched.macro_fusion_pair_p (prev, insn))
+           SCHED_GROUP_P (insn) = 1;
+         return;
+       }
     }
-  else
-    {
-      rtx insn_set = single_set (insn);
-
-      prev = prev_nonnote_nondebug_insn (insn);
-      if (!prev
-          || !insn_set
-          || !single_set (prev))
-        return;
 
+  if (single_set (insn) && single_set (prev))
+    {
+      if (targetm.sched.macro_fusion_pair_p (prev, insn))
+       SCHED_GROUP_P (insn) = 1;
     }
-
-  if (targetm.sched.macro_fusion_pair_p (prev, insn))
-    SCHED_GROUP_P (insn) = 1;
-
 }
 
 /* Get the implicit reg pending clobbers for INSN and save them in TEMP.  */
@@ -3501,6 +3498,31 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx_insn *insn)
       if (!deps->readonly)
        deps->last_args_size = insn;
     }
+
+  /* We must not mix prologue and epilogue insns.  See PR78029.  */
+  if (prologue_contains (insn))
+    {
+      add_dependence_list (insn, deps->last_epilogue, true, REG_DEP_ANTI, true);
+      if (!deps->readonly)
+       {
+         if (deps->last_logue_was_epilogue)
+           free_INSN_LIST_list (&deps->last_prologue);
+         deps->last_prologue = alloc_INSN_LIST (insn, deps->last_prologue);
+         deps->last_logue_was_epilogue = false;
+       }
+    }
+
+  if (epilogue_contains (insn))
+    {
+      add_dependence_list (insn, deps->last_prologue, true, REG_DEP_ANTI, true);
+      if (!deps->readonly)
+       {
+         if (!deps->last_logue_was_epilogue)
+           free_INSN_LIST_list (&deps->last_epilogue);
+         deps->last_epilogue = alloc_INSN_LIST (insn, deps->last_epilogue);
+         deps->last_logue_was_epilogue = true;
+       }
+    }
 }
 
 /* Return TRUE if INSN might not always return normally (e.g. call exit,
@@ -3684,7 +3706,8 @@ deps_analyze_insn (struct deps_desc *deps, rtx_insn *insn)
              Since we only have a choice between 'might be clobbered'
              and 'definitely not clobbered', we must include all
              partly call-clobbered registers here.  */
-            else if (HARD_REGNO_CALL_PART_CLOBBERED (i, reg_raw_mode[i])
+           else if (targetm.hard_regno_call_part_clobbered (i,
+                                                            reg_raw_mode[i])
                      || TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
               SET_REGNO_REG_SET (reg_pending_clobbers, i);
           /* We don't know what set of fixed registers might be used
@@ -3906,6 +3929,9 @@ init_deps (struct deps_desc *deps, bool lazy_reg_last)
   deps->in_post_call_group_p = not_post_call;
   deps->last_debug_insn = 0;
   deps->last_args_size = 0;
+  deps->last_prologue = 0;
+  deps->last_epilogue = 0;
+  deps->last_logue_was_epilogue = false;
   deps->last_reg_pending_barrier = NOT_A_BARRIER;
   deps->readonly = 0;
 }
@@ -4688,6 +4714,11 @@ parse_add_or_inc (struct mem_inc_info *mii, rtx_insn *insn, bool before_mem)
   if (RTX_FRAME_RELATED_P (insn) || !pat)
     return false;
 
+  /* Do not allow breaking data dependencies for insns that are marked
+     with REG_STACK_CHECK.  */
+  if (find_reg_note (insn, REG_STACK_CHECK, NULL))
+    return false;
+
   /* Result must be single reg.  */
   if (!REG_P (SET_DEST (pat)))
     return false;