Optimizing out and var parameters
Summary
In this sample code, compiler does not put A and B in registers and it slows the result code. In complicated codebases, this slowdown is significant. The same issue can happen if the parameter is out
or var
, but var
is even slower.
System Information
Lazarus 4.99 (rev 4feac3a6f1) FPC 3.3.1 x86_64-win64-win32/win64
Example Project
program project1;
{$MODE Delphi}
uses
SysUtils;
procedure NextOut(I: integer; out A, B: integer); inline;
begin
A := I + 1;
B := I + 2;
end;
procedure TestOut;
var
I, A, B: integer;
begin
for I := 1 to 1000 * 1000 * 1000 do
NextOut(I, A, B);
end;
procedure NextVar(I: integer; var A, B: integer); inline;
begin
A := I + 1;
B := I + 2;
end;
procedure TestVar;
var
I, A, B: integer;
begin
for I := 1 to 1000 * 1000 * 1000 do
NextVar(I, A, B);
end;
function NextA(I: integer): integer; inline;
begin
Result := I + 1;
end;
function NextB(I: integer): integer; inline;
begin
Result := I + 2;
end;
procedure TestResult;
var
I, A, B: integer;
begin
for I := 1 to 1000 * 1000 * 1000 do
begin
A := NextA(I);
B := NextB(I);
end;
end;
var
T: QWord;
begin
T := GetTickCount64;
TestOut;
WriteLn(GetTickCount64 - T); //359
T := GetTickCount64;
TestVar;
WriteLn(GetTickCount64 - T); //406
T := GetTickCount64;
TestResult;
WriteLn(GetTickCount64 - T); //313
ReadLn;
end.
What is the expected (correct) behavior?
The compiler should optimize the TestOut and TestVar as TestResult.