https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80960
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |rguenth at gcc dot gnu.org --- Comment #25 from Richard Biener <rguenth at gcc dot gnu.org> --- Oh, so it's not actually that plus_constant calls but the ones called via get_addr from true_dependence_1 which is called 60 million times from check_mem_read_use. That does: /* Convert the address X into something we can use. This is done by returning it unchanged unless it is a VALUE or VALUE +/- constant; for VALUE we call cselib to get a more useful rtx. */ rtx get_addr (rtx x) { cselib_val *v; struct elt_loc_list *l; if (GET_CODE (x) != VALUE) { if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS) && GET_CODE (XEXP (x, 0)) == VALUE && CONST_SCALAR_INT_P (XEXP (x, 1))) { rtx op0 = get_addr (XEXP (x, 0)); if (op0 != XEXP (x, 0)) { poly_int64 c; if (GET_CODE (x) == PLUS && poly_int_rtx_p (XEXP (x, 1), &c)) return plus_constant (GET_MODE (x), op0, c); thus undoing the valueization DSE does. Since it unconditionally does this I guess DSE could do it itself instead. That helps tremendously: dead store elim2 : 6.34 ( 11%) 0.02 ( 7%) 6.38 ( 11%) 170M ( 45%) TOTAL : 56.96 0.27 57.26 381M 56.96user 0.29system 0:57.27elapsed 99%CPU (0avgtext+0avgdata 825148maxresident)k 0inputs+0outputs (0major+210372minor)pagefaults 0swaps diff --git a/gcc/dse.c b/gcc/dse.c index c88587e7d94..da0df54a2dd 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -2219,6 +2219,11 @@ check_mem_read_rtx (rtx *loc, bb_info_t bb_info) } if (maybe_ne (offset, 0)) mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset); + /* Avoid passing VALUE RTXen as mem_addr to canon_true_dependence + which will over and over re-create proper RTL and re-apply the + offset above. See PR80960 where we almost allocate 1.6GB of PLUS + RTXen that way. */ + mem_addr = get_addr (mem_addr); if (group_id >= 0) {