Hi,

and why is it not inlining the count and append call of this string builder? It is not using any implementation only function

unit inlinetest;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils,math;

type TStrBuilder = object
protected
  next, bufferend: pchar; //next empty pchar and first pos after the string
public
  buffer: pstring;
  procedure init(abuffer:pstring);
  procedure final;
  function count: SizeInt; inline;
  procedure reserveadd(delta: SizeInt);
  procedure append(c: char); inline;
  procedure append(const s: RawByteString); inline;
  procedure append(const p: pchar; const l: SizeInt); inline;
end;

implementation

procedure TStrBuilder.init(abuffer: pstring);
begin
  buffer := abuffer;
  SetLength(buffer^, 16); //use setlength to create a new string

  next := pchar(buffer^);
  bufferend := next + length(buffer^);
end;

procedure TStrBuilder.final;
begin
  if next <> bufferend then begin
    setlength(buffer^, count);  // !!! Note: Call to subroutine "function TStrBuilder.count:Int64;" marked as inline is not inlined
    next := pchar(buffer^) + length(buffer^);
    bufferend := next;
  end;
end;

function TStrBuilder.count: SizeInt;
begin
  result := next - pointer(buffer^);
end;


procedure TStrBuilder.reserveadd(delta: SizeInt);
var
  oldlen: SizeInt;
begin
  if next + delta > bufferend then begin
    oldlen := count;
    SetLength(buffer^, max(2*length(buffer^), oldlen + delta));
    next := pchar(buffer^) + oldlen;
    bufferend := pchar(buffer^) + length(buffer^);
  end;
end;

procedure TStrBuilder.append(c: char);
begin
  if next >= bufferend then reserveadd(1);
  next^ := c;
  inc(next);
end;

procedure TStrBuilder.append(const s: RawByteString);
begin
  append(pchar(pointer(s)), length(s)); // !!! inlinetest.pas(71,3) Note: Call to subroutine "procedure TStrBuilder.append(const p:PChar;const l:Int64);" marked as inline is not inlined
end;



procedure TStrBuilder.append(const p: pchar; const l: SizeInt); inline;
begin
  if l <= 0 then exit;
  if next + l > bufferend then reserveadd(l);
  move(p^, next^, l);
  inc(next, l);
end;



end.



Bye,
Benito

Am 29.12.18 um 20:31 schrieb Sven Barth via fpc-pascal:
Am Sa., 29. Dez. 2018, 15:23 hat Benito van der Zander <ben...@benibela.de <mailto:ben...@benibela.de>> geschrieben:

    Hi,

    after updating from fpc 3.1 to fpc 3.3, I am getting a lot of
    "function
    was not inlined" warnings, e.g. when an inline function depends on a
    function not declared in the interface part like:

    unit inlinetest;

    {$mode objfpc}{$H+}

    interface

    uses
       Classes, SysUtils;


    function strContains(const str, searched: string): boolean; inline;

    implementation

    function strContainsFrom(const str, searched: string; from: SizeInt):
    boolean;
    begin
       result:=Pos(searched, str, from) > 0;
    end;


    function strContains(const str, searched: string): boolean; inline;
    begin
       result := strContainsFrom(str, searched, 1);
    end;

    end.



    Is that supposed to happen?

    Fpc 3.1 did not show any warning in this case (although now that I
    investigate it, fpc 3.1 also did not seem to inline it despite not
    showing the warning)


Correct. FPC 3.1.1 did neither warn nor inline in this case, 3.3.1 at least warns (I think 3.2 already warns as well).

Regards,
Sven

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to