[fpc-pascal] AnsiStrings and Memory Management

Peter Vreman peter at freepascal.org
Fri Dec 16 11:12:28 CET 2005


> Peter Vreman wrote:
>
>>>>(astonishing that  ShortStrings are slower than AnsiStrings in this
>>>>example
>>>
>>>in delphi).
>>>
>>>Not really. Delphi is silently upcasting your shortstrings to
>>> AnsiStrings
>>>in
>>>the background. You would probably have to recompile the VCL to get
>>> around
>>>this ;-)
>>
>>
>> I've commited a few small fixes to improve performance, please try again
>> with current 2.1.1 from svn
>
> It's enough to get as fast as D7 :) I guess to get more speed we need:
> 1) subroutine generation without entry/exit code
> 2) better register allocation for small procedures
>
> else we can't compete with the hand optimized assembler routines of the
> delphi
> rtl: fpc_unique_string is used a lot here which looks like:
>
> .globl	fpc_ansistr_unique
> fpc_ansistr_unique:
> .globl	FPC_ANSISTR_UNIQUE
> FPC_ANSISTR_UNIQUE:
> # Temps allocated between ebp-8 and ebp+0
> 	pushl	%ebp
> 	movl	%esp,%ebp
> 	subl	$8,%esp
> 	movl	%ebx,-8(%ebp)
> 	movl	%esi,-4(%ebp)
> # Var S located in register
> # Var $result located in register
> 	movl	%eax,%ebx
> # [437] pointer(result) := pointer(s);
> 	movl	(%ebx),%esi
> # [438] If Pointer(S)=Nil then
> 	testl	%esi,%esi
> 	je	.L4159
> .L4164:
> # [440] if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then
> 	movl	(%ebx),%eax
> 	subl	$8,%eax
> 	movl	(%eax),%eax
> 	cmpl	$1,%eax
> 	je	.L4166
> # [441] result:=fpc_truely_ansistr_unique(s);
> 	movl	%ebx,%eax
> 	call	SYSTEM_FPC_TRUELY_ANSISTR_UNIQUE$POINTER$$POINTER
> 	movl	%eax,%esi
> .L4166:
> .L4159:
> # [442] end;
> 	movl	%esi,%eax
> 	movl	-8(%ebp),%ebx
> 	movl	-4(%ebp),%esi
> 	leave
> 	ret
>
> Making it "frameless" safes 4 instructions.
>
> Being able to put result into eax saves at least another 4. result could
> be put
> in eax if the compiler recognizes that it doesn't have to save result
> while the
> fpc_truely_ansistr_unique(s) call because result is assigned after it. Is
> this
> doable (Daniel, Peter)?
>
> Further, using ebx for s isn't necessary because after the
> fpc_truely_ansistr_unique call s isn't used anymore. Could save another 2
> instructions.

This issue is also in the Todo for 2.1.1

The register variable allocation should be optimized. Currently the
virtual registers for register variables are allocated for the whole
procedure. A first step is to limit the lifetime of the virtual register.
But limiting the limetime requires synchronization points of the register
variables for loops and if-then-else statements. Example:

while ... do
  begin
    inc(regvar);
    writeln(regvar);
  end

the lifetime of the regvar shall be the whole loop and not only for those
two instructions.

Another issue that can use some optimization is the parameter loading and
allocation of internally called functions like FPC_INCR_ANSISTR_REF. A
possible solution is to modify the parameter generation code to first load
all parameters values to virtual registers and then with a single method
push all parameters like it is already done in ncgcal.pas.






More information about the fpc-pascal mailing list