X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flists.c;h=998467103053b382b509ad7af1f624c0e4f5631a;hb=27f97b121b8499a35e7f1d915649d099ebe7fcfe;hp=58d90d37756caa43f96ffa3f956fc434666ff38e;hpb=548ec30fac7cb3becd23ba1d5c66bc56c225ad3b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lists.c b/gcc/lists.c index 58d90d37756..99846710305 100644 --- a/gcc/lists.c +++ b/gcc/lists.c @@ -1,12 +1,13 @@ -/* List management for the GNU C-Compiler expander. +/* List management for the GCC expander. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999 Free Software Foundation, Inc. + 1999, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. 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 @@ -15,42 +16,47 @@ 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, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "toplev.h" #include "rtl.h" #include "ggc.h" -static void free_list PARAMS ((rtx *, rtx *)); +static void free_list (rtx *, rtx *); /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs. */ /* An INSN_LIST containing all INSN_LISTs allocated but currently unused. */ -static GTY ((deletable (""))) rtx unused_insn_list; +static GTY ((deletable)) rtx unused_insn_list; /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused. */ -static GTY ((deletable (""))) rtx unused_expr_list; +static GTY ((deletable)) 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 on lists that consist exclusively of - nodes of one type only. This is only called by free_EXPR_LIST_list - and free_INSN_LIST_list. */ +/* This function will free an entire list of either EXPR_LIST, INSN_LIST + or DEPS_LIST nodes. This is to be used only on lists that consist + exclusively of nodes of one type only. This is only called by + free_EXPR_LIST_list, free_INSN_LIST_list and free_DEPS_LIST_list. */ static void -free_list (listp, unused_listp) - rtx *listp, *unused_listp; +free_list (rtx *listp, rtx *unused_listp) { rtx link, prev_link; prev_link = *listp; link = XEXP (prev_link, 1); + gcc_assert (unused_listp != &unused_insn_list + || GET_CODE (prev_link) == INSN_LIST); + while (link) { + gcc_assert (unused_listp != &unused_insn_list + || GET_CODE (prev_link) == INSN_LIST); + prev_link = link; link = XEXP (link, 1); } @@ -60,12 +66,45 @@ free_list (listp, unused_listp) *listp = 0; } +/* Find corresponding to ELEM node in the list pointed to by LISTP. + This node must exist in the list. Returns pointer to that node. */ +static rtx * +find_list_elem (rtx elem, rtx *listp) +{ + while (XEXP (*listp, 0) != elem) + listp = &XEXP (*listp, 1); + return listp; +} + +/* Remove the node pointed to by LISTP from the list. */ +static void +remove_list_node (rtx *listp) +{ + rtx node; + + node = *listp; + *listp = XEXP (node, 1); + XEXP (node, 1) = 0; +} + +/* Removes corresponding to ELEM node from the list pointed to by LISTP. + Returns that node. */ +rtx +remove_list_elem (rtx elem, rtx *listp) +{ + rtx node; + + listp = find_list_elem (elem, listp); + node = *listp; + remove_list_node (listp); + return node; +} + /* 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; +alloc_INSN_LIST (rtx val, rtx next) { rtx r; @@ -76,6 +115,8 @@ alloc_INSN_LIST (val, next) XEXP (r, 0) = val; XEXP (r, 1) = next; PUT_REG_NOTE_KIND (r, VOIDmode); + + gcc_assert (GET_CODE (r) == INSN_LIST); } else r = gen_rtx_INSN_LIST (VOIDmode, val, next); @@ -87,9 +128,7 @@ alloc_INSN_LIST (val, next) 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; +alloc_EXPR_LIST (int kind, rtx val, rtx next) { rtx r; @@ -102,15 +141,14 @@ alloc_EXPR_LIST (kind, val, next) PUT_REG_NOTE_KIND (r, kind); } else - r = gen_rtx_EXPR_LIST (kind, val, next); + r = gen_rtx_EXPR_LIST ((enum machine_mode) kind, val, next); return r; } /* This function will free up an entire list of EXPR_LIST nodes. */ void -free_EXPR_LIST_list (listp) - rtx *listp; +free_EXPR_LIST_list (rtx *listp) { if (*listp == 0) return; @@ -119,8 +157,7 @@ free_EXPR_LIST_list (listp) /* This function will free up an entire list of INSN_LIST nodes. */ void -free_INSN_LIST_list (listp) - rtx *listp; +free_INSN_LIST_list (rtx *listp) { if (*listp == 0) return; @@ -129,8 +166,7 @@ free_INSN_LIST_list (listp) /* This function will free up an individual EXPR_LIST node. */ void -free_EXPR_LIST_node (ptr) - rtx ptr; +free_EXPR_LIST_node (rtx ptr) { XEXP (ptr, 1) = unused_expr_list; unused_expr_list = ptr; @@ -138,11 +174,45 @@ free_EXPR_LIST_node (ptr) /* This function will free up an individual INSN_LIST node. */ void -free_INSN_LIST_node (ptr) - rtx ptr; +free_INSN_LIST_node (rtx ptr) { + gcc_assert (GET_CODE (ptr) == INSN_LIST); XEXP (ptr, 1) = unused_insn_list; unused_insn_list = ptr; } +/* Remove and free corresponding to ELEM node in the INSN_LIST pointed to + by LISTP. */ +void +remove_free_INSN_LIST_elem (rtx elem, rtx *listp) +{ + free_INSN_LIST_node (remove_list_elem (elem, listp)); +} + +/* Remove and free the first node in the INSN_LIST pointed to by LISTP. */ +rtx +remove_free_INSN_LIST_node (rtx *listp) +{ + rtx node = *listp; + rtx elem = XEXP (node, 0); + + remove_list_node (listp); + free_INSN_LIST_node (node); + + return elem; +} + +/* Remove and free the first node in the EXPR_LIST pointed to by LISTP. */ +rtx +remove_free_EXPR_LIST_node (rtx *listp) +{ + rtx node = *listp; + rtx elem = XEXP (node, 0); + + remove_list_node (listp); + free_EXPR_LIST_node (node); + + return elem; +} + #include "gt-lists.h"