This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

EXPR_LIST and INSN_LIST patch



Ths following patch provides some generic routines for stashing
away and reusing INSN_LIST notes and EXPR_LIST notes. I've
scavenged whats in haifa-sched.c and made them more generic.
I've also introduced a new file, lists.c which we can use to
maintain various types of structures. Right now, this is all thats here :-)

This bootstraps on Solaris, and was approved by both rth and law.

Andrew

	* 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.

Index: haifa-sched.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/haifa-sched.c,v
retrieving revision 1.95
diff -c -p -r1.95 haifa-sched.c
*** haifa-sched.c	1999/08/20 23:05:09	1.95
--- haifa-sched.c	1999/08/24 22:00:51
*************** static void schedule_region PROTO ((int)
*** 769,850 ****
  
  #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.  */
--- 769,774 ----
*************** remove_dependence (insn, elem)
*** 952,960 ****
  	    XEXP (prev, 1) = next;
  	  else
  	    LOG_LINKS (insn) = next;
! 
! 	  XEXP (link, 1) = unused_insn_list;
! 	  unused_insn_list = link;
  
  	  found = 1;
  	}
--- 876,882 ----
  	    XEXP (prev, 1) = next;
  	  else
  	    LOG_LINKS (insn) = next;
! 	  free_INSN_LIST_node (link);
  
  	  found = 1;
  	}
*************** free_pending_lists ()
*** 3214,3223 ****
  {
    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);
      }
    else
      {
--- 3136,3145 ----
  {
    if (current_nr_blocks <= 1)
      {
!       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
      {
*************** free_pending_lists ()
*** 3226,3235 ****
  
        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);
  	}
      }
  }
--- 3148,3157 ----
  
        for (bb = 0; bb < current_nr_blocks; bb++)
  	{
! 	  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]);
  	}
      }
  }
*************** flush_pending_lists (insn, only_write)
*** 3272,3284 ****
  
        link = pending_read_insns;
        pending_read_insns = XEXP (pending_read_insns, 1);
!       XEXP (link, 1) = unused_insn_list;
!       unused_insn_list = link;
  
        link = pending_read_mems;
        pending_read_mems = XEXP (pending_read_mems, 1);
!       XEXP (link, 1) = unused_expr_list;
!       unused_expr_list = link;
      }
    while (pending_write_insns)
      {
--- 3194,3204 ----
  
        link = pending_read_insns;
        pending_read_insns = XEXP (pending_read_insns, 1);
!       free_INSN_LIST_node (link);
  
        link = pending_read_mems;
        pending_read_mems = XEXP (pending_read_mems, 1);
!       free_EXPR_LIST_node (link);
      }
    while (pending_write_insns)
      {
*************** flush_pending_lists (insn, only_write)
*** 3286,3298 ****
  
        link = pending_write_insns;
        pending_write_insns = XEXP (pending_write_insns, 1);
!       XEXP (link, 1) = unused_insn_list;
!       unused_insn_list = link;
  
        link = pending_write_mems;
        pending_write_mems = XEXP (pending_write_mems, 1);
!       XEXP (link, 1) = unused_expr_list;
!       unused_expr_list = link;
      }
    pending_lists_length = 0;
  
--- 3206,3216 ----
  
        link = pending_write_insns;
        pending_write_insns = XEXP (pending_write_insns, 1);
!       free_INSN_LIST_node (link);
  
        link = pending_write_mems;
        pending_write_mems = XEXP (pending_write_mems, 1);
!       free_EXPR_LIST_node (link);
      }
    pending_lists_length = 0;
  
*************** flush_pending_lists (insn, only_write)
*** 3300,3306 ****
    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);
    last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX);
  }
  
--- 3218,3224 ----
    for (u = last_pending_memory_flush; u; u = XEXP (u, 1))
      add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
  
!   free_INSN_LIST_list (&last_pending_memory_flush);
    last_pending_memory_flush = alloc_INSN_LIST (insn, NULL_RTX);
  }
  
*************** sched_analyze_1 (x, insn)
*** 3367,3373 ****
  		 but sets must be ordered with respect to a pending clobber. */
  	      if (code == SET)
  		{
! 		  free_list (&reg_last_uses[regno + i], &unused_insn_list);
  	          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);
--- 3285,3291 ----
  		 but sets must be ordered with respect to a pending clobber. */
  	      if (code == SET)
  		{
! 		  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);
*************** sched_analyze_1 (x, insn)
*** 3394,3400 ****
  
  	  if (code == SET)
  	    {
! 	      free_list (&reg_last_uses[regno], &unused_insn_list);
  	      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);
--- 3312,3318 ----
  
  	  if (code == SET)
  	    {
! 	      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);
*************** sched_analyze_2 (x, insn)
*** 3660,3666 ****
  	      {
  		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);
  
  		for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		  add_dependence (insn, XEXP (u, 0), 0);
--- 3578,3584 ----
  	      {
  		for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
  		  add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 		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);
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3793,3799 ****
  	      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);
  
  	      for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		add_dependence (insn, XEXP (u, 0), 0);
--- 3711,3717 ----
  	      rtx u;
  	      for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
  		add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 	      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);
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3813,3821 ****
       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);
  			       reg_last_sets[i]
  				 = alloc_INSN_LIST (insn, NULL_RTX);
  			     });
--- 3731,3738 ----
       subsequent sets will be output dependant on it.  */
    EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
  			     {
! 			       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);
  			     });
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3831,3837 ****
      {
        for (i = 0; i < maxreg; i++)
  	{
! 	  free_list (&reg_last_sets[i], &unused_insn_list);
  	  reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
  	}
  
--- 3748,3754 ----
      {
        for (i = 0; i < maxreg; i++)
  	{
! 	  free_INSN_LIST_list (&reg_last_sets[i]);
  	  reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
  	}
  
*************** sched_analyze (head, tail)
*** 3925,3931 ****
  		{
  		  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);
  
  		  for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
  		    add_dependence (insn, XEXP (u, 0), 0);
--- 3842,3848 ----
  		{
  		  for (u = reg_last_uses[i]; u; u = XEXP (u, 1))
  		    add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
! 		  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);
*************** sched_analyze (head, tail)
*** 3983,3989 ****
  	     function call) on all hard register clobberage.  */
  
  	  /* last_function_call is now a list of insns */
! 	  free_list(&last_function_call, &unused_insn_list);
  	  last_function_call = alloc_INSN_LIST (insn, NULL_RTX);
  	}
  
--- 3900,3906 ----
  	     function call) on all hard register clobberage.  */
  
  	  /* last_function_call is now a list of insns */
! 	  free_INSN_LIST_list(&last_function_call);
  	  last_function_call = alloc_INSN_LIST (insn, NULL_RTX);
  	}
  
*************** compute_block_backward_dependences (bb)
*** 7443,7460 ****
    /* 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
       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);
        if (reg_last_sets[b])
! 	free_list (&reg_last_sets[b], &unused_insn_list);
        if (reg_last_uses[b])
! 	free_list (&reg_last_uses[b], &unused_insn_list);
      }
  
    /* Assert that we won't need bb_reg_last_* for this block anymore.  */
--- 7360,7377 ----
    /* 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_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_INSN_LIST_list (&reg_last_clobbers[b]);
        if (reg_last_sets[b])
! 	free_INSN_LIST_list (&reg_last_sets[b]);
        if (reg_last_uses[b])
! 	free_INSN_LIST_list (&reg_last_uses[b]);
      }
  
    /* Assert that we won't need bb_reg_last_* for this block anymore.  */
*************** schedule_insns (dump_file)
*** 8487,8504 ****
  
    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;
--- 8404,8409 ----
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.119
diff -c -p -r1.119 rtl.h
*** rtl.h	1999/08/24 12:04:52	1.119
--- rtl.h	1999/08/24 22:01:12
*************** extern void remove_node_from_expr_list	P
*** 1022,1027 ****
--- 1022,1034 ----
  /* 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: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.195
diff -c -p -r1.195 toplev.c
*** toplev.c	1999/08/24 12:04:52	1.195
--- toplev.c	1999/08/24 22:01:58
*************** rest_of_compilation (decl)
*** 3821,3826 ****
--- 3821,3828 ----
  
    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)
Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/Makefile.in,v
retrieving revision 1.280
diff -c -p -r1.280 Makefile.in
*** Makefile.in	1999/08/24 03:28:57	1.280
--- Makefile.in	1999/08/24 22:02:22
*************** OBJS = toplev.o version.o tree.o print-t
*** 667,673 ****
   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
  
  # 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
--- 667,673 ----
   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 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
*************** reg-stack.o : reg-stack.c $(CONFIG_H) sy
*** 1581,1586 ****
--- 1581,1587 ----
     $(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 \S


Index: lists.c
===================================================================
/* 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]