Optimizing the counter code
Summary
I have a simple code checking for a value. In the first test, it does everything in one go, but I want to update the counter an skip some values and report status. If I do the update of "I" in the function, everything is fine, but If I call a function to check even if inline, because of "var" parameter, FPC does not optimize the code. I like to know if this is a proper response of FPC or it is an optimization missed.
This is a very simplified case of the problem, in the real work, I need to change Value of I depending the results. So I can not do it in the main function, and need to call another function for code maintainability.
System Information
Lazarus 2.3.0 (rev main-2_3-1804-g43e385a90b) FPC 3.3.1 x86_64-win64-win32/win64
Example Project
program project1;
uses
Classes,
SysUtils;
function Test1(const Value: array of Integer): Int64;
var
I: Integer;
begin
Result := 0;
I := 0;
repeat
repeat
if Odd(Value[I]) then
Result += 1;
I += 1;
until I = Length(Value);
until True;
end;
function Check(var I: Integer): Boolean; inline;
begin
Result := True;
end;
function Test2(const Value: array of Integer): Int64;
var
I: Integer;
begin
Result := 0;
I := 0;
repeat
repeat
if Odd(Value[I]) then
Result += 1;
I += 1;
until I = Length(Value);
until Check(I);
end;
function Test3(const Value: array of Integer): Int64;
var
I, TempI: Integer;
begin
Result := 0;
I := 0;
repeat
TempI := I;
repeat
if Odd(Value[TempI]) then
Result += 1;
TempI += 1;
until TempI = Length(Value);
I := TempI;
until Check(I);
end;
var
Value: array of Integer;
Tick: QWord;
begin
SetLength(Value, 1000000000);
Tick := GetTickCount64;
Test1(Value);
WriteLn(GetTickCount64 - Tick);
Tick := GetTickCount64;
Test2(Value);
WriteLn(GetTickCount64 - Tick);
Tick := GetTickCount64;
Test3(Value);
WriteLn(GetTickCount64 - Tick);
ReadLn;
end.
What is the current bug behavior?
In this test, Test2 is two times slower as FPC does not use register for I. In Test3, I made a Temp variant to tricked FPC to use register.
More information
https://forum.lazarus.freepascal.org/index.php?topic=59340.0