r17-629-g582adc3c97b1e0 shrank cselib_val::hash to 30 bits in order
to free up two bits for new flags. However, I hadn't realised that
cselib_hash_rtx uses zero as an error return and so requires the hash
to be nonzero. In the PR, trimming the hash to 30 bits had the effect
of dropping the only nonzero bits, leading cselib_lookup_1 to fail even
when the "create" parameter was true.
Rather than fight against the system, it seemed better to restore the
hash to 32 bits and get the space another way: by moving the uid field
from cselib_val to the u2 field of the VALUE rtx. This slightly
complicates some uses and slightly simplifies others.
There is currently a 1:1 mapping between VALUEs and cselib_vals.
The only time val_rtx is set is in new_cselib_val:
e->val_rtx = (rtx_def*) value_pool.allocate ();
and the only times CSELIB_VAL_PTR is set are in new_cselib_val:
CSELIB_VAL_PTR (e->val_rtx) = e;
and discard_useless_values:
CSELIB_VAL_PTR (v->val_rtx) = NULL;
If in future we allowed multiple VALUEs to point to the same cselib_val
(e.g. for canonical_cselib_val), we would need to copy CSELIB_VAL_UID at
the same time as copying CSELIB_VAL_PTR.
Bootstrapped & regression-tested on x86_&4-linux-gnu, powerpc64le-linux-gnu
and aarch64-linux-gnu. OK to install?
Richard
gcc/
PR debug/126169
* rtl.h (rtx_def::u2): Add value_uid to the union.
(CSELIB_VAL_UID): New macro.
* cselib.h (cselib_val::HASH_MASK): Delete.
(cselib_val::hash): Restore to a full int.
(cselib_val::uid): Delete.
(canonical_cselib_val): Use CSELIB_VAL_UID instead of cselib_val::uid.
* alias.cc (refs_newer_value_p): Likewise.
* dse.cc (canon_address): Likewise.
* print-rtl.cc (rtx_writer::print_rtx_operand_code_0): Likewise.
* var-tracking.cc (dv_uid, canon_value_cmp): Likewise.
(variable_post_merge_new_vals): Likewise.
* cselib.cc (new_elt_loc_list, new_cselib_val): Likewise.
(cselib_lookup): Likewise.
(cselib_find_slot): Remove use of cselib_val::HASH_MASK.
---
gcc/alias.cc | 4 +-
gcc/cselib.cc | 13 +++---
gcc/cselib.h | 10 +----
gcc/dse.cc | 2 +-
gcc/print-rtl.cc | 2 +-
gcc/rtl.h | 7 +++
gcc/testsuite/gcc.dg/pr126169.c | 80 +++++++++++++++++++++++++++++++++
gcc/var-tracking.cc | 8 ++--
8 files changed, 104 insertions(+), 22 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/pr126169.c
diff --git a/gcc/alias.cc b/gcc/alias.cc
index 92c9d8bc360..abba2dd9f82 100644
--- a/gcc/alias.cc
+++ b/gcc/alias.cc
@@ -2274,10 +2274,10 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base,
static bool
refs_newer_value_p (const_rtx expr, rtx v)
{
- int minuid = CSELIB_VAL_PTR (v)->uid;
+ int minuid = CSELIB_VAL_UID (v);
subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (iter, array, expr, NONCONST)
- if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid >= minuid)
+ if (GET_CODE (*iter) == VALUE && CSELIB_VAL_UID (*iter) >= minuid)
return true;
return false;
}
diff --git a/gcc/cselib.cc b/gcc/cselib.cc
index 1889083517e..3e48fe5dcb0 100644
--- a/gcc/cselib.cc
+++ b/gcc/cselib.cc
@@ -360,14 +360,15 @@ new_elt_loc_list (cselib_val *val, rtx loc)
if (val->val_rtx == loc)
return;
- else if (val->uid > loc_val->uid)
+ else if (CSELIB_VAL_UID (val->val_rtx) > CSELIB_VAL_UID (loc))
{
/* Reverse the insertion. */
new_elt_loc_list (loc_val, val->val_rtx);
return;
}
- gcc_checking_assert (val->uid < loc_val->uid);
+ gcc_checking_assert (CSELIB_VAL_UID (val->val_rtx)
+ < CSELIB_VAL_UID (loc));
if (loc_val->locs)
{
@@ -658,7 +659,6 @@ cselib_find_slot (machine_mode mode, rtx x, hashval_t hash,
{
cselib_val **slot = NULL;
cselib_hasher::key lookup = { mode, x, memmode };
- hash &= cselib_val::HASH_MASK;
if (cselib_preserve_constants)
slot = cselib_preserved_hash_table->find_slot_with_hash (&lookup, hash,
NO_INSERT);
@@ -1683,7 +1683,6 @@ new_cselib_val (hashval_t hash, machine_mode mode, rtx x)
e->hash = hash;
e->in_preserved_table_p = false;
e->all_locs_preserved_p = false;
- e->uid = next_uid++;
/* We use an alloc pool to allocate this RTL construct because it
accounts for about 8% of the overall memory usage. We know
precisely when we can have VALUE RTXen (when cselib is active)
@@ -1694,6 +1693,7 @@ new_cselib_val (hashval_t hash, machine_mode mode, rtx x)
PUT_CODE (e->val_rtx, VALUE);
PUT_MODE (e->val_rtx, mode);
CSELIB_VAL_PTR (e->val_rtx) = e;
+ CSELIB_VAL_UID (e->val_rtx) = next_uid++;
e->addr_list = 0;
e->locs = 0;
e->next_containing_mem = 0;
@@ -1721,7 +1721,8 @@ new_cselib_val (hashval_t hash, machine_mode mode, rtx x)
if (dump_file && (dump_flags & TDF_CSELIB))
{
- fprintf (dump_file, "cselib value %u:%u ", e->uid, hash);
+ fprintf (dump_file, "cselib value %u:%u ",
+ CSELIB_VAL_UID (e->val_rtx), hash);
if (flag_dump_noaddr || flag_dump_unnumbered)
fputs ("# ", dump_file);
else
@@ -2571,7 +2572,7 @@ cselib_lookup (rtx x, machine_mode mode,
fputs ("cselib lookup ", dump_file);
print_inline_rtx (dump_file, x, 2);
fprintf (dump_file, " => %u:%u\n",
- ret ? ret->uid : 0,
+ ret ? CSELIB_VAL_UID (ret->val_rtx) : 0,
ret ? ret->hash : 0);
}
diff --git a/gcc/cselib.h b/gcc/cselib.h
index df7771e030e..6493303f7ff 100644
--- a/gcc/cselib.h
+++ b/gcc/cselib.h
@@ -23,11 +23,8 @@ along with GCC; see the file COPYING3. If not see
/* Describe a value. */
struct cselib_val
{
- /* A mask equivalent of HASH's bitfield width. */
- static const unsigned int HASH_MASK = 0x3fffffff;
-
/* The hash value. */
- unsigned int hash : 30;
+ unsigned int hash;
/* True if this value is entered in cselib_preserved_hash_table. */
unsigned int in_preserved_table_p : 1;
@@ -36,9 +33,6 @@ struct cselib_val
to be a preserved value. */
unsigned int all_locs_preserved_p : 1;
- /* A unique id assigned to values. */
- int uid;
-
/* A VALUE rtx that points back to this structure. */
rtx val_rtx;
@@ -130,7 +124,7 @@ canonical_cselib_val (cselib_val *val)
if (!val->locs || val->locs->next
|| !val->locs->loc || GET_CODE (val->locs->loc) != VALUE
- || val->uid < CSELIB_VAL_PTR (val->locs->loc)->uid)
+ || CSELIB_VAL_UID (val->val_rtx) < CSELIB_VAL_UID (val->locs->loc))
return val;
canon = CSELIB_VAL_PTR (val->locs->loc);
diff --git a/gcc/dse.cc b/gcc/dse.cc
index 847a8ff148a..68e6dd136f9 100644
--- a/gcc/dse.cc
+++ b/gcc/dse.cc
@@ -1220,7 +1220,7 @@ canon_address (rtx mem,
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, " varying cselib base=%u:%u offset = ",
- (*base)->uid, (*base)->hash);
+ CSELIB_VAL_UID ((*base)->val_rtx), (*base)->hash);
print_dec (*offset, dump_file);
fprintf (dump_file, "\n");
}
diff --git a/gcc/print-rtl.cc b/gcc/print-rtl.cc
index 0c18a994209..8123e2abe80 100644
--- a/gcc/print-rtl.cc
+++ b/gcc/print-rtl.cc
@@ -319,7 +319,7 @@ rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx
ATTRIBUTE_UNUSED,
{
cselib_val *val = CSELIB_VAL_PTR (in_rtx);
- fprintf (m_outfile, " %u:%u", val->uid, val->hash);
+ fprintf (m_outfile, " %u:%u", CSELIB_VAL_UID (in_rtx), val->hash);
dump_addr (m_outfile, " @", in_rtx);
dump_addr (m_outfile, "/", (void*)val);
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 747d917ecf2..e0311189db4 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -426,6 +426,9 @@ struct GTY((desc("0"), tag("0"),
HOST_WIDE_INTs in the hwivec_def. */
unsigned int num_elem;
+ /* The unique identifier of a VALUE rtx. */
+ int value_uid;
+
/* Information about a CONST_VECTOR. */
struct
{
@@ -1625,6 +1628,10 @@ jump_table_for_label (const rtx_code_label *label)
This is a "struct cselib_val", see cselib.h. */
#define CSELIB_VAL_PTR(RTX) X0CSELIB (RTX, 0)
+/* A VALUE's unique identifier. */
+#define CSELIB_VAL_UID(RTX) \
+ RTL_FLAG_CHECK1 ("CSELIB_VAL_UID", (RTX), VALUE)->u2.value_uid
+
/* Holds a list of notes on what this insn does to various REGs.
It is a chain of EXPR_LIST rtx's, where the second operand is the
chain pointer and the first operand is the REG being described.
diff --git a/gcc/testsuite/gcc.dg/pr126169.c b/gcc/testsuite/gcc.dg/pr126169.c
new file mode 100644
index 00000000000..ed3e14a8ad1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr126169.c
@@ -0,0 +1,80 @@
+/* { dg-options "-O3 -w -g" } */
+/* { dg-additional-options "-fPIC" { target fpic } } */
+
+extern float fmodf(float, float);
+float b, c;
+long h, i, k, *ab;
+char j;
+short m;
+static __attribute__((noinline)) int a(int n, int p2) {
+ static int d[6];
+ for (int e = 0; e < 256; ++e)
+ d[e] = e;
+ int f = n;
+ f = d[f ^ p2];
+ return f;
+}
+int g(double, char) { return 0; }
+void l(long n, int p2, char p) {
+ long o = 1, q, *t;
+ int r = 1, s;
+ ab = &o;
+ k = r = k;
+ if (0 >= p)
+ goto u;
+ goto v;
+u:
+ r = n - o;
+ if ((9142 ^ r) >= 90 + r)
+ goto ac;
+ r = k ? k : 9039991.125f;
+ if (__builtin_isfinite(c))
+ __builtin_trap();
+ if (905969534 + (p << 24) < o)
+ goto v;
+ac:
+ q = -o;
+ m = 6 - (p << 6);
+ if (q + 1073741825 ^ o + 7 & q)
+ goto af;
+ goto ae;
+af:
+ if (__builtin_isfinite(c))
+ __builtin_trap();
+ *ab = 5 + o;
+ if (p2)
+ goto u;
+ if (__builtin_isfinite(b / b))
+ __builtin_trap();
+ c = 0 + fmodf(b, b);
+ if (o < n)
+ goto ag;
+ if (h)
+ goto af;
+ae:
+ *t = k - 10992403549608;
+ q = 21285390711 * o - 403452967995;
+ if (q)
+ goto ah;
+ goto ai;
+ah:
+ k = h + h % 490681911 - *t % 9283091488;
+ r = (int)(o >> 4) - 1321465791 - -2057527364 + 724134559;
+ if (p)
+ goto ai;
+ag:
+ *t = j = g(0, p) ?: 81;
+ r = h;
+ if ((5275004732 | q - 80545797) - 9 / o)
+ goto ai;
+v:
+ m = r = b;
+ai:
+ s = q >> 4;
+ a(s, m);
+ s = a(s, 0);
+ s = a(s, r);
+ a(s, b);
+ s = (long)p2 >> a(s, p);
+ a(s, i);
+}
diff --git a/gcc/var-tracking.cc b/gcc/var-tracking.cc
index 31a9404c0a2..e54f9247888 100644
--- a/gcc/var-tracking.cc
+++ b/gcc/var-tracking.cc
@@ -452,7 +452,7 @@ static inline dvuid
dv_uid (decl_or_value dv)
{
if (dv_is_value_p (dv))
- return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
+ return CSELIB_VAL_UID (dv_as_value (dv));
else
return DECL_UID (dv_as_decl (dv));
}
@@ -1723,8 +1723,7 @@ shared_hash_find (shared_hash *vars, decl_or_value dv)
static inline bool
canon_value_cmp (rtx tval, rtx cval)
{
- return !cval
- || CSELIB_VAL_PTR (tval)->uid < CSELIB_VAL_PTR (cval)->uid;
+ return !cval || CSELIB_VAL_UID (tval) < CSELIB_VAL_UID (cval);
}
static bool dst_can_be_shared;
@@ -4531,7 +4530,8 @@ variable_post_merge_new_vals (variable **slot,
dfset_post_merge *dfpm)
if (dump_file)
fprintf (dump_file,
"Created new value %u:%u for reg %i\n",
- v->uid, v->hash, REGNO (node->loc));
+ CSELIB_VAL_UID (v->val_rtx), v->hash,
+ REGNO (node->loc));
}
var_reg_decl_set (*dfpm->permp, node->loc,
--
2.54.0