Hello,

I'm looking for some help in how to create a new function at compile time /
link time. The idea is an alternative form of constant propagation.

The current implementation of ipa-cp, may specialize functions for which
arguments may be known at compile time. Call graph edges from the caller to
the new specialized functions will replace the old call graph edges from
the caller to the original functions. Call graph edges which have no known
compile time constants will still point to the original unspecialized
function.

I would like to explore a different approach to function specialization.
Instead of only specializing functions which are guaranteed to have a
compile time constant, I would like to also attempt to specialize the edges
which do not have compile time constants with a parameter test. In other
words, for call graph edges with non-constant arguments at compile time,
create a wrapper function around the original function and do a switch
statement around parameters.

For example, let's say we have a function mul, which multiplies two
integers.

int
mul (int a, int b) {
  return a * b;
}

Function mul is called from three different callsites in the whole program:

A: mul (a, 2);
B: mul (b, 4);
C: mul (c, d);

At the moment, ipa-cp might specialize mul into 3 different versions:

// unoptimized original mul
int
mul (int a, int b) {
  return a * b;
}

// optimized for b = 2;
int
mul.constprop1 (int a) {
  // DEBUG b => 2
  return a << 1;
}

// optimized for b = 4;
int
mul.constprop2 (int a) {
  // DEBUG b => 4
  return a << 2;
}

and change the callsites to:

A: mul.constprop1 (a);
B: mul.constprop2 (b);
C: mul (c, d);

I would like instead to do the following:

Create a function mul_test_param

int
mul_test_param (int a, int b) {
  switch (b)
  {
    case 2:
      return mul.constprop1 (a);
      break;
    case 4:
      return mul.constprop2 (a);
      break;
    default:
      return mul (a, b);
      break;
  }
}

The function mul_test_param will test each parameter and then call the
specialized function. The callsites can either be changed to:

A: mul.constprop1 (a);
B: mul.constprop2 (b);
C: mul_test_param (c, d);

or

A: mul_test_param (a, 2);
B: mul_test_param (b, 4);
C: mul_test_param (c, d);

The idea is that there exist some class of functions for which the
parameter test and the specialized version is less expensive than the
original function version. And if, at runtime, d might be a quasi-constant
with a good likelihood of being either 2 or 4, then it makes sense to have
this parameter test.

This is very similar to function tests for making direct to indirect
functions and to what could be done in value profiling.

I already know how to achieve most of this, but I have never created a
function from scratch. That is the bit that is challenging to me at the
moment. Any help is appreciated.

Thanks!

-Erick

Reply via email to