aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/cselib.c26
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/opt/pr94468.C57
4 files changed, 86 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fdb685a..0221945 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2020-04-04 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/94468
+ * cselib.c (references_value_p): Formatting fix.
+ (cselib_useless_value_p): New function.
+ (discard_useless_locs, discard_useless_values,
+ cselib_invalidate_regno_val, cselib_invalidate_mem,
+ cselib_record_set): Use it instead of
+ v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx).
+
PR debug/94441
* tree-iterator.h (expr_single): Declare.
* tree-iterator.c (expr_single): New function.
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 507898e..256bd78 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -629,8 +629,8 @@ references_value_p (const_rtx x, int only_useless)
int i, j;
if (GET_CODE (x) == VALUE
- && (! only_useless ||
- (CSELIB_VAL_PTR (x)->locs == 0 && !PRESERVED_VALUE_P (x))))
+ && (! only_useless
+ || (CSELIB_VAL_PTR (x)->locs == 0 && !PRESERVED_VALUE_P (x))))
return 1;
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
@@ -646,6 +646,16 @@ references_value_p (const_rtx x, int only_useless)
return 0;
}
+/* Return true if V is a useless VALUE and can be discarded as such. */
+
+static bool
+cselib_useless_value_p (cselib_val *v)
+{
+ return (v->locs == 0
+ && !PRESERVED_VALUE_P (v->val_rtx)
+ && !SP_DERIVED_VALUE_P (v->val_rtx));
+}
+
/* For all locations found in X, delete locations that reference useless
values (i.e. values without any location). Called through
htab_traverse. */
@@ -666,7 +676,7 @@ discard_useless_locs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
p = &(*p)->next;
}
- if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
+ if (had_locs && cselib_useless_value_p (v))
{
if (setting_insn && DEBUG_INSN_P (setting_insn))
n_useless_debug_values++;
@@ -684,7 +694,7 @@ discard_useless_values (cselib_val **x, void *info ATTRIBUTE_UNUSED)
{
cselib_val *v = *x;
- if (v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
+ if (v->locs == 0 && cselib_useless_value_p (v))
{
if (cselib_discard_hook)
cselib_discard_hook (v);
@@ -2370,7 +2380,7 @@ cselib_invalidate_regno_val (unsigned int regno, struct elt_list **l)
}
}
- if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
+ if (had_locs && cselib_useless_value_p (v))
{
if (setting_insn && DEBUG_INSN_P (setting_insn))
n_useless_debug_values++;
@@ -2515,7 +2525,7 @@ cselib_invalidate_mem (rtx mem_rtx)
unchain_one_elt_loc_list (p);
}
- if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx))
+ if (had_locs && cselib_useless_value_p (v))
{
if (setting_insn && DEBUG_INSN_P (setting_insn))
n_useless_debug_values++;
@@ -2593,14 +2603,14 @@ cselib_record_set (rtx dest, cselib_val *src_elt, cselib_val *dest_addr_elt)
REG_VALUES (dreg)->elt = src_elt;
}
- if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx))
+ if (cselib_useless_value_p (src_elt))
n_useless_values--;
new_elt_loc_list (src_elt, dest);
}
else if (MEM_P (dest) && dest_addr_elt != 0
&& cselib_record_memory)
{
- if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx))
+ if (cselib_useless_value_p (src_elt))
n_useless_values--;
add_mem_for_addr (dest_addr_elt, src_elt, dest);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c08bc0d..427266a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2020-04-04 Jakub Jelinek <jakub@redhat.com>
+ PR rtl-optimization/94468
+ * g++.dg/opt/pr94468.C: New test.
+
PR debug/94441
* g++.dg/opt/pr94441.C: New test.
diff --git a/gcc/testsuite/g++.dg/opt/pr94468.C b/gcc/testsuite/g++.dg/opt/pr94468.C
new file mode 100644
index 0000000..bd3f0b5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr94468.C
@@ -0,0 +1,57 @@
+// PR rtl-optimization/94468
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+// { dg-additional-options "-fPIC" { target fpic } }
+
+bool a();
+enum b {};
+class c;
+template <typename> struct d;
+template <class e, typename g, typename... h> struct d<g (e::*)(h...)> {
+ typedef e i;
+};
+struct j { j(void(int, j *, c *, void **, bool *)) {} };
+template <typename l> struct m : public j {
+ l ab;
+ static void ac(int, j *, c *, void **, bool *);
+ m(l f) : j(ac), ab(f) {}
+};
+b ad;
+struct c {
+ template <typename n, typename o>
+ void ae(typename d<n>::i *p, n af, typename d<o>::i *ag, o ah) {
+ ai(p, &af, ag, &ah, new m<o>(ah), ad, &d<n>::i::aj);
+ }
+ void ai(c *, void *, c *, void *, j *, b, int *);
+};
+struct r : public c { static int aj; void t(); };
+struct al : public c {
+ static int aj;
+ void am();
+ void ao();
+ void ap();
+};
+struct aq { aq(const int &, const int & = int()); };
+struct ar : public c { ~ar(); };
+struct as : public ar {
+ as();
+ void at();
+ void au();
+ void av();
+};
+struct u : public c { void ax(); };
+struct ay { int az(); };
+struct ba : public c { static int aj; void bb(); };
+struct bc : public al { bc() { if (a()) am(); } };
+as::as() {
+ al *bd = new bc;
+ ae(bd, &al::ao, this, &as::au);
+ ae(bd, &al::ap, this, &as::av);
+ r be;
+ u bf;
+ ae(&be, &r::t, &bf, &u::ax);
+ c bg = *bd;
+ ae(static_cast<ba *>(&bg), &ba::bb, this, &as::at);
+ ay bh;
+ aq am(bh.az());
+}