Lazarus

Free Pascal => FPC development => Topic started by: Ñuño_Martínez on July 13, 2020, 09:53:57 pm

Title: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on July 13, 2020, 09:53:57 pm
I've found that any INLINE subroutine isn't inlined anymore, no matter if I use the -Si option or not.

This seems to be a bug, actually I've found bug 37241 (https://bugs.freepascal.org/view.php?id=37241) that seems similar but it says that it raises an internal error and that it is fixed in 3.2.0 but that's the compiler I'm using and it is not fixed (by the way I found Bug Tracker quite confusing).

Not sure what to do: Is it a feature or a bug? Is it fixed? Is it a new one?
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Bart on July 13, 2020, 10:25:11 pm
AFAIK "inline" does not guarantee that the compiler actually inlines the function.
It merely treats it as a request to inline, if it sees fit.

Bart
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: winni on July 13, 2020, 10:31:37 pm
Hi!

Yes, Bart is right: Every inline instruction is only a question to the compiler if it can do.

But when this is not possible a hint is shown like "open array not yet supported"  or "nested procedures not yet supported".

Winni
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Martin_fr on July 13, 2020, 11:37:05 pm
About the bug tracker:

"Product version" is the version in which the reporter found the bug. Or in which it the developper confirmed it. In short: the version with the bug.

There should be a field "Fixed in Version", but mantis has its own issues and it is not visible.
If it was set, it can be seen in the "issue history" at the bottom.  Also, if it is set, its usually set to trunk (e.g. here fpc 3.3.1) or indicate the hope of the developer to get the fix copied to an earlier release.
In this issue it is not set.

The same for FpcTarget or LazTarget fields.

---
Note "copied to an earlier release"
All developers work on "trunk". Therefore all fixes are first made to trunk.
If
- a developer believes the fix should be made available before the next major release (in this case the next major fpc release is 3.4)
- and there is an earlier release (either an already branched major release, like 3.2 was / or a minor release like 3.2.2 will be)
then the developer will initiate the "merge process" for this.
This means if possible the fix will be copied to that earlier release.

The only sure way to find out what happened to the fix, is the revision number.
With that you can find the fix in SVN.
You can download it as patch, and apply yourself.
You can search the "svn fixes" branches, and see if the revision was merged.
You do not know if it maybe will still be merged. For that you have to ask on the mailing list.

Sorry this is still a lot to take in. But that is the development process. (well approximately)
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: PascalDragon on July 14, 2020, 10:12:35 am
I've found that any INLINE subroutine isn't inlined anymore, no matter if I use the -Si option or not.

This seems to be a bug, actually I've found bug 37241 (https://bugs.freepascal.org/view.php?id=37241) that seems similar but it says that it raises an internal error and that it is fixed in 3.2.0 but that's the compiler I'm using and it is not fixed (by the way I found Bug Tracker quite confusing).

Not sure what to do: Is it a feature or a bug? Is it fixed? Is it a new one?

Before 3.2 the compiler did not report if it did not inline a function that was marked as inline. It simply didn't do it. Now it does report that and more often than not even with a reason. This way one can see what is really inlined and what is not.

One common reason (especially if no other reason was given) is that the function or method body has not yet been parsed (another reason are methods using inherited). Look at the following:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2.  
  3. type
  4.   TTest = class
  5.     procedure MethodA; inline;
  6.     procedure MethodB;
  7.     procedure MethodC;
  8.   end;
  9.  
  10. procedure TTest.MethodB;
  11. begin
  12.   MethodA; // "call not inlined"
  13. end;
  14.  
  15. procedure TTest.MethodA;
  16. begin
  17. end;
  18.  
  19. procedure TTest.MethodC;
  20. begin
  21.   MethodA; // no warning
  22. end;
  23.  
  24. begin
  25. end.

About the bug tracker:

"Product version" is the version in which the reporter found the bug. Or in which it the developper confirmed it. In short: the version with the bug.

There should be a field "Fixed in Version", but mantis has its own issues and it is not visible.
If it was set, it can be seen in the "issue history" at the bottom.  Also, if it is set, its usually set to trunk (e.g. here fpc 3.3.1) or indicate the hope of the developer to get the fix copied to an earlier release.
In this issue it is not set.

The same for FpcTarget or LazTarget fields.

It seems that the bug reporter themselves closed the issue instead of us resolving it with maybe some revision number that originally fixed the issue. Thus this bug report might fly under the radar and we don't merge anything... :'(
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on July 14, 2020, 12:05:24 pm
But anyway compiler should tell why it didn't inline inlined subroutines so they may be fixed or if it isn't possible to remove the INLINE keyword, shouldn't it?

Anyway I've revised all my INLINE subroutines and I can't see why they cannot be inlined.  For example, why next code can't be inlined?  I don't think it is just because it isn't parsed yet because it is used by several units, and units are parsed before they're used, aren't they?

Code: Pascal  [Select][+][-]
  1. (* Find game state. *)
  2.   FUNCTION TmngGameStateManager.FindState (aName: STRING): TmngGameState;
  3.   VAR
  4.     lNdx: INTEGER;
  5.   BEGIN
  6.     lNdx := SELF.IndexOfState (aName);
  7.     IF lNdx < 0 THEN
  8.       RAISE mngGameStateNotFoundException.CreateFmt (STATE_NOT_FOUND, [aName]);
  9.     RESULT := TmngGameState (fStates[lNdx])
  10.   END;

...
Thanks for the explanation.  I still find it confusing but I have a better view about what happens.
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Renat.Su on July 14, 2020, 12:29:20 pm
There are always too many same hints in the compiler message list after compilation. And it is unknown how to fix it. I have to search for the necessary hints through an infinite number of such hints
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Thaddy on July 14, 2020, 12:36:58 pm
It is quite easy to turn them off, e.g:
Code: Pascal  [Select][+][-]
  1. {$push}{$warn 5024 off}//some code that causes hint note or warning{$pop}
I explained that in the wiki a few years ago.
Note this 5024 is another one, not the inline one. But you can obtain the correct number by compilng with -vwnhel
Using the -v<w,h,n><xxx>- switch you can also do it globally (not recommended)
See the wiki:
https://wiki.freepascal.org/Turn_warnings_and_hints_on_or_off
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Renat.Su on July 14, 2020, 12:46:22 pm
It is quite easy to turn them off, e.g:
Code: Pascal  [Select][+][-]
  1. {$push}{$warn 5024 off}//some code that causes hint note or warning{$pop}
I explained that in the wiki a few years ago.
It is not worksing:
Code: Pascal  [Select][+][-]
  1. {$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined}
This does not works too
Code: Pascal  [Select][+][-]
  1. {$push}{$warn 5024 off}//some code that causes hint note or warning{$pop}
This does not works too for the entire project -vm3123 also
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Renat.Su on July 14, 2020, 12:47:46 pm
In all other cases, the hiding of hints works. I use it actively
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Thaddy on July 14, 2020, 12:48:10 pm
See https://wiki.freepascal.org/Turn_warnings_and_hints_on_or_off as I wrote. It DOES work with notes too... If it doesn't file a bug report about the note

(I just see that my wiki entry is heavily vandalized by a beginner and I will restore the missing parts)
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Renat.Su on July 14, 2020, 12:51:35 pm
See https://wiki.freepascal.org/Turn_warnings_and_hints_on_or_off as I wrote. It DOES work with notes too... If it doesn't file a bug report about the note
It works only via porject properties form interface (check off the options)
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Thaddy on July 14, 2020, 12:56:12 pm
See my last remark: the wiki was cpmplete and correct but is vandalized by nitwits. ( Huntingkashket contribs will be reversed by me )
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Renat.Su on July 14, 2020, 01:32:05 pm
See my last remark: the wiki was cpmplete and correct but is vandalized by nitwits. ( Huntingkashket contribs will be reversed by me )
Ok. Thanks
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: PascalDragon on July 14, 2020, 02:09:53 pm
But anyway compiler should tell why it didn't inline inlined subroutines so they may be fixed or if it isn't possible to remove the INLINE keyword, shouldn't it?

Anyway I've revised all my INLINE subroutines and I can't see why they cannot be inlined.  For example, why next code can't be inlined?  I don't think it is just because it isn't parsed yet because it is used by several units, and units are parsed before they're used, aren't they?

Is the hint triggered when called in a different unit or the same unit? If the same unit, then see my example: if you want FindState to be inlined then any callsite inside the same unit needs to be after FindState.

Other possibility: is STATE_NOT_FOUND global or local to the unit?
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on July 24, 2020, 11:50:08 am
I understand why the compiler isn't able in some cases, but anyway there should be a way to fix it;  maybe 2 pass compilation although I understand it isn't feasible without rewriting most of the compiler (IIRC current compilation is done in a single pass).  Anyway it is quite annoying.

Is the hint triggered when called in a different unit or the same unit? If the same unit, then see my example: if you want FindState to be inlined then any callsite inside the same unit needs to be after FindState.

Other possibility: is STATE_NOT_FOUND global or local to the unit?

Sometimes in the same unit, some times in other units.

Fixing the "same unit" the way you said is a mess, as I have the implementation in same order than the interface declarations, wich is helpful for maintenance.  So changing that...  Not sure but I think I have hundred methods in the engine and several docens in Allegro.pas.  :(

What about the other units?
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: PascalDragon on July 24, 2020, 12:19:56 pm
I understand why the compiler isn't able in some cases, but anyway there should be a way to fix it;  maybe 2 pass compilation although I understand it isn't feasible without rewriting most of the compiler (IIRC current compilation is done in a single pass).  Anyway it is quite annoying.

No, that won't be changed. If it is inside a single unit it's up to the user that their code is ordered correctly to allow inlining (at least if nothing else blocks inlining, e.g. inherited or open array arguments). Cross-unit that part isn't important anyway.

Is the hint triggered when called in a different unit or the same unit? If the same unit, then see my example: if you want FindState to be inlined then any callsite inside the same unit needs to be after FindState.

Other possibility: is STATE_NOT_FOUND global or local to the unit?

Sometimes in the same unit, some times in other units.

Fixing the "same unit" the way you said is a mess, as I have the implementation in same order than the interface declarations, wich is helpful for maintenance.  So changing that...  Not sure but I think I have hundred methods in the engine and several docens in Allegro.pas.  :(

What about the other units?

As said above if it's about cross-unit inline then the order is not important, but other things might be. Thus I ask again: is STATE_NOT_FOUND declared globally or locally? And is it used in a function that is declared as inline and is available from the interface section of the unit?
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on July 25, 2020, 11:05:15 am
As said above if it's about cross-unit inline then the order is not important, but other things might be. Thus I ask again: is STATE_NOT_FOUND declared globally or locally? And is it used in a function that is declared as inline and is available from the interface section of the unit?
STATE_NOT_FOUND is a RESOURCESTRING declared in the IMPLEMENTATION section.  It is used by two methods, one declared as INLINE, the other isn't.  The INLINE method is used by other units only (and never inlined).
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: PascalDragon on July 26, 2020, 11:08:08 pm
Then there is the problem. FPC < 3.3.1 does not support inlining functions from another unit that use local symbols. That was only implemented at the beginning of the year by Jonas, but it's too invasive to merge back to 3.2. If you want inlining to work for such functions then all symbols need to be available in the interface section.
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on July 27, 2020, 11:24:20 am
Well, I planed to remove all RESOURCESTRINGS since I'll change the way it uses strings.  Anyway project is still in alpha status.  ::)

Thanks for the tips. :)
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on August 14, 2020, 12:26:34 pm
Quite annoying, but I still don't understand.  Next method is marked as INLINE but it isn't:
Code: Pascal  [Select][+][-]
  1. (* Clears event queue. *)
  2.   PROCEDURE TmngEventManager.Clear;
  3.   BEGIN
  4.     IF NOT SELF.IsQueueEmpty THEN al_flush_event_queue (fEventQueue)
  5.   END;
fEventQueue is a field of TmngEventManager, while al_flush_event_queue is a procedure defined in a 3rd party unit that is included in the INTERFACE USES section.  As I understood it should be inlined, or didn't I understood the whole thing?

Can see the full unit code here (https://sourceforge.net/p/mingro/code/HEAD/tree/TRUNK/src/engine/mngevents.pas#l299).
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on November 08, 2020, 12:12:21 pm
Still fighting the inline thing.

I've found a bug report (https://bugs.freepascal.org/view.php?id=34230) that says the compiler throws a false positive (or negative?) as it inlined the subroutine but said it wasn't.

Also I've found the wiki says that inline is buggy (https://wiki.freepascal.org/Inline) without more information.  There are a few open bugs in the bug tracker (https://bugs.freepascal.org/view_all_bug_page.php?filter=5fa7cc0acc999), a bunch from several years ago.

Just informing.
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on November 08, 2020, 01:35:29 pm
Ok, this is nuts. It says it can't inline this:

Code: Pascal  [Select][+][-]
  1. PROCEDURE SetLotagHi (VAR aLoTag: INTEGER; CONST aValue: INTEGER);
  2. BEGIN
  3.   aLoTag := (aLoTag AND $00FFFFFF) OR (aValue SHL 24)
  4. END;

Or this other one:
Code: Pascal  [Select][+][-]
  1. FUNCTION GetLotagHi (CONST aLoTag, aValue: INTEGER): INTEGER;
  2. BEGIN
  3.   RESULT := (aLoTag AND $00FFFFFF) OR (aValue SHL 24)
  4. END;

I didn't get the assembler output (yet) to confirm if it is another false positive (https://forum.lazarus.freepascal.org/index.php/topic,50565.15.html), but something is wrong with the INLINE generation for sure.

I'm about to get mad.
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: PascalDragon on November 08, 2020, 03:15:13 pm
Ok, this is nuts. It says it can't inline this:

Please provide a full example. Both functions correctly inline both with 3.2.0 and trunk.
Title: Re: Note: Call to subroutine "function any;" marked as inline is not inlined
Post by: Ñuño_Martínez on November 10, 2020, 06:42:21 pm
I can't.  I don't know why it works now. %)

I was trying to write a code snippet to show but it didn't show the hint in any way.  So I recompiled the project where I had the problem and that procedures didn't show any hint.  Just vanished. Disappeared.  And I didn't changed anything (except remove the temporary files, but I swear I did it before and the hints appeared).

I feel like somebody were pranking me.
TinyPortal © 2005-2018