https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85180

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Simplified testcase:
struct words
{
#define V(n) short word_##n;
#define W(n) V(n)
#define X(n) W(n##0) W(n##1) W(n##2) W(n##3) W(n##4) W(n##5) W(n##6) W(n##7)
W(n##8) W(n##9)
#define Y X(0) X(1) X(2) X(3) X(4) X(5)
  Y
};

static char *pbuf, **pbuf_ptrs;

void
foo (struct words *w)
{
  char *aa = pbuf, **cptr = pbuf_ptrs;

  *cptr = aa;
#undef V
#define V(n) \
  __builtin_sprintf (*(cptr++), "word_" #n " %d ", w->word_##n); \
  *cptr = (aa += __builtin_strlen (aa) + 1);
  Y

  __builtin_sprintf (*(cptr++), " ");
  *cptr = (aa += __builtin_strlen (aa) + 1);
}

void
bar (char *x, char **y)
{
  pbuf = x;
  pbuf_ptrs = y;
}

Infinite recursion is not possible and is not what's going on here, that is
prevented through:
      f = val->locs;
      /* Temporarily reset val->locs to avoid infinite recursion.  */
      val->locs = NULL;
...
      val->locs = f;
in find_base_term.

I think the problem is rather that for PLUS and MINUS we recurse up to twice
(once for each argument) and for VALUEs we can recurse even more times if it
has long locs list, so if we are unlucky it can be exponential, one single
toplevel find_base_term call recursing transitively on a particular VALUE many
times.

Now, I guess caching find_base_term return value for each VALUE (or perhaps
delayed, look up say 20 VALUEs without caching and only then build the cache
and start caching) could be a way out of this, but the val->locs = NULL; hack
above will not be very good for that, because then we might cache a negative
answer even for VALUEs that would yield non-NULL answer if we called
find_base_term for it from the toplevel.  Dunno if that is acceptable or not.

I also wonder if we couldn't (either in new struct cselib_val field or on the
side table) just record find_base_term value (and find_base_value?) of each
VALUE we create when we process the instruction that created the VALUE.  Or is
the find_base_term not meant to be sticky for each VALUE forever and is
supposed to change as further insns are processed (invalidate locs from VALUEs
etc.)?

Reply via email to