summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cselib.c
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2002-09-01 20:38:57 +0000
committerkan <kan@FreeBSD.org>2002-09-01 20:38:57 +0000
commit2e25f3a6c57335cba50111faceb0ce2ab59e9bcb (patch)
treec6857d31c36dbd89a881b0229bf38b062797d413 /contrib/gcc/cselib.c
parent0895e1acb698e05d503c26bec5471de2e88b7d93 (diff)
downloadFreeBSD-src-2e25f3a6c57335cba50111faceb0ce2ab59e9bcb.zip
FreeBSD-src-2e25f3a6c57335cba50111faceb0ce2ab59e9bcb.tar.gz
Gcc 3.2.1-prerelease from the FSF anoncvs repo gcc-3_2-branch on 1-Sep-2002 00:00:01 EDT.
Diffstat (limited to 'contrib/gcc/cselib.c')
-rw-r--r--contrib/gcc/cselib.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/contrib/gcc/cselib.c b/contrib/gcc/cselib.c
index 0eb17b8..b0348fb 100644
--- a/contrib/gcc/cselib.c
+++ b/contrib/gcc/cselib.c
@@ -104,6 +104,10 @@ static int n_useless_values;
static varray_type reg_values;
#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
+/* The largest number of hard regs used by any entry added to the
+ REG_VALUES table. Cleared on each clear_table() invocation. */
+static unsigned int max_value_regs;
+
/* Here the set of indices I with REG_VALUES(I) != 0 is saved. This is used
in clear_table() for fast emptying. */
static varray_type used_regs;
@@ -227,6 +231,8 @@ clear_table (clear_all)
for (i = 0; i < VARRAY_ACTIVE_SIZE (used_regs); i++)
REG_VALUES (VARRAY_UINT (used_regs, i)) = 0;
+ max_value_regs = 0;
+
VARRAY_POP_ALL (used_regs);
htab_empty (hash_table);
@@ -897,6 +903,14 @@ cselib_lookup (x, mode, create)
if (! create)
return 0;
+ if (i < FIRST_PSEUDO_REGISTER)
+ {
+ unsigned int n = HARD_REGNO_NREGS (i, mode);
+
+ if (n > max_value_regs)
+ max_value_regs = n;
+ }
+
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
e->locs = new_elt_loc_list (e->locs, x);
if (REG_VALUES (i) == 0)
@@ -957,11 +971,22 @@ cselib_invalidate_regno (regno, mode)
pseudos, only REGNO is affected. For hard regs, we must take MODE
into account, and we must also invalidate lower register numbers
if they contain values that overlap REGNO. */
- endregno = regno + 1;
if (regno < FIRST_PSEUDO_REGISTER && mode != VOIDmode)
- endregno = regno + HARD_REGNO_NREGS (regno, mode);
+ {
+ if (regno < max_value_regs)
+ i = 0;
+ else
+ i = regno - max_value_regs;
- for (i = 0; i < endregno; i++)
+ endregno = regno + HARD_REGNO_NREGS (regno, mode);
+ }
+ else
+ {
+ i = regno;
+ endregno = regno + 1;
+ }
+
+ for (; i < endregno; i++)
{
struct elt_list **l = &REG_VALUES (i);
@@ -1171,6 +1196,14 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
if (REG_VALUES (dreg) == 0)
VARRAY_PUSH_UINT (used_regs, dreg);
+ if (dreg < FIRST_PSEUDO_REGISTER)
+ {
+ unsigned int n = HARD_REGNO_NREGS (dreg, GET_MODE (dest));
+
+ if (n > max_value_regs)
+ max_value_regs = n;
+ }
+
REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
if (src_elt->locs == 0)
n_useless_values--;
OpenPOWER on IntegriCloud