Sign in Join

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

Mailing lists / fpc-pascal / 2019-06

not inlined?

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Ryan Joseph

The method TDictionary.IsSet is not able to be inlined but why not? What are the rules to inlining in FPC? I know calling inherited is not possible (makes sense) but I often get this warning and I don’t always understand why.

      TDictionaryEntry = record
        key: TDictionaryKey;
        value: TValue;
      end;
      TDictionaryEntryArray = array[0..high(integer)] of TDictionaryEntry;
      TDictionaryEntryArrayPtr = ^TDictionaryEntryArray;
      TDictionaryHeader = record
	...
        entries: TDictionaryEntryArrayPtr;
      end;
      header: TDictionaryHeaderPtr;
function TDictionary.IsSet (index: integer): boolean;
begin
  result := assigned(header^.entries[index]^.value);
end;

Regards,
Ryan Joseph

Reply by email

Ben Grasset
to Ryan Joseph
PM Ryan Joseph wrote 5 lines
The method TDictionary.IsSet is not able to be inlined but why not? What are the rules to inlining in FPC? I know calling inherited is not possible (makes sense) but I often get this warning and I don’t always understand why.

It depends a lot on the context you're calling the function-to-be-inlined from. Can you show more of the code?

Reply by email

Ryan Joseph
to Ben Grasset
On Jun 19, 2019, at 3:32 PM, Ben Grasset wrote: It depends a lot on the context you're calling the function-to-be-inlined from. Can you show more of the code?

What are the rules with he calling context? I didn’t even know that was a factor! I’ll have to look to get some examples.

Regards,
Ryan Joseph

Reply by email

Ben Grasset
to Ryan Joseph
PM Ryan Joseph wrote
What are the rules with he calling context? I didn’t even know that was a factor! I’ll have to look to get some examples.

Basically, if you're calling a function marked inline from another function, the implementation of the function to be inlined has to come first in the unit.

So for example, the following code generates assembly that is completely identical for all three functions, because `Proc` gets inlined into `Proc2` and then through that into `Proc3`.

unit Example;
{$mode ObjFPC}
{$modeswitch AdvancedRecords}
interface
type Letters = (A, B, C);
type
  TRecord = record
    procedure Proc; inline;
    procedure Proc2; inline;
    procedure Proc3;
  end;
implementation
procedure TRecord.Proc;
begin
  WriteLn([B] <= [A, B, C]);
end;
procedure TRecord.Proc2;
begin
  Proc();
end;
procedure TRecord.Proc3;
begin
  Proc2();
end;
end.

If the implementation order was `Proc2` -> `Proc` -> `Proc3`, however, `Proc3` could still inline away both `Proc` and `Proc2`, but `Proc2` itself could not inline away `Proc.`

Lastly, if the implementation for `Proc` came after both those for `Proc2` and `Proc3`, it would not be inlined into either. (I.E. `Proc3` would directly call `Proc2`, and `Proc2` would directly call `Proc`.)

Reply by email