Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-05

Inline methods

21 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

LacaK

Hi *,
is it possible inline also methods of objects (not regular procedures) ? I have very simple class method, which call I need inline. (looking at assembler code it is not inlined; I have looked also in documentation, but I do not found article about inline and methods)

Example:

function T2DArray.Data(x, y: integer): PElement; inline;
begin
   Result := @FArray[x+y*Fx];
end;

Thanks
-Laco.

Sven Barth
to LacaK
"LacaK" wrote 5 lines
Hi *, is it possible inline also methods of objects (not regular procedures) ? I have very simple class method, which call I need inline. (looking at assembler code it is not inlined; I have looked also in

documentation, but I do not found article about inline and methods)

Show quoted text 7 lines
Example: function T2DArray.Data(x, y: integer): PElement; inline; begin Result := @FArray[x+y*Fx]; end;

Yes. Inline needs to be declared at the declaration however and not the implementation and any function or method that uses it (in the same unit) needs to come afterwards if you want it to be inlined (for other units that doesn't matter as long as you don't have circular dependencies, cause then things get messy). On addition to that "inline" is only a hint for the compiler, so there might be cases when the compiler decides not to inline.

Regards,
Sven

Sven Barth
to Sven Barth
"Sven Barth" wrote 7 lines
Am 18.05.2016 10:06 schrieb "LacaK" : > > Hi *, > is it possible inline also methods of objects (not regular procedures) ? > I have very simple class method, which call I need inline. > (looking at assembler code it is not inlined; I have looked also in

documentation, but I do not found article about inline and methods)

Show quoted text 9 lines
> > Example: > > function T2DArray.Data(x, y: integer): PElement; inline; > begin > Result := @FArray[x+y*Fx]; > end; Yes. Inline needs to be declared at the declaration however and not the

implementation and any function or method that uses it (in the same unit) needs to come afterwards if you want it to be inlined (for other units that doesn't matter as long as you don't have circular dependencies, cause then things get messy). On addition to that "inline" is only a hint for the compiler, so there might be cases when the compiler decides not to inline.

Oh and it obviously won't work with virtual methods.

Regards,
Sven

Mark Morgan Lloyd
to LacaK: is it possible inline also methods of objects (not regular procedures) ? I have very…
LacaK wrote 12 lines
Hi *, is it possible inline also methods of objects (not regular procedures) ? I have very simple class method, which call I need inline. (looking at assembler code it is not inlined; I have looked also in documentation, but I do not found article about inline and methods) Example: function T2DArray.Data(x, y: integer): PElement; inline; begin Result := @FArray[x+y*Fx]; end;

I thought it was, and believe that in the past I've been told that it was a useful optimisation aid hence in my code I find e.g.

(*
Setters marked "inline" are trivial except for an assertion to check the parameter range. Most of the associated code will be optimised away if assertions are ignored by the compiler.
*)

[Sorry, I've got this bad habit of commenting stuff which some people frown on. But I think that for something like this- i.e. /why/ something is being done- it's justified.]

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
LacaK
to Sven Barth: documentation, but I do not found article about inline and methods) implementation and…
Show quoted text 16 lines
> > is it possible inline also methods of objects (not regular procedures) ? > > I have very simple class method, which call I need inline. > > (looking at assembler code it is not inlined; I have looked also in documentation, but I do not found article about inline and methods) > > > > Example: > > > > function T2DArray.Data(x, y: integer): PElement; inline; > > begin > > Result := @FArray[x+y*Fx]; > > end; > > Yes. Inline needs to be declared at the declaration however and not the implementation

I have "inline" on both places also on declaration

and any function or method that uses it (in the same unit) needs to come afterwards

Yes it comes afterwards

Show quoted text 7 lines
if you want it to be inlined (for other units that doesn't matter as long as you don't have circular dependencies, cause then things get messy). On addition to that "inline" is only a hint for the compiler, so there might be cases when the compiler decides not to inline. Oh and it obviously won't work with virtual methods.

In my case it is not virtual method.

But I forgot to mention, that it is method of generic object:

   generic T2DArray<T> = object
    ...
     public
       constructor Init(oobMode: TOutOfBoundsMode); overload;
       constructor Init(x,y: integer); overload;
       ...
       function Data(x,y: integer): PElement; overload; inline;
   end;

So what can be a case, that method is not inlined, can it be track down or is there something which I can do to force inlining ? (FPC 2.6.4)
Thanks
-Laco.

Michael Van Canneyt
to LacaK
LacaK wrote 16 lines
> In my case it is not virtual method. But I forgot to mention, that it is method of generic object: generic T2DArray<T> = object ... public constructor Init(oobMode: TOutOfBoundsMode); overload; constructor Init(x,y: integer); overload; ... function Data(x,y: integer): PElement; overload; inline; end; So what can be a case, that method is not inlined, can it be track down or is there something which I can do to force inlining ?

Did you add {$INLINE ON} ?

If not, the compiler will ignore the ;inline; modifier.

Michael.

LacaK
to Michael Van Canneyt
Show quoted text 23 lines
>> > In my case it is not virtual method. > > But I forgot to mention, that it is method of generic object: > > generic T2DArray<T> = object > ... > public > constructor Init(oobMode: TOutOfBoundsMode); overload; > constructor Init(x,y: integer); overload; > ... > function Data(x,y: integer): PElement; overload; inline; > end; > > So what can be a case, that method is not inlined, can it be track > down or is there something which I can do to force inlining ? Did you add {$INLINE ON} ?

No, but I have enabled it using Project Options.
Now I added to source unit {$INLINE ON}, but it does not help. I have in assembler still CALL to method.
(In same source unit I have regular procedures and these are inlined as expected; My problem is relatod to object methods only)

Any other ideas, what leads compiler to not inline ? Thanks

-Laco.

Jonas Maebe
to LacaK

LacaK wrote on Wed, 18 May 2016:

Any other ideas, what leads compiler to not inline ?

If you compile with -vd, the compiler will tell you in most cases why it's not inlining. Additionally, it's possible that it's not possible to inline generic routines in regular routines, because IIRC the code for specialisations is generated after the code for all regular routines has been generated (and hence it's probably never available yet while generating code for regular routines, unless perhaps if the specialisation is defined in another unit).

Jonas

Sven Barth
to Jonas Maebe
"Jonas Maebe" wrote 8 lines
LacaK wrote on Wed, 18 May 2016: > Any other ideas, what leads compiler to not inline ? If you compile with -vd, the compiler will tell you in most cases why

it's not inlining. Additionally, it's possible that it's not possible to inline generic routines in regular routines, because IIRC the code for specialisations is generated after the code for all regular routines has been generated (and hence it's probably never available yet while generating code for regular routines, unless perhaps if the specialisation is defined in another unit).

Yes, that might indeed be the most probable cause. That's something that I still need to fix in trunk, cause I really want inlining to work with generic functions (with generic records and classes it should work if the specialization was done in the interface section of another unit).

Regards,
Sven

LacaK
to Jonas Maebe: LacaK wrote on Wed, 18 May 2016: If you compile with -vd, the compiler will tell you in…
Show quoted text 5 lines
> Any other ideas, what leads compiler to not inline ? If you compile with -vd, the compiler will tell you in most cases why it's not inlining.

Hm, I have checked in Lazarus on Project Options / Verbosity appropriate -vd option, but in output window I do not see any more info ... How should look such info message ?

Additionally, it's possible that it's not possible to inline generic routines in regular routines,

It is not my case.
I use this generic in another generic and then it is specialized in interface section of same unit.

Later this specialized object is used in another class type, which comes after specialization.
So this object is not used in regular procedure, but in methods of another class ...

I did also attempt to put all this stuff (with generics and specializations) into separate unit and then I have used this unit ( in interface section ) in "main" unit
But still does not inline ...

-Laco.

Marco van de Voort
to Sven Barth: it's not inlining. Additionally, it's possible that it's not possible to inline generic…

In our previous episode, Sven Barth said:

Yes, that might indeed be the most probable cause. That's something that I still need to fix in trunk, cause I really want inlining to work with generic functions (with generic records and classes it should work if the specialization was done in the interface section of another unit).

(delphi doesn't inline generics either. At least it didn't at XE7 level, haven't tested XE10 yet)

Mattias Gaertner
to LacaK: Hm, I have checked in Lazarus on Project Options / Verbosity appropriate -vd option, but…
Show quoted text 9 lines
> >> Any other ideas, what leads compiler to not inline ? > > If you compile with -vd, the compiler will tell you in most cases why > it's not inlining. Hm, I have checked in Lazarus on Project Options / Verbosity appropriate -vd option, but in output window I do not see any more info ... How should look such info message ?

Did you build your project clean?
Changing verbosity flags does not recompile units.

Mattias

Sven Barth
to Marco van de Voort: In our previous episode, Sven Barth said: (delphi doesn't inline generics either. At…
"Marco van de Voort" wrote
In our previous episode, Sven Barth said: > Yes, that might indeed be the most probable cause. That's something

that I

> still need to fix in trunk, cause I really want inlining to work with > generic functions (with generic records and classes it should work if

the

> specialization was done in the interface section of another unit). (delphi doesn't inline generics either. At least it didn't at XE7 level, haven't tested XE10 yet)

Doesn't mean that we can't do that better... ;)

Regards,
Sven

Sven Barth
to LacaK: Hm, I have checked in Lazarus on Project Options / Verbosity appropriate -vd option, but…
"LacaK" wrote
> Additionally, it's possible that it's not possible to inline generic

routines in regular routines,

It is not my case. I use this generic in another generic and then it is specialized in

interface section of same unit.

Later this specialized object is used in another class type, which comes

after specialization.

So this object is not used in regular procedure, but in methods of

another class ...

I did also attempt to put all this stuff (with generics and

specializations) into separate unit and then I have used this unit ( in interface section ) in "main" unit

But still does not inline ...

You need to call the function in another unit than where the specialization is. Maybe provide a small (compileable) example that shows what you're doing so that we can check that ourselves. It could also be that 2.6.x had still problems there...

Regards,
Sven

LacaK
to Mattias Gaertner: On Wed, 18 May 2016 14:43:06 +0200 Did you build your project clean? Changing verbosity…
> Hm, I have checked in Lazarus on Project Options / Verbosity appropriate > -vd option, but in output window I do not see any more info ... > How should look such info message ? Did you build your project clean?

Yes, I have used "Clean and build" option.
May be that this diagnostic messages are not shown in "Messages" window. (because when I compile from command line I see also other lines, which are not shown in Lazarus)
L.

LacaK
to Sven Barth: interface section of same unit. after specialization. another class ... specializations)…
Show quoted text 21 lines
>> Additionally, it's possible that it's not possible to inline generic routines in regular routines, > > It is not my case. > I use this generic in another generic and then it is specialized in interface section of same unit. > > Later this specialized object is used in another class type, which comes after specialization. > So this object is not used in regular procedure, but in methods of another class ... > > I did also attempt to put all this stuff (with generics and specializations) into separate unit and then I have used this unit ( in interface section ) in "main" unit > But still does not inline ... You need to call the function in another unit than where the specialization is.

Yes I do it so (in attached example it is in one unit, but in my real generic and specialization is in separate unit, that is used by another in interface section)

Maybe provide a small (compileable) example that shows what you're doing so that we can check that ourselves.

Attached

It could also be that 2.6.x had still problems there...

I tried also with FPC 3.0, but result is same AFAICS

Thanks
-Laco.

Mattias Gaertner
to LacaK: Yes, I have used "Clean and build" option. May be that this diagnostic messages are not…
Show quoted text 9 lines
>> Hm, I have checked in Lazarus on Project Options / Verbosity appropriate >> -vd option, but in output window I do not see any more info ... >> How should look such info message ? > Did you build your project clean? Yes, I have used "Clean and build" option. May be that this diagnostic messages are not shown in "Messages" window. (because when I compile from command line I see also other lines, which are not shown in Lazarus)

Right click on Messages window / Filter...

Mattias

LacaK
to Mattias Gaertner
Show quoted text 5 lines
> Yes, I have used "Clean and build" option. > May be that this diagnostic messages are not shown in "Messages" window. > (because when I compile from command line I see also other lines, which > are not shown in Lazarus) Right click on Messages window / Filter...

Very nice!
(I was not aware of such option I have searched through menu Tools/Environment options ...)
Thanks
-Laco.

Sven Barth
to LacaK: Yes I do it so (in attached example it is in one unit, but in my real generic and…
"LacaK" wrote
> > >> Additionally, it's possible that it's not possible to inline generic

routines in regular routines,

> > > > It is not my case. > > I use this generic in another generic and then it is specialized in

interface section of same unit.

> > > > Later this specialized object is used in another class type, which

comes after specialization.

> > So this object is not used in regular procedure, but in methods of

another class ...

> > > > I did also attempt to put all this stuff (with generics and

specializations) into separate unit and then I have used this unit ( in interface section ) in "main" unit

> > But still does not inline ... > > You need to call the function in another unit than where the

specialization is.

> Yes I do it so (in attached example it is in one unit, but in my real

generic and specialization is in separate unit, that is used by another in interface section)

> Maybe provide a small (compileable) example that shows what you're doing

so that we can check that ourselves.

> Attached

Moving GT and T1 to a separate unit results in inlined code, as expected (tested with 2.6.4, 3.0.0 and 3.1.1), also if T2 is in another separate unit.

Regards,
Sven

LacaK
to Sven Barth

Dňa 20.5.2016 o 14:42 Sven Barth napísal(a):

Show quoted text 40 lines
Am 19.05.2016 08:52 schrieb "LacaK" < >: > > >> >> >> Additionally, it's possible that it's not possible to inline generic routines in regular routines, >> > >> > It is not my case. >> > I use this generic in another generic and then it is specialized in interface section of same unit. >> > >> > Later this specialized object is used in another class type, which comes after specialization. >> > So this object is not used in regular procedure, but in methods of another class ... >> > >> > I did also attempt to put all this stuff (with generics and specializations) into separate unit and then I have used this unit ( in interface section ) in "main" unit >> > But still does not inline ... >> >> You need to call the function in another unit than where the specialization is. >> > Yes I do it so (in attached example it is in one unit, but in my real generic and specialization is in separate unit, that is used by another in interface section) > > >> Maybe provide a small (compileable) example that shows what you're doing so that we can check that ourselves. >> > Attached Moving GT and T1 to a separate unit results in inlined code, as expected (tested with 2.6.4, 3.0.0 and 3.1.1), also if T2 is in another separate unit.

Yes I can confirm, that this works .
So if I have specialized object type (with inline methods), which is used by another type in same unit inline methods are not inlined ? (assume, that specialized type is defined before type which uses it in interface section and is implemented also before in implementation section) Can this be fixed or is this some kind of design limitation, which can not be bypassed (nor in future) ?
Thanks
-Laco.

Show quoted text 9 lines
Regards, Sven _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Sven Barth
to LacaK
"LacaK" wrote 10 lines
Dňa 20.5.2016 o 14:42 Sven Barth napísal(a): > > Am 19.05.2016 08:52 schrieb "LacaK" < <mailto: >: > > > > > >> > >> >> Additionally, it's possible that it's not possible to inline

generic routines in regular routines,

> >> > > >> > It is not my case. > >> > I use this generic in another generic and then it is specialized in

interface section of same unit.

> >> > > >> > Later this specialized object is used in another class type, which

comes after specialization.

> >> > So this object is not used in regular procedure, but in methods of

another class ...

> >> > > >> > I did also attempt to put all this stuff (with generics and

specializations) into separate unit and then I have used this unit ( in interface section ) in "main" unit

> >> > But still does not inline ... > >> > >> You need to call the function in another unit than where the

specialization is.

> >> > > Yes I do it so (in attached example it is in one unit, but in my real

generic and specialization is in separate unit, that is used by another in interface section)

> > > > > >> Maybe provide a small (compileable) example that shows what you're

doing so that we can check that ourselves.

> >> > > Attached > > Moving GT and T1 to a separate unit results in inlined code, as expected

(tested with 2.6.4, 3.0.0 and 3.1.1), also if T2 is in another separate unit.

> Yes I can confirm, that this works . So if I have specialized object type (with inline methods), which is used

by another type in same unit inline methods are not inlined ?

(assume, that specialized type is defined before type which uses it in

interface section and is implemented also before in implementation section)

Your assumption is correct.

Can this be fixed or is this some kind of design limitation, which can

not be bypassed (nor in future) ?

This *might* get fixed in the future. After all by definition inlining is completely up to the compiler, so even if you add "inline" to some method or function there is no guarantee that it will be inlined.

Regards,
Sven