[fpc-pascal] Inline function parameters

Sven Barth pascaldragon at googlemail.com
Mon Nov 8 07:27:29 CET 2021


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 at 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


More information about the fpc-pascal mailing list