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
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to