why fpc do not use a known return function value

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

why fpc do not use a known return function value

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
-----------------------
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Mark Morgan Lloyd-5
misu kun wrote:

> 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]
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Jonas Maebe-2
In reply to this post by misu kun
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_propagation


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

jeppe@j-software.dk
In reply to this post by misu kun

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


------ Oprindelig besked------

Fra: Jonas Maebe

Dato: tir., 3. feb. 2015 10:24

Til: 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  - [hidden email]p://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

misu kun
In reply to this post by Mark Morgan Lloyd-5
thanks ,
 even if you remove c and call test() inside writeln for example,
still the same thing .
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

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 <[hidden email]>:
> thanks ,
>  even if you remove c and call test() inside writeln for example,
> still the same thing .
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

leledumbo
Administrator
In reply to this post by misu kun
> while the same program in c compiled with old version of gcc generate this asm
> which is optimal

mind sharing the C code?
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Jonas Maebe-2
In reply to this post by misu kun
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.


Jonas

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Jonas Maebe-2
In reply to this post by jeppe@j-software.dk
On 03/02/15 11:01, [hidden email] wrote:
> Constant propagation won't work on global variables in fpc because they
> currently are always considered volatile.

The propagation is into the inlined body of the function, not the value
of the global variable 'c' after it has been assigned.


Jonas

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

misu kun
In reply to this post by leledumbo
> mind sharing the C code?

int c ;
int test( int p){
  int i;
  i = p;
  return (i+2+c+2+c+2+c);
}
int main(){
  c = test(128);
}
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Sven Barth-2
In reply to this post by Jonas Maebe-2

Am 03.02.2015 12:13 schrieb "Jonas Maebe" <[hidden email]>:
>
> 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


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Jonas Maebe-2

On 03 Feb 2015, at 14:27, 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

leledumbo
Administrator
In reply to this post by misu kun
> 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.
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Jonas Maebe-2

On 03 Feb 2015, at 15:58, leledumbo wrote:

>> 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Florian Klaempfl
In reply to this post by misu kun
Am 03.02.2015 um 12:25 schrieb misu kun:

>> mind sharing the C code?
>
> int c ;
> int test( int p){
>   int i;
>   i = p;
>   return (i+2+c+2+c+2+c);
> }
> int main(){
>   c = test(128);
> }

I do not see why it is worth trying to optimize such code. No well-written real world program
contains code like this.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Michael Schnell
In reply to this post by misu kun
On 02/03/2015 11:33 AM, 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
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: why fpc do not use a known return function value

Michael Schnell
In reply to this post by Sven Barth-2
On 02/03/2015 02:27 PM, Sven Barth wrote:
> Afterall globals are considered volatile...

... hence a Pascal compiler creating other code would be erroneous.

It might be a good idea to introduce a keyword such as "nonvolatile" to
allow for exactly such optimizations.

-Michael
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal