OSDN Git Service

PR fortran/31612
[pf3gnuchains/gcc-fork.git] / gcc / sched-deps.c
index 456636c..1bea55d 100644 (file)
@@ -1,7 +1,7 @@
 /* Instruction scheduling pass.  This file computes dependencies between
    instructions.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
    and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -10,7 +10,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -19,9 +19,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 \f
 #include "config.h"
 #include "system.h"
@@ -42,7 +41,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "sched-int.h"
 #include "params.h"
 #include "cselib.h"
-#include "df.h"
 
 #ifdef ENABLE_CHECKING
 #define CHECK (true)
@@ -550,7 +548,7 @@ sched_insns_conditions_mutex_p (rtx insn1, rtx insn2)
 {
   rtx cond1, cond2;
 
-  /* flow.c doesn't handle conditional lifetimes entirely correctly;
+  /* df doesn't handle conditional lifetimes entirely correctly;
      calls mess up the conditional lifetimes.  */
   if (!CALL_P (insn1) && !CALL_P (insn2))
     {
@@ -1017,11 +1015,26 @@ fixup_sched_groups (rtx insn)
    so that we can do memory aliasing on it.  */
 
 static void
-add_insn_mem_dependence (struct deps *deps, rtx *insn_list, rtx *mem_list,
+add_insn_mem_dependence (struct deps *deps, bool read_p,
                         rtx insn, rtx mem)
 {
+  rtx *insn_list;
+  rtx *mem_list;
   rtx link;
 
+  if (read_p)
+    {
+      insn_list = &deps->pending_read_insns;
+      mem_list = &deps->pending_read_mems;
+      deps->pending_read_list_length++;
+    }
+  else
+    {
+      insn_list = &deps->pending_write_insns;
+      mem_list = &deps->pending_write_mems;
+      deps->pending_write_list_length++;
+    }
+
   link = alloc_INSN_LIST (insn, *insn_list);
   *insn_list = link;
 
@@ -1032,8 +1045,6 @@ add_insn_mem_dependence (struct deps *deps, rtx *insn_list, rtx *mem_list,
     }
   link = alloc_EXPR_LIST (VOIDmode, canon_rtx (mem), *mem_list);
   *mem_list = link;
-
-  deps->pending_lists_length++;
 }
 
 /* Make a dependency between every memory reference on the pending lists
@@ -1049,12 +1060,13 @@ flush_pending_lists (struct deps *deps, rtx insn, int for_read,
       add_dependence_list_and_free (insn, &deps->pending_read_insns, 1,
                                    REG_DEP_ANTI);
       free_EXPR_LIST_list (&deps->pending_read_mems);
+      deps->pending_read_list_length = 0;
     }
 
   add_dependence_list_and_free (insn, &deps->pending_write_insns, 1,
                                for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
   free_EXPR_LIST_list (&deps->pending_write_mems);
-  deps->pending_lists_length = 0;
+  deps->pending_write_list_length = 0;
 
   add_dependence_list_and_free (insn, &deps->last_pending_memory_flush, 1,
                                for_read ? REG_DEP_ANTI : REG_DEP_OUTPUT);
@@ -1218,7 +1230,8 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
        }
       t = canon_rtx (t);
 
-      if (deps->pending_lists_length > MAX_PENDING_LIST_LENGTH)
+      if ((deps->pending_read_list_length + deps->pending_write_list_length)
+         > MAX_PENDING_LIST_LENGTH)
        {
          /* Flush all pending reads and writes to prevent the pending lists
             from getting any larger.  Insn scheduling runs too slowly when
@@ -1258,8 +1271,7 @@ sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
          add_dependence_list (insn, deps->last_pending_memory_flush, 1,
                               REG_DEP_ANTI);
 
-         add_insn_mem_dependence (deps, &deps->pending_write_insns,
-                                  &deps->pending_write_mems, insn, dest);
+         add_insn_mem_dependence (deps, false, insn, dest);
        }
       sched_analyze_2 (deps, XEXP (dest, 0), insn);
     }
@@ -1380,8 +1392,7 @@ sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
 
        /* Always add these dependencies to pending_reads, since
           this insn may be followed by a write.  */
-       add_insn_mem_dependence (deps, &deps->pending_read_insns,
-                                &deps->pending_read_mems, insn, x);
+       add_insn_mem_dependence (deps, true, insn, x);
 
        /* Take advantage of tail recursion here.  */
        sched_analyze_2 (deps, XEXP (x, 0), insn);
@@ -1585,8 +1596,12 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn)
 
   /* If this instruction can throw an exception, then moving it changes
      where block boundaries fall.  This is mighty confusing elsewhere.
-     Therefore, prevent such an instruction from being moved.  */
-  if (can_throw_internal (insn))
+     Therefore, prevent such an instruction from being moved.  Same for
+     non-jump instructions that define block boundaries.
+     ??? Unclear whether this is still necessary in EBB mode.  If not,
+     add_branch_dependences should be adjusted for RGN mode instead.  */
+  if (((CALL_P (insn) || JUMP_P (insn)) && can_throw_internal (insn))
+      || (NONJUMP_INSN_P (insn) && control_flow_insn_p (insn)))
     reg_pending_barrier = MOVE_BARRIER;
 
   /* Add dependencies if a scheduling barrier was found.  */
@@ -1823,9 +1838,6 @@ sched_analyze (struct deps *deps, rtx head, rtx tail)
 
       if (INSN_P (insn))
        {
-         /* Clear out the stale LOG_LINKS from flow.  */
-         free_INSN_LIST_list (&LOG_LINKS (insn));
-
          /* These two lists will be freed in schedule_insn ().  */
          INSN_BACK_DEPS (insn) = create_deps_list (false);
          INSN_RESOLVED_BACK_DEPS (insn) = create_deps_list (false);
@@ -1920,8 +1932,8 @@ sched_analyze (struct deps *deps, rtx head, rtx tail)
       /* 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);
+       gcc_assert (NOTE_KIND (insn) != NOTE_INSN_EH_REGION_BEG
+                   && NOTE_KIND (insn) != NOTE_INSN_EH_REGION_END);
 
       if (current_sched_info->use_cselib)
        cselib_process_insn (insn);
@@ -2081,7 +2093,8 @@ init_deps (struct deps *deps)
   deps->pending_read_mems = 0;
   deps->pending_write_insns = 0;
   deps->pending_write_mems = 0;
-  deps->pending_lists_length = 0;
+  deps->pending_read_list_length = 0;
+  deps->pending_write_list_length = 0;
   deps->pending_flush_length = 0;
   deps->last_pending_memory_flush = 0;
   deps->last_function_call = 0;