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.