[fpc-pascal] Argument evaluation order in Free Pascal and Delphi
Sven Barth
pascaldragon at googlemail.com
Thu Oct 31 10:47:29 CET 2013
Am 31.10.2013 09:45, schrieb Michael Schnell:
> On 10/28/2013 02:47 PM, Dmitry Pribysh wrote:
>> As it is written in Free Pascal wiki
>> <http://wiki.freepascal.org/Code_Conversion_Guide#Order_of_parameter_evaluation>,
>> order of parameter evaluation is not defined in FPC, but it is
>> defined in Delphi (Delphi guarantees left-to-right evaluation order).
>>
> IMHO =in fact evaluation of a parameter should not be guaranteed at all.
>
> The compiler should be free to inline a function, detect that the
> parameter is not necessary for the evaluation of the function result
> and drop the evaluation of the parameter (maybe giving a warning or
> error message if that might trigger side-effects).
1. FPC does not guarantee evaluation order exactly for this reason
2. The compiler already does this inlining already in that way (at least
partially).
Take this code:
=== code begin ===
program tinlinetest;
{$mode objfpc}
function GetStr1: String; inline;
begin
Result := 'Hello World';
end;
function GetStr2: String;
begin
Result := 'Hello World';
end;
function Test(aArg1: Integer; aArg2: String): Integer; inline;
begin
Result := aArg1 * 42;
end;
begin
Writeln(Test(42, 'Hello World'));
Writeln(Test(42, GetStr1));
Writeln(Test(42, GetStr2));
end.
=== code end ===
this will produce this output in the main function (2.7.1 and compiled
with -O2):
=== assembler begin ===
PASCALMAIN:
.globl _main
_main:
# Temps allocated between esp+0 and esp+512
# [20] begin
pushl %ebx
addl $-512,%esp
call FPC_INITIALIZEUNITS
# [21] Writeln(Test(42, 'Hello World'));
// No usage of 'Hello World' constant here
call fpc_get_output
movl %eax,%ebx
movl %ebx,%edx
movl $1764,%ecx
movl $0,%eax
call fpc_write_text_sint
call FPC_IOCHECK
movl %ebx,%eax
call fpc_writeln_end
call FPC_IOCHECK
# [22] Writeln(Test(42, GetStr1));
// here this might be a bug... the compiler inlines GetStr1, but does
not detect that its result is constant and not used...
call fpc_get_output
movl %eax,%ebx
movl $_$TINLINETEST$_Ld1,%ecx
leal 256(%esp),%eax
movl $255,%edx
call fpc_shortstr_to_shortstr
leal 256(%esp),%ecx
movl %esp,%eax
movl $255,%edx
call fpc_shortstr_to_shortstr
movl $1764,%ecx
movl %ebx,%edx
movl $0,%eax
call fpc_write_text_sint
call FPC_IOCHECK
movl %ebx,%eax
call fpc_writeln_end
call FPC_IOCHECK
# [23] Writeln(Test(42, GetStr2));
// here it can not inline GetStr2, because it can not detect whether
GetStr2 is sideeffect free
call fpc_get_output
movl %eax,%ebx
leal 256(%esp),%eax
call P$TINLINETEST_$$_GETSTR2$$SHORTSTRING
leal 256(%esp),%ecx
movl %esp,%eax
movl $255,%edx
call fpc_shortstr_to_shortstr
movl $1764,%ecx
movl %ebx,%edx
movl $0,%eax
call fpc_write_text_sint
call FPC_IOCHECK
movl %ebx,%eax
call fpc_writeln_end
call FPC_IOCHECK
# [24] end.
call FPC_DO_EXIT
addl $512,%esp
popl %ebx
ret
=== assembler end ===
So case 2 could be improved a bit.
And for case 3 it might be interesting to have the compiler mark
functions with additional flags to check whether they are e.g.
"constant" or access memory (aside from parameters) in a writing way,
etc. This *might* improve some optimizations...
Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20131031/6a73a505/attachment.html>
More information about the fpc-pascal
mailing list