Re: [fpc-devel] Does FPC optimize unused parameters ?
On 26 Aug 2012, at 21:17, Florian Klaempfl wrote: >> That looks like a very serious bug introduced in the handling of >> parameters to inlined routines. Florian changed several things there >> over the last couple of months, maybe he has an idea. > > Yes, r21445 is guilty. para.left should be checked with > might_have_sideeffects if refs=0 if it really could be removed. I've added that, and additionally made this optimization only active if the new -Oodeadvalues optimization switch is used (it's also part of -O4), because it can change the behaviour of code due to the removal of implicit side-effects caused by the original calculation of those parameters (range check errors, segmentation faults, ...). Jonas___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
Am 24.08.2012 13:48, schrieb Jonas Maebe: Martin wrote on Fri, 24 Aug 2012: On 24/08/2012 12:04, Jonas Maebe wrote: Martin wrote on Fri, 24 Aug 2012: The above takes the first of the overloaded. All bodies are empty. procedure DebugLn(const s: string = ''); inline; overload; That looks like a very serious bug introduced in the handling of parameters to inlined routines. Florian changed several things there over the last couple of months, maybe he has an idea. Yes, r21445 is guilty. para.left should be checked with might_have_sideeffects if refs=0 if it really could be removed. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
Martin wrote on Fri, 24 Aug 2012: On 24/08/2012 12:48, Jonas Maebe wrote: That looks like a very serious bug introduced in the handling of parameters to inlined routines. Florian changed several things there over the last couple of months, maybe he has an idea. If he looks at it, maybe a compiler-switch. It could be treated like in bool eval, that might omit calls. Definitely not, as far as I am concerned. Either the compiler can figure it out by itself, or you add an annotation which the compiler then verifies for correctness (like "const" for methods in C++ -- but even this I don't like, because it adds a lot of clutter to the source code, makes people focus way too much on useless micro-optimizations that have to be removed again later because the code changes, and leads only to ever more such annotations), but random annotations that allow you to completely disable safety checks are mainly a very good way to get completely unmaintainable code. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
On 24/08/2012 12:48, Jonas Maebe wrote: Martin wrote on Fri, 24 Aug 2012: On 24/08/2012 12:04, Jonas Maebe wrote: Martin wrote on Fri, 24 Aug 2012: The above takes the first of the overloaded. All bodies are empty. procedure DebugLn(const s: string = ''); inline; overload; That looks like a very serious bug introduced in the handling of parameters to inlined routines. Florian changed several things there over the last couple of months, maybe he has an idea. If he looks at it, maybe a compiler-switch. It could be treated like in bool eval, that might omit calls. But obviously not as default. Anyway, if the behaviour is kept for none function-call params, then it is a nice addition. (Allows me to to my debugln with empty body) ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
Martin wrote on Fri, 24 Aug 2012: On 24/08/2012 12:04, Jonas Maebe wrote: Martin wrote on Fri, 24 Aug 2012: The above takes the first of the overloaded. All bodies are empty. procedure DebugLn(const s: string = ''); inline; overload; That looks like a very serious bug introduced in the handling of parameters to inlined routines. Florian changed several things there over the last couple of months, maybe he has an idea. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
On 24/08/2012 12:04, Jonas Maebe wrote: Martin wrote on Fri, 24 Aug 2012: On 08/08/2012 15:37, Jonas Maebe wrote: Martin wrote on Wed, 08 Aug 2012: Out of curiosity. Is there an optimization like this [removing calculation/load of unused parameters] No. Are you sure? It seems the compiler disagrees with you. I tested with 2.7.1 (updated yesterday): function Foo(s:string): string; begin Result := s; Form1.Caption := s; end; procedure TForm1.FormCreate(Sender: TObject); begin //DebugLn(['abc']); //DebugLn('abc'); DebugLn(foo('abc')); end; The assembler for FormCreate (no optimization used). It even omits the call to "Foo"... How is debugln defined? The above takes the first of the overloaded. All bodies are empty. procedure DebugLn(const s: string = ''); inline; overload; procedure DebugLn(Args: array of const); {inline;} overload; procedure DebugLn(const S: String; Args: array of const); {inline;} overload;// similar to Format(s,Args) procedure DebugLn(const s1, s2: string; const s3: string = ''; const s4: string = ''; const s5: string = ''; const s6: string = ''; const s7: string = ''; const s8: string = ''; const s9: string = ''; const s10: string = ''; const s11: string = ''; const s12: string = ''; const s13: string = ''; const s14: string = ''; const s15: string = ''; const s16: string = ''; const s17: string = ''; const s18: string = ''); inline; overload; ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
Martin wrote on Fri, 24 Aug 2012: On 08/08/2012 15:37, Jonas Maebe wrote: Martin wrote on Wed, 08 Aug 2012: Out of curiosity. Is there an optimization like this [removing calculation/load of unused parameters] No. Are you sure? It seems the compiler disagrees with you. I tested with 2.7.1 (updated yesterday): function Foo(s:string): string; begin Result := s; Form1.Caption := s; end; procedure TForm1.FormCreate(Sender: TObject); begin //DebugLn(['abc']); //DebugLn('abc'); DebugLn(foo('abc')); end; The assembler for FormCreate (no optimization used). It even omits the call to "Foo"... How is debugln defined? Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
On 08/08/2012 15:37, Jonas Maebe wrote: Martin wrote on Wed, 08 Aug 2012: Out of curiosity. Is there an optimization like this [removing calculation/load of unused parameters] No. Are you sure? It seems the compiler disagrees with you. I tested with 2.7.1 (updated yesterday): function Foo(s:string): string; begin Result := s; Form1.Caption := s; end; procedure TForm1.FormCreate(Sender: TObject); begin //DebugLn(['abc']); //DebugLn('abc'); DebugLn(foo('abc')); end; The assembler for FormCreate (no optimization used). It even omits the call to "Foo"... .section .text.n_unit1$_$tform1_$__$$_formcreate$tobject,"x" .balign 16,0x90 .globlUNIT1$_$TFORM1_$__$$_FORMCREATE$TOBJECT UNIT1$_$TFORM1_$__$$_FORMCREATE$TOBJECT: .Lc6: # Temps allocated between ebp-8 and ebp-8 # Register ebp allocated .Ll7: # [42] begin pushl%ebp .Lc8: .Lc9: movl%esp,%ebp .Lc10: subl$8,%esp # Temp -4,4 allocated # Var Sender located at ebp-4 # Temp -8,4 allocated # Var $self located at ebp-8 # Register eax,edx allocated movl%eax,-8(%ebp) # Register eax released movl%edx,-4(%ebp) # Register edx released # Temp -4,4 released # Temp -8,4 released .Ll8: # [46] end; leave # Register ebp released ret .Lc7: .Lt2: .Ll9: # End asmlist al_procedures # Begin asmlist al_globals ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
Martin wrote on Wed, 08 Aug 2012: On 08/08/2012 15:55, Jonas Maebe wrote: {$macro on} {$ifdef debugmsg} {$define CallSendDebug:=SendDebug} {$else} {$define CallSendDebug:=//} {$endif} CallSendDebug('|'); Yes I have seen that, and even the macro for continues lines (if params wrap) But it needs to be declared in each unit (or in an include). The alternative has to be declared on each debug line... Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
On 08/08/2012 15:55, Jonas Maebe wrote: It's possible to do that in a more compact way with a macro (the following is used in a couple of places in the RTL): {$macro on} {$ifdef debugmsg} {$define CallSendDebug:=SendDebug} {$else} {$define CallSendDebug:=//} {$endif} CallSendDebug('|'); Yes I have seen that, and even the macro for continues lines (if params wrap) But it needs to be declared in each unit (or in an include). It doesn't simple come via using a unit. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
On 08/08/2012 15:47, michael.vancann...@wisa.be wrote: On Wed, 8 Aug 2012, Jonas Maebe wrote: (or is it possible? After the body of the called routine has been parsed, it would be possible in theory (with indeed all the caveats the compiler would have to take care of such as side effects -- note that these may include non-obvious side-effects, such as potential overflow exceptions and invalid pointer accesses). You'd need to check the caller routine as well, values for parameters might still be used after the call to the function. Dbg:=SomeCalculatingFunction+' Some message'; DebugLn(Dbg); // If debugln is empty, you don't need dbg for it, so the previous call is not needed. In this case only the reference to the variable (but not the constant) would be dropped. So if the next writeln wasnt there, then the well known note "variable assigned but never read" would be given. Of course this would not help the debugln, except the author could then place the string const directly into the call... Writeln(dbg); // but you need it here. And you don't know what SomeCalculatingFunction may have as side effects. Yes, I did indicate that. function calls can not be removed. Again Except: if a special mode flag was introduced that could toggle this (default off). It is the same as with bool eval Of course, all highly theoretical. I still use ifdefs for debug messages, and have a template to quickly insert : {$ifdef debugmsg}SendDebug('|');{$endif debugmsg} Yes, but it adds a lot of extra text to the source. If therce are frequent debugln calls. - Either the debugln lines get very long, - Or 2 extra lines are added for teh ifdef/endif and that stretches the length of the procedure, and how much fits on a screen Of course the IFDEF does highlight in the IDE telling you where the debugln are But I already have the idea to allow highlighting user specified words (and then all debugln can highlight too) ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
michael.vancanneyt wrote on Wed, 08 Aug 2012: On Wed, 8 Aug 2012, Jonas Maebe wrote: After the body of the called routine has been parsed, it would be possible in theory (with indeed all the caveats the compiler would have to take care of such as side effects -- note that these may include non-obvious side-effects, such as potential overflow exceptions and invalid pointer accesses). You'd need to check the caller routine as well, values for parameters might still be used after the call to the function. There's a difference between not loading/evaluating expressions passed as a parameter, and completely eliminating the program slice that contributed to calculating every value used in the parameter expression. Obviously, the latter has much more stringent requirements. I still use ifdefs for debug messages, and have a template to quickly insert : {$ifdef debugmsg}SendDebug('|');{$endif debugmsg} This way, there is no extra code in my final build. It's possible to do that in a more compact way with a macro (the following is used in a couple of places in the RTL): {$macro on} {$ifdef debugmsg} {$define CallSendDebug:=SendDebug} {$else} {$define CallSendDebug:=//} {$endif} CallSendDebug('|'); Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
Martin wrote on Wed, 08 Aug 2012: That makes me wonder how inlining works? Doesn't inlining need to know the body? Yes. Before the body is known, an "inline" function does not get inlined. That's why units are sometimes recompiled even if you don't change anything, because in case of circular (implementation) unit references, more inline bodies may be known during subsequent compilations. Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
On Wed, 8 Aug 2012, Jonas Maebe wrote: Martin wrote on Wed, 08 Aug 2012: Out of curiosity. Is there an optimization like this [removing calculation/load of unused parameters] No. (or is it possible? After the body of the called routine has been parsed, it would be possible in theory (with indeed all the caveats the compiler would have to take care of such as side effects -- note that these may include non-obvious side-effects, such as potential overflow exceptions and invalid pointer accesses). You'd need to check the caller routine as well, values for parameters might still be used after the call to the function. Dbg:=SomeCalculatingFunction+' Some message'; DebugLn(Dbg); // If debugln is empty, you don't need dbg for it, so the previous call is not needed. Writeln(dbg); // but you need it here. And you don't know what SomeCalculatingFunction may have as side effects. Function SomeCalculatingFunction : String; begin LastKnownAlive:=Now; Result:=DateTimeToStr(LastKnownAlive); end; If the call to this function is optimized away, LastKnownAlive is not updated correctly any more... Of course, all highly theoretical. I still use ifdefs for debug messages, and have a template to quickly insert : {$ifdef debugmsg}SendDebug('|');{$endif debugmsg} This way, there is no extra code in my final build. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
On 08/08/2012 15:37, Jonas Maebe wrote: [removing calculation/load of unused parameters] No. I assumed that... (or is it possible? After the body of the called routine has been parsed, it would be possible in theory (with indeed all the caveats the compiler would have to take care of such as side effects -- note that these may include non-obvious side-effects, such as potential overflow exceptions and invalid pointer accesses). I could have known that. I totally forgot it works on the declaration only. That makes me wonder how inlining works? Doesn't inlining need to know the body? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Does FPC optimize unused parameters ?
Martin wrote on Wed, 08 Aug 2012: Out of curiosity. Is there an optimization like this [removing calculation/load of unused parameters] No. (or is it possible? After the body of the called routine has been parsed, it would be possible in theory (with indeed all the caveats the compiler would have to take care of such as side effects -- note that these may include non-obvious side-effects, such as potential overflow exceptions and invalid pointer accesses). Jonas ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] Does FPC optimize unused parameters ?
Out of curiosity. Is there an optimization like this (or is it possible? procedure Foo(a:String; B: Integer); inline; // inline is optional begin // EMPTY end; This is a plain procedure, not a method, not overloaded, not virtual. And the parameters are both not used in the procedure (But obviously this might also apply for none empty, if params are not used) somewhere else might be Foo('hello world', 1); or Foo('hello world', CalcSomeInt()); At that point it could be known (especially if inlined?) that the params are not used). So the string constant would not be needed in the app. If not inlined, there may still be a need to satisfy calling params ABI or whatever... But if inlined, even the integer wasn't needed. The CalcSomeInt may be wanted of course, for side effcts Of course the question is who would write such code. But actually it happens The LazLoggerDumy unit provides empty inline-able procedures. This allows to write all the debugln in your app without plenty of $IFDEF. Simply change the unit From LazLogger to LazLoggerDumy and logging is gone. Of course it would be nice if FPC could drop as much of the not required params as possible. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel