public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Creating a wrapper around a function at compile time
@ 2022-07-14 12:38 Erick Ochoa
  2022-07-14 13:27 ` Richard Biener
  0 siblings, 1 reply; 10+ messages in thread
From: Erick Ochoa @ 2022-07-14 12:38 UTC (permalink / raw)
  To: gcc

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-07-15  8:29 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-14 12:38 Creating a wrapper around a function at compile time Erick Ochoa
2022-07-14 13:27 ` Richard Biener
2022-07-14 13:29   ` Richard Biener
2022-07-14 13:46     ` Erick Ochoa
2022-07-14 13:50       ` Richard Biener
2022-07-14 14:08         ` Erick Ochoa
2022-07-14 14:10           ` Martin Liška
2022-07-14 14:25             ` Erick Ochoa
2022-07-15  8:10               ` Martin Liška
2022-07-15  8:33                 ` Erick Ochoa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).