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

            Bug ID: 77580
           Summary: Improve devirtualization
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wdijkstr at arm dot com
  Target Milestone: ---

A commonly used benchmark contains a hot loop which calls one of 2 virtual
functions via a static variable which is set just before. A reduced example is:

int f1(int x) { return x + 1; }
int f2(int x) { return x + 2; }

static int (*virt)(int);

int f(int *p, int n, int x)
{
  int i;
  if (x > 10)
    virt = f1;
  else
    virt = f2;
  for (i = 0; i < n; i++)
    p[i] = virt (i);
}

This is obviously very stupid code, however GCC could do better. virt is not
address-taken, neither f1 nor f2 make a call, so virt is effectively a local
variable. So the loop could be transformed to p[i] = (x > 10) ? f1 (i) : f2
(i); to enable inlining after which the if can be lifted:

int f_opt(int *p, int n, int x)
{
  int i;
  if (x > 10)
    virt = f1;
  else
    virt = f2;
  if (x > 10)
    for (i = 0; i < n; i++)
      p[i] = f1 (i);
  else
    for (i = 0; i < n; i++)
      p[i] = f2 (i);
}

Reply via email to