Lazarus

Free Pascal => General => Topic started by: fcu on June 13, 2019, 11:11:03 am

Title: evaluate constant expression at compile time
Post by: fcu on June 13, 2019, 11:11:03 am
Hi
are there a compiler switches to evaluate constant expression at compile time ?
for example
Code: Pascal  [Select][+][-]
  1. var
  2.  a : array of longint;
  3.  i : longint;
  4. begin
  5.  setlength(a,9);
  6.  for i:= 0 to length(a)-1 do
  7.   a[i] := i;
  8. end.
  9.  

assembler for this code :
Code: Pascal  [Select][+][-]
  1. # [13] for i:= 0 to length(a)-1 do
  2.         movl    U_$P$TEST_$$_A,%eax
  3.         testl   %eax,%eax
  4.         je      .Lj19
  5.         movl    -4(%eax),%eax
  6.         addl    $1,%eax
  7. .Lj19:
  8.         subl    $1,%eax
  9. # Var i located in register edx
  10.         movl    $0,%edx
  11.         cmpl    %edx,%eax
  12.         jl      .Lj21
  13.         subl    $1,%edx
  14.         .balign 4,0x90
  15. .Lj22:
  16.         addl    $1,%edx
  17. # [14] a[i] := i;
  18.         movl    U_$P$TEST_$$_A,%ecx
  19.         movl    %edx,(%ecx,%edx,4)
  20.         cmpl    %edx,%eax
  21.         jg      .Lj22
  22.  

but if you replace length(a)-1 with 8 the assembler would be much simpler
Code: Pascal  [Select][+][-]
  1. # [13] for i:= 0 to 8 do
  2.         movl    $0,%eax
  3.         subl    $1,%eax
  4.         .balign 4,0x90
  5. .Lj19:
  6.         addl    $1,%eax
  7. # [14] a[i] := i;
  8.         movl    U_$P$TEST_$$_A,%edx
  9.         movl    %eax,(%edx,%eax,4)
  10.         cmpl    $8,%eax
  11.         jl      .Lj19
  12.  
Title: Re: evaluate constant expression at compile time
Post by: fcu on June 13, 2019, 11:15:34 am
seems fpc knew that length(a)-1 is 8 at compile time , but the asm generated is not the same as when i replace length(a)-1 with 8
Title: Re: evaluate constant expression at compile time
Post by: Thaddy on June 13, 2019, 11:49:06 am
It also depends on optimization mode. -O-  to -O4
Title: Re: evaluate constant expression at compile time
Post by: fcu on June 13, 2019, 11:51:19 am
it is compiled with -O3
Title: Re: evaluate constant expression at compile time
Post by: PascalDragon on June 14, 2019, 09:21:33 am
are there a compiler switches to evaluate constant expression at compile time ?
The compiler automatically does constant propagation depending on the general optimization switches. However dynamic arrays (for example) are not part of these optimizations.
Title: Re: evaluate constant expression at compile time
Post by: ASerge on June 14, 2019, 04:05:45 pm
Code: Pascal  [Select][+][-]
  1. var
  2.  a : array of longint;
  3.  i : longint;
  4. begin
  5.  setlength(a,9);
  6.  for i:= 0 to length(a)-1 do
  7.   a[i] := i;
  8. end.
Code: Pascal  [Select][+][-]
  1. const
  2.   L = 9;
  3. var
  4.   a: array of LongInt;
  5.   i: LongInt;
  6. begin
  7.   SetLength(a, L);
  8.   for i := 0 to L - 1 do
  9.     a[i] := i;
  10. end.
:)
Title: Re: evaluate constant expression at compile time
Post by: Leledumbo on June 17, 2019, 07:42:19 am
Hi
are there a compiler switches to evaluate constant expression at compile time ?
for example
Code: Pascal  [Select][+][-]
  1. var
  2.  a : array of longint;
  3.  i : longint;
  4. begin
  5.  setlength(a,9);
  6.  for i:= 0 to length(a)-1 do
  7.   a[i] := i;
  8. end.
  9.  
Let's change that a bit:
Code: Pascal  [Select][+][-]
  1. var
  2.  a : array [0 .. 8] of longint;
  3.  i : longint;
  4. begin
  5.  for i:= 0 to length(a)-1 do
  6.   a[i] := i;
  7. end.
  8.  
Code: [Select]
# [5] for i:= 0 to length(a)-1 do
movl $-1,U_$P$PROGRAM_$$_I
.p2align 4,,10
.p2align 3
.Lj3:
movl U_$P$PROGRAM_$$_I,%eax
leal 1(%eax),%eax
movl %eax,U_$P$PROGRAM_$$_I
# [6] a[i] := i;
movl U_$P$PROGRAM_$$_I,%eax
movl U_$P$PROGRAM_$$_I,%edx
movl %edx,U_$P$PROGRAM_$$_A(,%rax,4)
cmpl $8,U_$P$PROGRAM_$$_I
jge .Lj5
jmp .Lj3
Same as you wish? Optimization level 0, btw :) (O3 will activate loop unrolling, totally removing the loop).
Length() is a compiler intrinsic, its implementation depends on type of given data. In static arrays, its replaced directly by a constant. In dynamic arrays, it's located at negative offset of the array (4 bytes to the left to be precise), much like all dynamic strings, hence requires a little computation that can't be replaced by a constant. Check this short programmer's guide (https://www.freepascal.org/docs-html/prog/progsu164.html) page.
Code: Pascal  [Select][+][-]
  1. const
  2.   L = 9;
  3. var
  4.   a: array of LongInt;
  5.   i: LongInt;
  6. begin
  7.   SetLength(a, L);
  8.   for i := 0 to L - 1 do
  9.     a[i] := i;
  10. end.
:)
Wirthian optimization :)
Title: Re: evaluate constant expression at compile time
Post by: PascalDragon on June 17, 2019, 09:00:49 am
Length() is a compiler intrinsic, its implementation depends on type of given data. In static arrays, its replaced directly by a constant. In dynamic arrays, it's located at negative offset of the array (4 bytes to the left to be precise), much like all dynamic strings, hence requires a little computation that can't be replaced by a constant. Check this short programmer's guide (https://www.freepascal.org/docs-html/prog/progsu164.html) page.
Well, for local dynamic arrays the compiler could in theory keep the length of the array in a register as well (as long as the array isn't passed to some other function) and thus generate more optimized code.
TinyPortal © 2005-2018