Am 08.11.2021 um 03:45 schrieb Ryan Joseph via fpc-pascal:

On Nov 7, 2021, at 2:17 PM, Jonas Maebe via fpc-pascal 
<fpc-pascal@lists.freepascal.org> wrote:

Is there anyway a function parameter could be inlined in FPC? This would go a 
long way in helping to parameterize functions that have tight loops in them.
It's theoretically possible through constant propagation.
I understand simple constant propagation cases but how does this apply to 
inlining entire functions? I think C++ can do this with closures so it's 
something worth looking in to for the future.

This has nothing to do with closures.

Take a look at this:

=== code begin ===

type
  TFunc = function(aArg: LongInt): LongInt;
  TLongIntArray = array of LongInt;

function MultBy2(aArg: LongInt): LongInt; inline;
begin
  Result := aArg * 2;
end;

function Map(aArr: TLongIntArray; aFunc: TFunc): TLongIntArray; inline;
begin
  SetLength(Result, Length(aArr));
  for i := 0 to High(aArr) do
    Result[i] := aFunc(aArr[i]);
end;

var
  l1, l2: TLongIntArray;
begin
  l1 := [1, 2, 3, 4];
  l2 := Map(l1, @MultBy2);
end.

=== code end ===

Assuming constant propagation of function variables would work correctly what would happen in the compiler would be as follows (this is how the compiler already works):

Step 1: Inline Map function

=== code begin ===

// ...

begin
  l1 := [1, 2, 3, 4];
  SetLength(l2, 4);
  for i := 0 to 3 do
    Result[i] := MultBy2(aArr[i]);
end.

=== code end ===

Step 2: Check whether inlining provided new optimization possibilities (which again includes inlining and thus allows inlining of MultBy2!)

=== code begin ===

// ...

begin
  l1 := [1, 2, 3, 4];
  SetLength(l2, 4);
  for i := 0 to 3 do
    Result[i] := aArr[i] * 2;
end.

=== code end ===

And there you have it (simplified obviously). As long as the compiler can determine *at compile time* the code of the function (and the function is inlineable) it should in theory be able to inline it. This is true no matter if it's a function variable, a method variable (pointing to a non-virtual method) or an anonymous function. However if somewhere between passing in the function address and calling the function inlining does not work for one reason or the other (e.g. due to open array parameters which are currently not supported by inlining) then the compiler obviously can't inline the provided function either.

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to