"For" loops optimizations proposal [feature]
Original Reporter info from Mantis: lagprogramming
-
Reporter name:
Original Reporter info from Mantis: lagprogramming
- Reporter name:
Description:
Regarding near zero {-1,1} comparisons I think it would be a good idea to consider optimizing the "for" loops.
CASE 1
"for signedvariable:={INITIALVALUE} to -1 do {CODE}" act like
"signedvariable:={INITIALVALUE};
if signedvariable<0 then
repeat
{CODE}
inc(signedvariable);
until signedvariable=0;"
CASE 2
"for signedvariable:={INITIALVALUE} downto 1 do {CODE}" act like
"signedvariable:={INITIALVALUE};
if signedvariable>0 then
repeat
{CODE}
dec(signedvariable);
until signedvariable=0;"
CASE 3
"for unsignedvariable:={INITIALVALUE} downto 1 do {CODE}" act like
"unsignedvariable:={INITIALVALUE};
if unsignedvariable<>0 then
repeat
{CODE}
dec(unsignedvariable);
until unsignedvariable=0;"
{INITIALVALUE} should match the sign of {to -1, downto 1} to optimize these loops.
Results using fpc svn 28896 for the below code
function fordowntoloop(parameter:integer):boolean;
begin
for parameter:=parameter downto 1 do
if (parameter and 1)=0 then exit(true);
result:=false;
end;
.section .text.n_unit1_$_fordowntoloop
longint$$boolean
.balign 16,0x90
.globl UNIT1_$_FORDOWNTOLOOP
LONGINT$$BOOLEAN
.type UNIT1_$_FORDOWNTOLOOP
LONGINT$$BOOLEAN,@Function
UNIT1_$_FORDOWNTOLOOP
LONGINT$$BOOLEAN:
.Lc1:
.Ll1:
# [unit1.pas]
# [33] begin
nop
# Var parameter located in register edi
# Var $result located in register al
# Var parameter located in register edi
.Ll2:
# [34] for parameter:=parameter downto 1 do
cmpl $1,%edi
jl .Lj6
addl $1,%edi
.balign 8,0x90
.Lj7:
subl $1,%edi
.Ll3:
# [35] if (parameter and 1)=0 then exit(true);
movl %edi,%edx
andl $1,%edx
testl %edx,%edx
jne .Lj9
movb $1,%al
jmp .Lj3
.Lj9:
.Ll4:
cmpl $1,%edi
jg .Lj7
.Lj6:
.Ll5:
# [36] result:=false;
movb $0,%al
.Lj3:
# PeepHole Optimization,var9
.Ll6:
# [37] end;
andl $255,%eax
nop
ret
.Lc2:
.Lt1:
.Le0:
.size UNIT1_$_FORDOWNTOLOOP
LONGINTBOOLEAN, .Le0 - UNIT1_
_FORDOWNTOLOOPLONGINT
$BOOLEAN
function ifrepeatloop(parameter:integer):boolean;
begin
parameter:=parameter;//ignored by compiler
if parameter>0 then
repeat
if (parameter and 1)=0 then exit(true);
dec(parameter);
until parameter=0;
result:=false;
end;
.section .text.n_unit1_$_ifrepeatloop
longint$$boolean
.balign 16,0x90
.globl UNIT1_$_IFREPEATLOOP
LONGINT$$BOOLEAN
.type UNIT1_$_IFREPEATLOOP
LONGINT$$BOOLEAN,@Function
UNIT1_$_IFREPEATLOOP
LONGINT$$BOOLEAN:
.Lc3:
.Ll8:
# [40] begin
nop
# Var parameter located in register edi
# Var $result located in register al
# Var parameter located in register edi
.Ll9:
# [42] if parameter>0 then
cmpl $0,%edi
jng .Lj19
.balign 8,0x90
.Lj20:
.Ll10:
# [44] if (parameter and 1)=0 then exit(true);
movl %edi,%edx
andl $1,%edx
testl %edx,%edx
jne .Lj24
movb $1,%al
jmp .Lj14
.Lj24:
.Ll11:
# [45] dec(parameter);
subl $1,%edi
.Ll12:
# [46] until parameter=0;
testl %edi,%edi
jne .Lj20
.Lj19:
.Ll13:
# [47] result:=false;
movb $0,%al
.Lj14:
# PeepHole Optimization,var9
.Ll14:
# [48] end;
andl $255,%eax
nop
ret
.Lc4:
.Lt2:
.Le1:
.size UNIT1_$_IFREPEATLOOP
LONGINTBOOLEAN, .Le1 - UNIT1_
_IFREPEATLOOPLONGINT
$BOOLEAN
procedure TForm1.Button1Click(Sender: TObject);
var r:integer;
begin
for r:=-3 to -1 do fordowntoloop(r);
end;
.section .text.n_unit1_
tform1___
$_button1click$tobject
.balign 16,0x90
.globl UNIT1_
TFORM1___
$_BUTTON1CLICK$TOBJECT
.type UNIT1_
TFORM1___
$_BUTTON1CLICK$TOBJECT,@Function
UNIT1_
TFORM1___
$_BUTTON1CLICK$TOBJECT:
.Lc5:
.Ll16:
# [52] begin
pushq %rbx
nop
.Lc7:
# Var Sender located in register rsi
# Var $self located in register rdi
# Var r located in register ebx
# Var r located in register ebx
.Ll17:
# [53] for r:=-3 to -1 do fordowntoloop(r);
movl $-3,%ebx
subl $1,%ebx
.balign 8,0x90
.Lj33:
addl $1,%ebx
movl %ebx,%edi
call UNIT1_$_FORDOWNTOLOOP
LONGINT$$BOOLEAN
cmpl $-1,%ebx
jl .Lj33
.Ll18:
# [54] end;
popq %rbx
nop
ret
.Lc6:
.Lt3:
.Le2:
.size UNIT1_
TFORM1___
$_BUTTON1CLICKTOBJECT, .Le2 - UNIT1
_TFORM1_
__$_BUTTON1CLICK
TOBJECT
Mantis conversion info:
- Mantis ID: 26925
- Build: 2.7.1 rev 28896