•    Free Pascal
• Website
• Downloads
• Wiki
• Bugtracker
• Mailing List
•    Lazarus
• Website
• Downloads (Laz+FPC)
• Packages (OPM)
• FAQ
• Wiki
• Bugtracker
• IRC channel
• Developer Blog
• Follow us on Twitter
• Latest SVN
• Mailing List
• Other languages
•    Foundation
• Website
•    Useful Wiki Links
• Project Roadmap
• Getting the Source
• Screenshots Bookstore Computer Math and Games in Pascal (preview) Lazarus Handbook (preview only) Author Topic: evaluate constant expression at compile time  (Read 617 times)

fcu

• New Member
• • Posts: 41 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. #  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. #  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. #  for i:= 0 to 8 do
2.         movl    \$0,%eax
3.         subl    \$1,%eax
4.         .balign 4,0x90
5. .Lj19:
7. #  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

• New Member
• • Posts: 41 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 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
Most people that want to use threading should learn to patch their jeans first: use a needle.

fcu

• New Member
• • Posts: 41 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: 616
• 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: 1405 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 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]
#  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
#  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: 616
• 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.