### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

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

#### fcu

• Jr. Member
• Posts: 64
##### 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
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:
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:
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: 64
##### 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

• Hero Member
• Posts: 10293
##### 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
I am more like donkey than shrek

#### fcu

• Jr. Member
• Posts: 64
##### 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: 1962
• 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: 1641
##### 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: 8244
• 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: 1962
• 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.