<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">Am 31.10.2013 09:45, schrieb Michael
Schnell:<br>
</div>
<blockquote cite="mid:527218A3.5050708@lumino.de" type="cite">
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
<div class="moz-cite-prefix">On 10/28/2013 02:47 PM, Dmitry
Pribysh wrote:<br>
</div>
<blockquote cite="mid:292231382968049@web3m.yandex.ru" type="cite">
<div> </div>
<div>As it is written in Free Pascal <a moz-do-not-send="true"
href="http://wiki.freepascal.org/Code_Conversion_Guide#Order_of_parameter_evaluation">wiki</a>,
order of parameter evaluation is not defined in FPC, but it is
defined in Delphi (Delphi guarantees left-to-right evaluation
order).</div>
<br>
</blockquote>
IMHO =in fact evaluation of a parameter should not be guaranteed
at all. <br>
<br>
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).<br>
</blockquote>
1. FPC does not guarantee evaluation order exactly for this reason<br>
2. The compiler already does this inlining already in that way (at
least partially). <br>
Take this code:<br>
<br>
=== code begin ===<br>
<br>
program tinlinetest;<br>
<br>
{$mode objfpc}<br>
<br>
function GetStr1: String; inline;<br>
begin<br>
Result := 'Hello World';<br>
end;<br>
<br>
function GetStr2: String;<br>
begin<br>
Result := 'Hello World';<br>
end;<br>
<br>
function Test(aArg1: Integer; aArg2: String): Integer; inline;<br>
begin<br>
Result := aArg1 * 42;<br>
end;<br>
<br>
begin<br>
Writeln(Test(42, 'Hello World'));<br>
Writeln(Test(42, GetStr1));<br>
Writeln(Test(42, GetStr2));<br>
end.<br>
<br>
=== code end ===<br>
<br>
this will produce this output in the main function (2.7.1 and
compiled with -O2):<br>
<br>
=== assembler begin ===<br>
<br>
PASCALMAIN:<br>
.globl _main<br>
_main:<br>
# Temps allocated between esp+0 and esp+512<br>
# [20] begin<br>
pushl %ebx<br>
addl $-512,%esp<br>
call FPC_INITIALIZEUNITS<br>
# [21] Writeln(Test(42, 'Hello World'));<br>
// No usage of 'Hello World' constant here<br>
call fpc_get_output<br>
movl %eax,%ebx<br>
movl %ebx,%edx<br>
movl $1764,%ecx<br>
movl $0,%eax<br>
call fpc_write_text_sint<br>
call FPC_IOCHECK<br>
movl %ebx,%eax<br>
call fpc_writeln_end<br>
call FPC_IOCHECK<br>
# [22] Writeln(Test(42, GetStr1));<br>
// here this might be a bug... the compiler inlines GetStr1, but
does not detect that its result is constant and not used...<br>
call fpc_get_output<br>
movl %eax,%ebx<br>
movl $_$TINLINETEST$_Ld1,%ecx<br>
leal 256(%esp),%eax<br>
movl $255,%edx<br>
call fpc_shortstr_to_shortstr<br>
leal 256(%esp),%ecx<br>
movl %esp,%eax<br>
movl $255,%edx<br>
call fpc_shortstr_to_shortstr<br>
movl $1764,%ecx<br>
movl %ebx,%edx<br>
movl $0,%eax<br>
call fpc_write_text_sint<br>
call FPC_IOCHECK<br>
movl %ebx,%eax<br>
call fpc_writeln_end<br>
call FPC_IOCHECK<br>
# [23] Writeln(Test(42, GetStr2));<br>
// here it can not inline GetStr2, because it can not detect
whether GetStr2 is sideeffect free<br>
call fpc_get_output<br>
movl %eax,%ebx<br>
leal 256(%esp),%eax<br>
call P$TINLINETEST_$$_GETSTR2$$SHORTSTRING<br>
leal 256(%esp),%ecx<br>
movl %esp,%eax<br>
movl $255,%edx<br>
call fpc_shortstr_to_shortstr<br>
movl $1764,%ecx<br>
movl %ebx,%edx<br>
movl $0,%eax<br>
call fpc_write_text_sint<br>
call FPC_IOCHECK<br>
movl %ebx,%eax<br>
call fpc_writeln_end<br>
call FPC_IOCHECK<br>
# [24] end.<br>
call FPC_DO_EXIT<br>
addl $512,%esp<br>
popl %ebx<br>
ret<br>
<br>
=== assembler end ===<br>
<br>
So case 2 could be improved a bit.<br>
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...<br>
<br>
Regards,<br>
Sven<br>
</body>
</html>