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)
     {

Reply via email to