Compiler generates unnecessary moves when using inline methods
Original Reporter info from Mantis: Julian Puhl @jpuhl
-
Reporter name:
Original Reporter info from Mantis: Julian Puhl @jpuhl
- Reporter name:
Description:
This is a simplified example. When you compile the program posted in "Steps To Reproduce" you will get two different assembly codes for the sums, despite of the code being the same:
# [37] Result1 := obj1.Getter1 + obj1.Getter2;
movq U_$P$PROJECT1_$$_ARRAY1(%rip),%rdx
movslq U_$P$PROJECT1_$$_INDEX(%rip),%rax
movss (%rdx,%rax,4),%xmm1
movq U_$P$PROJECT1_$$_ARRAY2(%rip),%rax
movslq U_$P$PROJECT1_$$_INDEX(%rip),%rdx
movss (%rax,%rdx,4),%xmm0
addss %xmm1,%xmm0
# Var Result1 located in register xmm0
# [38] Result2 := array1[index] + array2[index];
movq U_$P$PROJECT1_$$_ARRAY1(%rip),%rcx
movslq U_$P$PROJECT1_$$_INDEX(%rip),%rax
movq U_$P$PROJECT1_$$_ARRAY2(%rip),%rdx
movss (%rcx,%rax,4),%xmm0
addss (%rdx,%rax,4),%xmm0
As you can see, two mov instructions could be avoided. It would be nice if this behaviour could be fixed, since we have a lot of code which relies on the index being within the object (I moved it outside for this example). This code gets executed very often, so it is performance critical.
Steps to reproduce:
program project1;
var
array1: array of Single;
array2: array of Single;
index: Integer;
type
TObj1 = object
function Getter1: Single; inline;
function Getter2: Single; inline;
end;
function TObj1.Getter1: Single;
begin
Result := array1[index];
end;
function TObj1.Getter2: Single;
begin
Result := array2[index];
end;
var
Result1, Result2: Single;
obj1: TObj1;
begin
Result1 := obj1.Getter1 + obj1.Getter2;
Result2 := array1[index] + array2[index];
end.