[fpc-pascal] inlining functions

Benito van der Zander benito at benibela.de
Tue Jan 1 22:38:43 CET 2019


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 
> <benito at benibela.de <mailto:benito at 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 at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20190101/7cdf0c77/attachment.html>


More information about the fpc-pascal mailing list