On Fri, Apr 03, 2020 at 07:42:10PM +0200, Jakub Jelinek via Gcc-patches wrote: > Or, to avoid the repetitive code, should I introduce > 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))); > } > predicate and use it in those 6 spots?
Here is the patch variant with the above helper. Also bootstrapped/regtested on x86_64-linux and i686-linux. 2020-04-04 Jakub Jelinek <ja...@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). * g++.dg/opt/pr94468.C: New test. --- gcc/cselib.c.jj 2020-04-02 14:28:02.620577679 +0200 +++ gcc/cselib.c 2020-04-03 17:08:54.295282018 +0200 @@ -629,8 +629,8 @@ references_value_p (const_rtx x, int onl 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 onl 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, vo 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, { 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 in } } - 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 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); } --- gcc/testsuite/g++.dg/opt/pr94468.C.jj 2020-04-03 17:16:38.804457422 +0200 +++ gcc/testsuite/g++.dg/opt/pr94468.C 2020-04-03 17:16:18.450756522 +0200 @@ -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()); +} Jakub