summaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-13 16:14:55 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2002-06-13 16:14:55 +0000
commit90295bd2e83a3a802eb080cd23c9760a748239de (patch)
tree1e31a85b6ad526e69fcd507891472e959a6541de /gcc/emit-rtl.c
parent61b914265a93af0ff15ab294fa6beb30405dd051 (diff)
downloadgcc-90295bd2e83a3a802eb080cd23c9760a748239de.tar.gz
* emit-rtl.c (static_regno_reg_rtx): Define.
(init_emit_once): Initialize static_regno_reg_rtx. (init_emit): Copy static_regno_reg_rtx into regno_reg_rtx instead of building new hard reg objects once per function. (gen_rtx_REG): Try to share hard regs. * regclass.c (init_fake_stack_mems): New function broken out from init_regs. * rtl.h (init_fake_stack_mems): Declare. * toplev.c (lang_independent_init): Call init_regs before init_emit_once. Call init_fake_stack_mems after init_emit_once. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@54588 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 27a511f0331..5186c854dc3 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -92,6 +92,12 @@ static int no_line_numbers;
rtx global_rtl[GR_MAX];
+/* Commonly used RTL for hard registers. These objects are not necessarily
+ unique, so we allocate them separately from global_rtl. They are
+ initialized once per compilation unit, then copied into regno_reg_rtx
+ at the beginning of each function. */
+static GTY(()) rtx static_regno_reg_rtx[FIRST_PSEUDO_REGISTER];
+
/* We record floating-point CONST_DOUBLEs in each floating-point mode for
the values of 0, 1, and 2. For the integer entries and VOIDmode, we
record a copy of const[012]_rtx. */
@@ -527,6 +533,15 @@ gen_rtx_REG (mode, regno)
return stack_pointer_rtx;
}
+ /* If the per-function register table has been set up, try to re-use
+ an existing entry in that table to avoid useless generation of RTL. */
+ if (cfun
+ && cfun->emit
+ && regno_reg_rtx
+ && regno < FIRST_PSEUDO_REGISTER
+ && reg_raw_mode[regno] == mode)
+ return regno_reg_rtx[regno];
+
return gen_raw_REG (mode, regno);
}
@@ -5067,7 +5082,6 @@ void
init_emit ()
{
struct function *f = cfun;
- int i;
f->emit = (struct emit_status *) ggc_alloc (sizeof (struct emit_status));
first_insn = NULL;
@@ -5098,13 +5112,13 @@ init_emit ()
* sizeof (tree));
/* Put copies of all the hard registers into regno_reg_rtx. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
+ memcpy (regno_reg_rtx,
+ static_regno_reg_rtx,
+ FIRST_PSEUDO_REGISTER * sizeof (rtx));
/* Put copies of all the virtual register rtx into regno_reg_rtx. */
init_virtual_regs (f->emit);
-
/* Indicate that the virtual registers and stack locations are
all pointers. */
REG_POINTER (stack_pointer_rtx) = 1;
@@ -5238,6 +5252,11 @@ init_emit_once (line_numbers)
gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
+ /* Initialize RTL for commonly used hard registers. These are
+ copied into regno_reg_rtx as we begin to compile each function. */
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ static_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
+
#ifdef INIT_EXPANDERS
/* This is to initialize {init|mark|free}_machine_status before the first
call to push_function_context_to. This is needed by the Chill front