[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