Recent

Author Topic: evaluate constant expression at compile time  (Read 2029 times)

fcu

  • Jr. Member
  • **
  • Posts: 89
evaluate constant expression at compile time
« 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.  

fcu

  • Jr. Member
  • **
  • Posts: 89
Re: evaluate constant expression at compile time
« Reply #1 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

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: evaluate constant expression at compile time
« Reply #2 on: June 13, 2019, 11:49:06 am »
It also depends on optimization mode. -O-  to -O4
Specialize a type, not a var.

fcu

  • Jr. Member
  • **
  • Posts: 89
Re: evaluate constant expression at compile time
« Reply #3 on: June 13, 2019, 11:51:19 am »
it is compiled with -O3

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: evaluate constant expression at compile time
« Reply #4 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.

ASerge

  • Hero Member
  • *****
  • Posts: 2222
Re: evaluate constant expression at compile time
« Reply #5 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.
:)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8746
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: evaluate constant expression at compile time
« Reply #6 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 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 :)

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: evaluate constant expression at compile time
« Reply #7 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 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