lists.c (unused_insn_list, [...]): New file for maintaining various types of lists.
authorAndrew MacLeod <amacleod@cygnus.com>
Wed, 25 Aug 1999 17:50:53 +0000 (17:50 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Wed, 25 Aug 1999 17:50:53 +0000 (17:50 +0000)
Wed Aug 25 13:41:47 EDT 1999  Andrew MacLeod  <amacleod@cygnus.com>

* lists.c (unused_insn_list, unused_expr_list): New file for
maintaining various types of lists. New statics for maintaining a
cache of available INSN_LIST and EXPR_LIST nodes.
(free_list): Static function for freeing a list of INSN/EXPR nodes.
(alloc_INSN_LIST): Function to get a free INSN_LIST node.
(alloc_EXPR_LIST): Function to get a free EXPR_LIST node.
(init_EXPR_INSN_LIST_cache): Initialize the cache lists.
(free_EXPR_LIST_list): Free an entire list of EXPR_LIST nodes.
(free_INSN_LIST_list): Free an entire list of INSN_LIST nodes.
(free_EXPR_LIST_node): Free an individual EXPR_LIST node.
(free_INSN_LIST_node): Free an individual INSN_LIST node.
* haifa-sched.c (unused_insn_list, unused_expr_list): Moved to flow.c
(free_list, alloc_INSN_LIST, alloc_EXPR_LIST): Moved to flow.c
(remove_dependence, free_pending_lists): Use new global routines.
(flush_pending_lists, sched_analyze_insn): Use new global routines.
(sched_analyze, compute_block_backward_dependences): Use new routines.
(sched_analyze_1, sched_analyze_2): Use new routines.
(schedule_insns): Use new global routines.
* rtl.h (init_EXPR_INSN_LIST_cache, free_EXPR_LIST_list): Add function
prototypes.
(free_INSN_LIST_list, free_EXPR_LIST_node): Add prototypes.
(free_INSN_LIST_node, alloc_INSN_LIST, alloc_EXPR_LIST): Add function
prototypes.
* toplev.c (rest_of_compilation): Initialize node cache.
* Makefile.in (OBJS): Add lists.o to list of object files.
(lists.o): Add dependancies.

From-SVN: r28864

gcc/ChangeLog
gcc/Makefile.in
gcc/haifa-sched.c
gcc/lists.c [new file with mode: 0644]
gcc/rtl.h
gcc/toplev.c

index 5b81e158e4ae9529c8e75c8e12ac317682b98994..3e39ae7c08c5946b19da55c6077bef8fd40449ac 100644 (file)
@@ -1,3 +1,32 @@
+Wed Aug 25 13:41:47 EDT 1999  Andrew MacLeod  <amacleod@cygnus.com>
+
+       * lists.c (unused_insn_list, unused_expr_list): New file for
+       maintaining various types of lists. New statics for maintaining a 
+       cache of available INSN_LIST and EXPR_LIST nodes.
+       (free_list): Static function for freeing a list of INSN/EXPR nodes.
+       (alloc_INSN_LIST): Function to get a free INSN_LIST node.
+       (alloc_EXPR_LIST): Function to get a free EXPR_LIST node.
+       (init_EXPR_INSN_LIST_cache): Initialize the cache lists.
+       (free_EXPR_LIST_list): Free an entire list of EXPR_LIST nodes.
+       (free_INSN_LIST_list): Free an entire list of INSN_LIST nodes.
+       (free_EXPR_LIST_node): Free an individual EXPR_LIST node.
+       (free_INSN_LIST_node): Free an individual INSN_LIST node.
+       * haifa-sched.c (unused_insn_list, unused_expr_list): Moved to flow.c
+       (free_list, alloc_INSN_LIST, alloc_EXPR_LIST): Moved to flow.c
+       (remove_dependence, free_pending_lists): Use new global routines.
+       (flush_pending_lists, sched_analyze_insn): Use new global routines.
+       (sched_analyze, compute_block_backward_dependences): Use new routines.
+       (sched_analyze_1, sched_analyze_2): Use new routines.
+       (schedule_insns): Use new global routines.
+       * rtl.h (init_EXPR_INSN_LIST_cache, free_EXPR_LIST_list): Add function
+       prototypes.
+       (free_INSN_LIST_list, free_EXPR_LIST_node): Add prototypes.
+       (free_INSN_LIST_node, alloc_INSN_LIST, alloc_EXPR_LIST): Add function
+       prototypes.
+       * toplev.c (rest_of_compilation): Initialize node cache.
+       * Makefile.in (OBJS): Add lists.o to list of object files.
+       (lists.o): Add dependancies.
+
 Wed Aug 25 17:31:56 1999  Nick Clifton  <nickc@cygnus.com>
 
        * config/v850/v850.md: Fix compile time warning messages.
index bc424b13de128b6f5271b9c122aa7d71426232ff..2fcffc2d925619b577995c6bcda1c65bcf4dacf0 100644 (file)
@@ -667,7 +667,7 @@ OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
  insn-peep.o reorg.o haifa-sched.o final.o recog.o reg-stack.o \
  insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \
  profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o \
- mbchar.o dyn-string.o splay-tree.o graph.o sbitmap.o resource.o hash.o
+ mbchar.o dyn-string.o splay-tree.o graph.o sbitmap.o resource.o hash.o lists.o
 
 # GEN files are listed separately, so they can be built before doing parallel
 #  makes for cc1 or cc1plus.  Otherwise sequent parallel make attempts to load
@@ -1581,6 +1581,7 @@ reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) recog.h \
    $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-flags.h toplev.h \
    function.h
 dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h
+lists.o: lists.c $(CONFIG_H) system.h toplev.h $(RTL_H)
 
 $(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) \
    $(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \
index 5638592e17d416b731960740cd6200024405a2ea..42f44b7cad6e73e7b019db060c3fa3208c8e866d 100644 (file)
@@ -766,82 +766,6 @@ static void schedule_region PROTO ((int));
 \f
 #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X)))
 
-/* Helper functions for instruction scheduling.  */
-
-/* An INSN_LIST containing all INSN_LISTs allocated but currently unused.  */
-static rtx unused_insn_list;
-
-/* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused.  */
-static rtx unused_expr_list;
-
-static void free_list PROTO ((rtx *, rtx *));
-static rtx alloc_INSN_LIST PROTO ((rtx, rtx));
-static rtx alloc_EXPR_LIST PROTO ((int, rtx, rtx));
-
-static void
-free_list (listp, unused_listp)
-     rtx *listp, *unused_listp;
-{
-  register rtx link, prev_link;
-
-  if (*listp == 0)
-    return;
-
-  prev_link = *listp;
-  link = XEXP (prev_link, 1);
-
-  while (link)
-    {
-      prev_link = link;
-      link = XEXP (link, 1);
-    }
-
-  XEXP (prev_link, 1) = *unused_listp;
-  *unused_listp = *listp;
-  *listp = 0;
-}
-
-static rtx
-alloc_INSN_LIST (val, next)
-     rtx val, next;
-{
-  rtx r;
-
-  if (unused_insn_list)
-    {
-      r = unused_insn_list;
-      unused_insn_list = XEXP (r, 1);
-      XEXP (r, 0) = val;
-      XEXP (r, 1) = next;
-      PUT_REG_NOTE_KIND (r, VOIDmode);
-    }
-  else
-    r = gen_rtx_INSN_LIST (VOIDmode, val, next);
-
-  return r;
-}
-
-static rtx
-alloc_EXPR_LIST (kind, val, next)
-     int kind;
-     rtx val, next;
-{
-  rtx r;
-
-  if (unused_expr_list)
-    {
-      r = unused_expr_list;
-      unused_expr_list = XEXP (r, 1);
-      XEXP (r, 0) = val;
-      XEXP (r, 1) = next;
-      PUT_REG_NOTE_KIND (r, kind);
-    }
-  else
-    r = gen_rtx_EXPR_LIST (kind, val, next);
-
-  return r;
-}
-
 /* Add ELEM wrapped in an INSN_LIST with reg note kind DEP_TYPE to the
    LOG_LINKS of INSN, if not already there.  DEP_TYPE indicates the type
    of dependence that this link represents.  */
@@ -949,9 +873,7 @@ remove_dependence (insn, elem)
            XEXP (prev, 1) = next;
          else
            LOG_LINKS (insn) = next;
-
-         XEXP (link, 1) = unused_insn_list;
-         unused_insn_list = link;
+         free_INSN_LIST_node (link);
 
          found = 1;
        }
@@ -3226,10 +3148,10 @@ free_pending_lists ()
 {
   if (current_nr_blocks <= 1)
     {
-      free_list (&pending_read_insns, &unused_insn_list);
-      free_list (&pending_write_insns, &unused_insn_list);
-      free_list (&pending_read_mems, &unused_expr_list);
-      free_list (&pending_write_mems, &unused_expr_list);
+      free_INSN_LIST_list (&pending_read_insns);
+      free_INSN_LIST_list (&pending_write_insns);
+      free_EXPR_LIST_list (&pending_read_mems);
+      free_EXPR_LIST_list (&pending_write_mems);
     }
   else
     {
@@ -3238,10 +3160,10 @@ free_pending_lists ()
 
       for (bb = 0; bb < current_nr_blocks; bb++)
        {
-         free_list (&bb_pending_read_insns[bb], &unused_insn_list);
-         free_list (&bb_pending_write_insns[bb], &unused_insn_list);
-         free_list (&bb_pending_read_mems[bb], &unused_expr_list);
-         free_list (&bb_pending_write_mems[bb], &unused_expr_list);
+         free_INSN_LIST_list (&bb_pending_read_insns[bb]);
+         free_INSN_LIST_list (&bb_pending_write_insns[bb]);
+         free_EXPR_LIST_list (&bb_pending_read_mems[bb]);
+         free_EXPR_LIST_list (&bb_pending_write_mems[bb]);
        }
     }
 }
@@ -3284,13 +3206,11 @@ flush_pending_lists (insn, only_write)
 
       link = pending_read_insns;
       pending_read_insns = XEXP (pending_read_insns, 1);
-      XEXP (link, 1) = unused_insn_list;
-      unused_insn_list = link;
+      free_INSN_LIST_node (link);
 
       link = pending_read_mems;
       pending_read_mems = XEXP (pending_read_mems, 1);
-      XEXP (link, 1) = unused_expr_list;
-      unused_expr_list = link;
+      free_EXPR_LIST_node (link);
     }
   while (pending_write_insns)
     {
@@ -3298,13 +3218,11 @@ flush_pending_lists (insn, only_write)
 
       link = pending_write_insns;
       pending_write_insns = XEXP (pending_write_insns, 1);
-      XEXP (link, 1) = unused_insn_list;
-      unused_insn_list = link;
+      free_INSN_LIST_node (link);
 
       link = pending_write_mems;
       pending_write_mems = XEXP (pending_write_mems, 1);
-      XEXP (link, 1) = unused_expr_list;
-      unused_expr_list = link;
+      free_EXPR_LIST_node (link);
     }
   pending_lists_length = 0;
 
@@ -3312,7 +3230,7 @@ flush_pending_lists (insn, only_write)
   for (u = last_pending_memory_flush; u; u = XEXP (u, 1))
     add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
 
-  free_list (&last_pending_memory_flush, &unused_insn_list);
+  free_INSN_LIST_list (&last_pending_memory_flush);
   last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX);
 }
 
@@ -3379,7 +3297,7 @@ sched_analyze_1 (x, insn)
                 but sets must be ordered with respect to a pending clobber. */
              if (code == SET)
                {
-                 free_list (&reg_last_uses[regno + i], &unused_insn_list);
+                 free_INSN_LIST_list (&reg_last_uses[regno + i]);
                  for (u = reg_last_clobbers[regno + i]; u; u = XEXP (u, 1))
                    add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
                  SET_REGNO_REG_SET (reg_pending_sets, regno + i);
@@ -3406,7 +3324,7 @@ sched_analyze_1 (x, insn)
 
          if (code == SET)
            {
-             free_list (&reg_last_uses[regno], &unused_insn_list);
+             free_INSN_LIST_list (&reg_last_uses[regno]);
              for (u = reg_last_clobbers[regno]; u; u = XEXP (u, 1))
                add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
              SET_REGNO_REG_SET (reg_pending_sets, regno);
@@ -3672,7 +3590,7 @@ sched_analyze_2 (x, insn)
              {
                for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
                  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
-               free_list (&reg_last_uses[i], &unused_insn_list);
+               free_INSN_LIST_list (&reg_last_uses[i]);
 
                for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
                  add_dependence (insn, XEXP (u, 0), 0);
@@ -3805,7 +3723,7 @@ sched_analyze_insn (x, insn, loop_notes)
              rtx u;
              for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
                add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
-             free_list (&reg_last_uses[i], &unused_insn_list);
+             free_INSN_LIST_list (&reg_last_uses[i]);
 
              for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
                add_dependence (insn, XEXP (u, 0), 0);
@@ -3825,9 +3743,8 @@ sched_analyze_insn (x, insn, loop_notes)
      subsequent sets will be output dependant on it.  */
   EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
                             {
-                              free_list (&reg_last_sets[i], &unused_insn_list);
-                              free_list (&reg_last_clobbers[i],
-                                         &unused_insn_list);
+                              free_INSN_LIST_list (&reg_last_sets[i]);
+                              free_INSN_LIST_list (&reg_last_clobbers[i]);
                               reg_last_sets[i]
                                 = alloc_INSN_LIST (insn, NULL_RTX);
                             });
@@ -3843,7 +3760,7 @@ sched_analyze_insn (x, insn, loop_notes)
     {
       for (i = 0; i < maxreg; i++)
        {
-         free_list (&reg_last_sets[i], &unused_insn_list);
+         free_INSN_LIST_list (&reg_last_sets[i]);
          reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
        }
 
@@ -3937,7 +3854,7 @@ sched_analyze (head, tail)
                {
                  for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
                    add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
-                 free_list (&reg_last_uses[i], &unused_insn_list);
+                 free_INSN_LIST_list (&reg_last_uses[i]);
 
                  for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
                    add_dependence (insn, XEXP (u, 0), 0);
@@ -3995,7 +3912,7 @@ sched_analyze (head, tail)
             function call) on all hard register clobberage.  */
 
          /* last_function_call is now a list of insns */
-         free_list(&last_function_call, &unused_insn_list);
+         free_INSN_LIST_list(&last_function_call);
          last_function_call = alloc_INSN_LIST (insn, NULL_RTX);
        }
 
@@ -7455,18 +7372,18 @@ compute_block_backward_dependences (bb)
   /* Free up the INSN_LISTs 
 
      Note this loop is executed max_reg * nr_regions times.  It's first 
-     implementation accounted for over 90% of the calls to free_list.
-     The list was empty for the vast majority of those calls.  On the PA,
-     not calling free_list in those cases improves -O2 compile times by
+     implementation accounted for over 90% of the calls to free_INSN_LIST_list.
+     The list was empty for the vast majority of those calls.  On the PA, not 
+     calling free_INSN_LIST_list in those cases improves -O2 compile times by
      3-5% on average.  */
   for (b = 0; b < max_reg; ++b)
     {
       if (reg_last_clobbers[b])
-       free_list (&reg_last_clobbers[b], &unused_insn_list);
+       free_INSN_LIST_list (&reg_last_clobbers[b]);
       if (reg_last_sets[b])
-       free_list (&reg_last_sets[b], &unused_insn_list);
+       free_INSN_LIST_list (&reg_last_sets[b]);
       if (reg_last_uses[b])
-       free_list (&reg_last_uses[b], &unused_insn_list);
+       free_INSN_LIST_list (&reg_last_uses[b]);
     }
 
   /* Assert that we won't need bb_reg_last_* for this block anymore.  */
@@ -7823,18 +7740,6 @@ schedule_insns (dump_file)
   nr_inter = 0;
   nr_spec = 0;
 
-  /* Initialize the unused_*_lists.  We can't use the ones left over from
-     the previous function, because gcc has freed that memory.  We can use
-     the ones left over from the first sched pass in the second pass however,
-     so only clear them on the first sched pass.  The first pass is before
-     reload if flag_schedule_insns is set, otherwise it is afterwards.  */
-
-  if (reload_completed == 0 || !flag_schedule_insns)
-    {
-      unused_insn_list = 0;
-      unused_expr_list = 0;
-    }
-
   /* initialize issue_rate */
   issue_rate = ISSUE_RATE;
 
diff --git a/gcc/lists.c b/gcc/lists.c
new file mode 100644 (file)
index 0000000..331b953
--- /dev/null
@@ -0,0 +1,150 @@
+/* List management for the GNU C-Compiler expander.
+   Copyright (C) 1987, 88, 92-97, 1998, 1999 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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 version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "toplev.h"
+#include "rtl.h"
+
+/* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs.  */
+
+/* An INSN_LIST containing all INSN_LISTs allocated but currently unused.  */
+static rtx unused_insn_list;
+
+/* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused.  */
+static rtx unused_expr_list;
+
+
+/* This function will free an entire list of either EXPR_LIST or INSN_LIST
+   nodes. This is to be used only only lists that consist exclusively of
+   nodes of one type only.  This is only called by free_EXPR_LIST_list
+   and free_INSN_LIST_list.  */
+static void
+free_list (listp, unused_listp)
+     rtx *listp, *unused_listp;
+{
+  register rtx link, prev_link;
+
+  prev_link = *listp;
+  link = XEXP (prev_link, 1);
+
+  while (link)
+    {
+      prev_link = link;
+      link = XEXP (link, 1);
+    }
+
+  XEXP (prev_link, 1) = *unused_listp;
+  *unused_listp = *listp;
+  *listp = 0;
+}
+
+/* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached
+   node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST 
+   is made.  */
+rtx
+alloc_INSN_LIST (val, next)
+     rtx val, next;
+{
+  rtx r;
+
+  if (unused_insn_list)
+    {
+      r = unused_insn_list;
+      unused_insn_list = XEXP (r, 1);
+      XEXP (r, 0) = val;
+      XEXP (r, 1) = next;
+      PUT_REG_NOTE_KIND (r, VOIDmode);
+    }
+  else
+    r = gen_rtx_INSN_LIST (VOIDmode, val, next);
+
+  return r;
+}
+
+/* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached
+   node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST 
+   is made.  */
+rtx
+alloc_EXPR_LIST (kind, val, next)
+     int kind;
+     rtx val, next;
+{
+  rtx r;
+
+  if (unused_expr_list)
+    {
+      r = unused_expr_list;
+      unused_expr_list = XEXP (r, 1);
+      XEXP (r, 0) = val;
+      XEXP (r, 1) = next;
+      PUT_REG_NOTE_KIND (r, kind);
+    }
+  else
+    r = gen_rtx_EXPR_LIST (kind, val, next);
+
+  return r;
+}
+
+/* This function will initialize the EXPR_LIST and INSN_LIST caches.  */
+void 
+init_EXPR_INSN_LIST_cache ()
+{
+  unused_expr_list = NULL;
+  unused_insn_list = NULL;
+}
+
+/* This function will free up an entire list of EXPR_LIST nodes.  */
+void 
+free_EXPR_LIST_list (listp)
+     rtx *listp;
+{
+  if (*listp == 0)
+    return;
+  free_list (listp, &unused_expr_list);
+}
+
+/* This function will free up an entire list of INSN_LIST nodes.  */
+void 
+free_INSN_LIST_list (listp)
+     rtx *listp;
+{
+  if (*listp == 0)
+    return;
+  free_list (listp, &unused_insn_list);
+}
+
+/* This function will free up an individual EXPR_LIST node.  */
+void 
+free_EXPR_LIST_node (ptr)
+     rtx ptr;
+{
+  XEXP (ptr, 1) = unused_expr_list;
+  unused_expr_list = ptr;
+}
+
+/* This function will free up an individual INSN_LIST node.  */
+void 
+free_INSN_LIST_node (ptr)
+     rtx ptr;
+{
+  XEXP (ptr, 1) = unused_insn_list;
+  unused_insn_list = ptr;
+}
index 40a3125342f7eacdd3b9d0b887687b37d622a84b..3c8a1924eb530e61d66fbc72183ec6a359045cf5 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1022,6 +1022,13 @@ extern void remove_node_from_expr_list   PROTO((rtx, rtx *));
 /* flow.c */
 
 extern rtx find_use_as_address         PROTO((rtx, rtx, HOST_WIDE_INT));
+void init_EXPR_INSN_LIST_cache         PROTO((void));
+void free_EXPR_LIST_list               PROTO((rtx *));
+void free_INSN_LIST_list               PROTO((rtx *));
+void free_EXPR_LIST_node               PROTO((rtx));
+void free_INSN_LIST_node               PROTO((rtx));
+rtx alloc_INSN_LIST                    PROTO((rtx, rtx));
+rtx alloc_EXPR_LIST                    PROTO((int, rtx, rtx));
 
 /* regclass.c */
 
index 1f831b7b2254b7120a032b2187239baea7783456..19b983332483cf1d8af7ce1e39a55cc4a46f4193 100644 (file)
@@ -3821,6 +3821,8 @@ rest_of_compilation (decl)
 
   unshare_all_rtl (insns);
 
+  init_EXPR_INSN_LIST_cache ();
+
 #ifdef SETJMP_VIA_SAVE_AREA
   /* This must be performed before virutal register instantiation.  */
   if (current_function_calls_alloca)