lists.c (unused_insn_list, [...]): New file for maintaining various types of lists.

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
This commit is contained in:
Andrew MacLeod 1999-08-25 17:50:53 +00:00 committed by Andrew Macleod
parent b54480a7e6
commit 5a4f6418af
6 changed files with 219 additions and 125 deletions

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

View 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 \

View File

@ -766,82 +766,6 @@ static void schedule_region PROTO ((int));
#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;

150
gcc/lists.c Normal file
View File

@ -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;
}

View File

@ -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 */

View 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)