1/* List management for the GCC expander. 2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3 1999, 2003, 2004 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 2, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING. If not, write to the Free 19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2002110-1301, USA. */ 21 22#include "config.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tm.h" 26#include "toplev.h" 27#include "rtl.h" 28#include "ggc.h" 29 30static void free_list (rtx *, rtx *); 31 32/* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs. */ 33 34/* An INSN_LIST containing all INSN_LISTs allocated but currently unused. */ 35static GTY ((deletable)) rtx unused_insn_list; 36 37/* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused. */ 38static GTY ((deletable)) rtx unused_expr_list; 39 40 41/* This function will free an entire list of either EXPR_LIST or INSN_LIST 42 nodes. This is to be used only on lists that consist exclusively of 43 nodes of one type only. This is only called by free_EXPR_LIST_list 44 and free_INSN_LIST_list. */ 45static void 46free_list (rtx *listp, rtx *unused_listp) 47{ 48 rtx link, prev_link; 49 50 prev_link = *listp; 51 link = XEXP (prev_link, 1); 52 53 while (link) 54 { 55 prev_link = link; 56 link = XEXP (link, 1); 57 } 58 59 XEXP (prev_link, 1) = *unused_listp; 60 *unused_listp = *listp; 61 *listp = 0; 62} 63 64/* This call is used in place of a gen_rtx_INSN_LIST. If there is a cached 65 node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST 66 is made. */ 67rtx 68alloc_INSN_LIST (rtx val, rtx next) 69{ 70 rtx r; 71 72 if (unused_insn_list) 73 { 74 r = unused_insn_list; 75 unused_insn_list = XEXP (r, 1); 76 XEXP (r, 0) = val; 77 XEXP (r, 1) = next; 78 PUT_REG_NOTE_KIND (r, VOIDmode); 79 } 80 else 81 r = gen_rtx_INSN_LIST (VOIDmode, val, next); 82 83 return r; 84} 85 86/* This call is used in place of a gen_rtx_EXPR_LIST. If there is a cached 87 node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST 88 is made. */ 89rtx 90alloc_EXPR_LIST (int kind, rtx val, rtx next) 91{ 92 rtx r; 93 94 if (unused_expr_list) 95 { 96 r = unused_expr_list; 97 unused_expr_list = XEXP (r, 1); 98 XEXP (r, 0) = val; 99 XEXP (r, 1) = next; 100 PUT_REG_NOTE_KIND (r, kind); 101 } 102 else 103 r = gen_rtx_EXPR_LIST (kind, val, next); 104 105 return r; 106} 107 108/* This function will free up an entire list of EXPR_LIST nodes. */ 109void 110free_EXPR_LIST_list (rtx *listp) 111{ 112 if (*listp == 0) 113 return; 114 free_list (listp, &unused_expr_list); 115} 116 117/* This function will free up an entire list of INSN_LIST nodes. */ 118void 119free_INSN_LIST_list (rtx *listp) 120{ 121 if (*listp == 0) 122 return; 123 free_list (listp, &unused_insn_list); 124} 125 126/* This function will free up an individual EXPR_LIST node. */ 127void 128free_EXPR_LIST_node (rtx ptr) 129{ 130 XEXP (ptr, 1) = unused_expr_list; 131 unused_expr_list = ptr; 132} 133 134/* This function will free up an individual INSN_LIST node. */ 135void 136free_INSN_LIST_node (rtx ptr) 137{ 138 XEXP (ptr, 1) = unused_insn_list; 139 unused_insn_list = ptr; 140} 141 142#include "gt-lists.h" 143