Forum > FPC development

String related improvements for FPC

(1/2) > >>

lagprogramming:
The code of FPC has lots of lines like SetLength(AnyKindOfStringType, 0).
When SetLength(AnyKindOfStringType, 0) is replaced with AnyKindOfStringType := '' the compiler produces better code because it avoids calling the SetLength procedure. I couldn't find a string type where the compiler would produce worse code for AnyKindOfStringType := '' than for SetLength(AnyKindOfStringType, 0).
Replacing the SetLength(AnyKindOfStringType, 0) code with AnyKindOfStringType := '' leads to a problem. The patch from an external source would be large enough that I have doubts any FPC developer would commit it to git.
So, is there a FPC developer willing to do this improvement!? I don't think that the compiler will automatically optimize this string related code in the near future. Also, it would be a step forward in having a single pascal programming practice for these particular assignments: StringType := '', not SetLength(StringType, 0).

SymbolicFrank:
Why not optimize the SetLength code? Much simpler.

Чебурашка:
The idea of optimizing is always good of course.

OTOH there is a sort of symmetry in
 

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure DoIt();var  s: string;begin  SetLength(s, 5);  try    // operations  finally     SetLength(s, 0);  end;end; 
Perhaps it would be lost if fpc forces to make ":= nil".

Personally I like this symmetry. But I also admit that I am not a big fan of having two ways of doing the same task, especially when one is less efficient than the other.

BeniBela:
The compiler developers messed this symmetry up


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---var  s: string;begin  SetLength(s, 5);
you are not allowed to write that anymore

it gives a warning: "Hint: Local variable "s" does not seem to be initialized"


--- Quote from: lagprogramming on July 20, 2023, 04:25:48 pm ---
When SetLength(AnyKindOfStringType, 0) is replaced with AnyKindOfStringType := '' the compiler produces better code because it avoids calling the SetLength procedure.

--- End quote ---

is that actually true?

then it calls fpc_AnsiStr_Assign

lagprogramming:

--- Quote from: BeniBela on July 20, 2023, 06:42:05 pm ---
--- Quote from: lagprogramming on July 20, 2023, 04:25:48 pm ---
When SetLength(AnyKindOfStringType, 0) is replaced with AnyKindOfStringType := '' the compiler produces better code because it avoids calling the SetLength procedure.

--- End quote ---

is that actually true?

then it calls fpc_AnsiStr_Assign

--- End quote ---

I don't know why but I remember that the first time a value was assigned to a string variable in a routine and that value was an empty string, the compiler would have completely avoided the call to fpc_stringtype_assign. Instead of calling the assign routine, something like an inlined code was executed. You know, like it does with shortstrings(change TestString to shortstring in the example below and notice there's a single instruction produced instead of going into fpc_shortstr_setlength). With the latest fpc development version I see the assign routine too.  :(


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1; type  TestString = ansistring;               //shortstring;               //unicodestring;               procedure foo(var param:TestString);begin  param:='';end; procedure bar(var param:TestString);begin  setlength(param, 0);end; var  L: TestString;begin  L:='';  setlength(L, 0);  foo(L);  bar(L);  writeln(L);end. Anyway, even with this unpleasant surprise, unlike fpc_ansistr_setlength, fpc_ansistr_assign doesn't additionally call fpc_ansistr_decr_ref.
This is the code executed.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---fpc_ansistr_assign 000000000040ADB0 53                       push rbx000000000040ADB1 4154                     push r12000000000040ADB3 50                       push rax000000000040ADB4 4889FB                   mov rbx,rdi000000000040ADB7 4989F4                   mov r12,rsi000000000040ADBA 483B37                   cmp rsi,[rdi]000000000040ADBD 7422                     jz +$22    # $000000000040ADE1 fpc_ansistr_assign+49...000000000040ADE1 59                       pop rcx000000000040ADE2 415C                     pop r12000000000040ADE4 5B                       pop rbx000000000040ADE5 C3                       ret vs.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---fpc_ansistr_setlength 000000000040BF10 53                       push rbx000000000040BF11 4154                     push r12000000000040BF13 4155                     push r13000000000040BF15 488D6424F0               lea rsp,[rsp-$10]000000000040BF1A 4889FB                   mov rbx,rdi000000000040BF1D 4989F4                   mov r12,rsi000000000040BF20 664189D5                 mov r13w,dx000000000040BF24 4885F6                   test rsi,rsi000000000040BF27 0F8E0B010000             jle +$0000010B    # $000000000040C038 fpc_ansistr_setlength+296...000000000040C038 4889DF                   mov rdi,rbx000000000040C03B E810EDFFFF               call -$000012F0    # $000000000040AD50 fpc_ansistr_decr_ref000000000040C040 488D642410               lea rsp,[rsp+$10]000000000040C045 415D                     pop r13000000000040C047 415C                     pop r12000000000040C049 5B                       pop rbx000000000040C04A C3                       ret  fpc_ansistr_decr_ref 000000000040AD50 53                       push rbx000000000040AD51 48833F00                 cmp qword ptr [rdi],$00000000000040AD55 7429                     jz +$29    # $000000000040AD80 fpc_ansistr_decr_ref+48...000000000040AD80 5B                       pop rbx000000000040AD81 C3                       ret
By using just a few instructions instead, can't FPC replace the call to assign when the first assignment to a variable is an empty string!? Either I'm confusing things, either there was a time when FPC did it. Overall, with those few instructions instead of the call to SetLength, the improvement is welcomed, especially because many developers have the tendency to assign empty string values to variables and function results at the beginning of the routines. They use these assignments as default values, or as workarounds to avoid warnings when using SetLength later in code.
EDIT: Maybe the assign routine was inlined at the time I've done tests in the past and now it's no longer inlined.

Navigation

[0] Message Index

[#] Next page

Go to full version