Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-02

why fpc do not use a known return function value

17 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

misu kun
Hi
in this program test function has a known return value , and should be
calculated in compile time , but fpc make it in real time !!!
---------------------
program test;
var c : int32;
function test( p: int32): int32; inline;
var i : int32;
begin
  i := p;
  test := i+2+c+2+c+2+c;
end;
begin
  c:= test(128);
end.

---------------------
fpc (3.1.1 i386 ) generate this asm
---------------------
_main:
call FPC_INITIALIZEUNITS
movl $128,%eax
movl U_$P$TEST_$$_C,%eax
addl $130,%eax
addl $2,%eax
addl U_$P$TEST_$$_C,%eax
addl $2,%eax
addl U_$P$TEST_$$_C,%eax
movl %eax,U_$P$TEST_$$_C
call FPC_DO_EXIT
ret
----------------------

while the same program in c compiled with old version of gcc generate this asm which is optimal
------------------------
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
call ___main
movl _c, %eax
leal 134(%eax,%eax,2), %eax
movl %eax, _c
leave
ret
-----------------------

Reply by email

Mark Morgan Lloyd
to misu kun
misu kun wrote 15 lines
Hi in this program test function has a known return value , and should be calculated in compile time , but fpc make it in real time !!! --------------------- program test; var c : int32; function test( p: int32): int32; inline; var i : int32; begin i := p; test := i+2+c+2+c+2+c; end; begin c:= test(128); end.

The initial value of c is undefined. How do you expect the compiler to optimise it?

In the more general case, my recollection is that C has simpler scoping rules, so there may be cases where it can optimise where a Pascal compiler would be more cautious.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Unknown author

Constant propagation won't work on global variables in fpc because they currently are always considered volatile.

------ Oprindelig besked------Fra: Jonas MaebeDato: tir., 3. feb. 2015 10:24Til: FPC-Pascal users discussions;Emne:Re: [fpc-pascal] why fpc do not use a known return function value On 02/02/15 13:56, misu kun wrote:> in this program test function has a known return value , and should be> calculated in compile time , but fpc make it in real time !!!Constant propagation is a new feature in the upcoming FPC release:http://wiki.freepascal.org/FPC_New_Features_Trunk#Constant_propagationJonas_______________________________________________fpc-pascal maillist -

Reply by email

misu kun
to misu kun

i mean even if you initilize c with a const value. i enabled {$optimization constprop} but nothing changed !

2015-02-03 11:19 UTC+01:00, misu kun :

thanks , even if you remove c and call test() inside writeln for example, still the same thing .

Reply by email

Jonas Maebe
to misu kun: i mean even if you initilize c with a const value. i enabled {$optimization constprop}…
misu kun wrote
i mean even if you initilize c with a const value.

That is irrelevant.

i enabled {$optimization constprop} but nothing changed !

I misread the original assembler code you posted, due to how you phrased the subject of your mail. The inline function is actually already completely evaluated at compile time (you probably compiled with -O3 before) and the compiler does use the statically evaluated function return value (rather than calling the function).

It's however true that there appear to be a few missing optimizations to fold the rest of the address calculation, but those are minor.

Jonas

Reply by email

Sven Barth
to Jonas Maebe: That is irrelevant. I misread the original assembler code you posted, due to how you…
"Jonas Maebe" wrote 16 lines
On 03/02/15 11:33, misu kun wrote: > i mean even if you initilize c with a const value. That is irrelevant. > i enabled {$optimization constprop} but nothing changed ! I misread the original assembler code you posted, due to how you phrased the subject of your mail. The inline function is actually already completely evaluated at compile time (you probably compiled with -O3 before) and the compiler does use the statically evaluated function return value (rather than calling the function). It's however true that there appear to be a few missing optimizations to fold the rest of the address calculation, but those are minor.

But three times the addition of "c" will stay, right? Afterall globals are considered volatile...

Regards,
Sven

Reply by email

Jonas Maebe
to Sven Barth
Sven Barth wrote
But three times the addition of "c" will stay, right? Afterall globals are considered volatile...

Yes, you're right. Sorry, especially to Jeppe who had it right from the start. I obviously wasn't thinking straight :/

Jonas

Reply by email

leledumbo
to misu kun: int c ; int test( int p){ int i; i = p; return (i+2+c+2+c+2+c); } int main(){ c =…
Show quoted text 9 lines
int c ; int test( int p){ int i; i = p; return (i+2+c+2+c+2+c); } int main(){ c = test(128); }

Hmm....yes, from C perspective, there's nothing can modify c before it's used the first time (unless you inject the startup code). Therefore, the compiler is safe to assume that c is its initial global value (0) and is able to use constant propagation, with c assumed as constant to reduce the function call into a simple value.

The case with Pascal is not the same, however. Pascal has unit system with initialization section that can inject code before the main block is executed. A unit can extern-ize the variable and modify it in its initialization section. So it's not safe to assume the same thing as C does above. It's not impossible, but would be harder to implement, probably requiring whole program analysis.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/why-fpc-do-not-use-a-known-return-function-value-tp5720901p5720918.html Sent from the Free Pascal - General mailing list .

Reply by email

Jonas Maebe
to leledumbo
leledumbo wrote 19 lines
> int c ; > int test( int p){ > int i; > i = p; > return (i+2+c+2+c+2+c); > } > int main(){ > c = test(128); > } Hmm....yes, from C perspective, there's nothing can modify c before it's used the first time (unless you inject the startup code). Therefore, the compiler is safe to assume that c is its initial global value (0) and is able to use constant propagation, with c assumed as constant to reduce the function call into a simple value.

The assembler code generated for the C program does take into account the initial value of C:

movl _c, %eax
leal 134(%eax,%eax,2), %eax
movl %eax, _c

It could also be modified in a C program before "main" gets executed by e.g. the initialisation code of a dynamic library.

In the end, it's not so much about constant propagation as it is about reordering expressions to be able to fold them better.

Jonas

Reply by email

Michael Schnell
to misu kun: i mean even if you initilize c with a const value. i enabled {$optimization constprop}…
misu kun wrote
i mean even if you initilize c with a const value. i enabled {$optimization constprop} but nothing changed !

(E.g.) another thread could modify on the fly c without the "function test" knowing. Hence it needs to reload c with every usage. In C this is managed by the "volatile" keyword, AFAIK, in Pascal all static variables need to be considered "volatile".

-Michael

Reply by email