Compiler generates unnecessary moves when using inline methods and arithmetic operations
Original Reporter info from Mantis: Julian Puhl @jpuhl
-
Reporter name:
Original Reporter info from Mantis: Julian Puhl @jpuhl
- Reporter name:
Description:
I don't know if I am asking too much from the compiler, but here is another example, where the code gets very inefficient (see "Steps To Reproduce"). I made sure striping out the initializations doesn't affect the code. The code was compiled with -O3.
The resulting code should look like:
# [45] array3[obj1.index] += array1[obj1.index] * array2[obj1.index];
movslq U_$P$PROJECT1_$$_OBJ1(%rip),%rax
movq U_$P$PROJECT1_$$_ARRAY1(%rip),%rcx
movq U_$P$PROJECT1_$$_ARRAY2(%rip),%rdx
movss (%rcx,%rax,4),%xmm0
mulss (%rdx,%rax,4),%xmm0
addss (%r8,%rax,4),%xmm0
movss %xmm0,(%r8,%rax,4)
instead you get for both other cases:
# [46] obj1.Add(obj1.Getter1 * obj1.Getter2);
movq U_$P$PROJECT1_$$_ARRAY1(%rip),%rcx
movslq U_$P$PROJECT1_$$_OBJ1(%rip),%rax
movq U_$P$PROJECT1_$$_ARRAY2(%rip),%rdx
movss (%rcx,%rax,4),%xmm0
mulss (%rdx,%rax,4),%xmm0
movq U_$P$PROJECT1_$$_ARRAY3(%rip),%rdx
movslq U_$P$PROJECT1_$$_OBJ1(%rip),%rax
movss (%rdx,%rax,4),%xmm1
addss %xmm0,%xmm1
movss %xmm1,(%rdx,%rax,4)
# [47] obj1.AddMul(obj1.Getter1, obj1.Getter2);
movq U_$P$PROJECT1_$$_ARRAY2(%rip),%rax
movslq U_$P$PROJECT1_$$_OBJ1(%rip),%rdx
movss (%rax,%rdx,4),%xmm1
movq U_$P$PROJECT1_$$_ARRAY1(%rip),%rdx
movslq U_$P$PROJECT1_$$_OBJ1(%rip),%rax
movss (%rdx,%rax,4),%xmm0
movq U_$P$PROJECT1_$$_ARRAY3(%rip),%rdx
movslq U_$P$PROJECT1_$$_OBJ1(%rip),%rax
mulss %xmm1,%xmm0
addss (%rdx,%rax,4),%xmm0
movss %xmm0,(%rdx,%rax,4)
P.S.: Thanks for fixing my other issue regarding generated assembly code.
Steps to reproduce:
program project1;
var
array1: array of Single;
array2: array of Single;
array3: array of Single;
type
TObj1 = object
function Getter1: Single; inline;
function Getter2: Single; inline;
procedure AddMul(const val1: Single; const val2: Single); inline;
procedure Add(const val: Single); inline;
var
index: Integer;
end;
function TObj1.Getter1: Single;
begin
Result := array1[index];
end;
function TObj1.Getter2: Single;
begin
Result := array2[index];
end;
procedure TObj1.AddMul(const val1: Single; const val2: Single);
begin
array3[index] += val1 * val2;
end;
procedure TObj1.Add(const val: Single);
begin
array3[index] += val;
end;
var
obj1: TObj1;
begin
array3[obj1.index] += array1[obj1.index] * array2[obj1.index];
obj1.Add(obj1.Getter1 * obj1.Getter2);
obj1.AddMul(obj1.Getter1, obj1.Getter2);
end.
Mantis conversion info:
- Mantis ID: 36320
- OS: Windows
- OS Build: 7
- Build: 43504
- Platform: x64
- Version: 3.3.1