Sign in Join

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

Mailing lists / fpc-devel / 2025-09

Do type-helpers block "regvar" opt?

4 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

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

Martin Frb

Tested with 3.3.1  d3ac07ad27
-O4
Win 64 bit

In the code below, compiled with -alr
   .section .text.n_p$project1_$$_foo,"ax"
   ....
   # Var a located in register rbx
(and it stays in rbx, until the call to write is prepared)

But if I comment out the "write", and uncomment the "a.w"    # Var a located at rsp+32, size=OS_64

Even the initial 2 lines will then NOT use a register for "a"?

program project1;
{$mode objfpc}{$Inline on}
{$StackFrames off}{$ImplicitExceptions off}
{$ModeSwitch typehelpers}
type
   P = ^integer;
   PH = type helper for P
     procedure w;
   end;
procedure PH.w;
begin
   write(self^)
end;
var g:p;
procedure Foo;
var a: p;
begin
   a:= g;
   a^:=1;
   //a.w;
   write(a^); //
end;
begin
   foo;
end.

Reply by email

Sven Barth
to Martin Frb

Martin Frb via fpc-devel schrieb am Mo.,
29. Sep. 2025, 12:30:

Show quoted text 17 lines
Tested with 3.3.1 d3ac07ad27 -O4 Win 64 bit In the code below, compiled with -alr .section .text.n_p$project1_$$_foo,"ax" .... # Var a located in register rbx (and it stays in rbx, until the call to write is prepared) But if I comment out the "write", and uncomment the "a.w" # Var a located at rsp+32, size=OS_64 Even the initial 2 lines will then NOT use a register for "a"?

The Self parameter of a type helper is a pointer, so the compiler needs to be able to take the address which in turn prohibits the use of the regvar optimization for that variable.

Regards,
Sven

Reply by email

Martin Frb
to Sven Barth
Sven Barth wrote 25 lines
Martin Frb via fpc-devel schrieb am Mo., 29. Sep. 2025, 12:30: Tested with 3.3.1  d3ac07ad27 -O4 Win 64 bit In the code below, compiled with -alr     .section .text.n_p$project1_$$_foo,"ax"     ....     # Var a located in register rbx (and it stays in rbx, until the call to write is prepared) But if I comment out the "write", and uncomment the "a.w"     # Var a located at rsp+32, size=OS_64 Even the initial 2 lines will then NOT use a register for "a"? The Self parameter of a type helper is a pointer, so the compiler needs to be able to take the address which in turn prohibits the use of the regvar optimization for that variable.

Ok, I see (well mostly....)

Does that need to affect (all the) code in which the pointer is used as just a pointer?

I mean, ok, (if) for the last statement (where the type helper is called) it needs to be on the stackframe, then the variable could be stored then. (and there after)

But for section of the code where it isn't using the type helper, a copy could be in  a register? => afaik if there are more vars than registers, then one register can be used for more than one var, just in different places? So then vars are swapped between frame and register?

Well, ok, the type helper could store a copy of self (pointer to the pointer) somewhere, and that could be accessed.
But then
- any code before the first call to the type helper should be safe to optimize
- code after would be tricky, as anything could be that copied pointer  (maybe when "pure" functions exists, and the type helper method is pure)

It also raises the question (I could test that, but...) what happens if I take a pointer of any other local var => will the compiler see that, and prevent such a local var from being optimised to a register?

Anyway, not important to change. Just important for me to know (so I know I am not trying to get something to work, that can't work) Thanks for the explanation.

Reply by email

Sven Barth
to Martin Frb

Martin Frb via fpc-devel schrieb am Mo.,
29. Sep. 2025, 14:58:

Show quoted text 51 lines
On 29/09/2025 14:17, Sven Barth via fpc-devel wrote: Martin Frb via fpc-devel schrieb am Mo., 29. Sep. 2025, 12:30: > Tested with 3.3.1 d3ac07ad27 > -O4 > Win 64 bit > > In the code below, compiled with -alr > .section .text.n_p$project1_$$_foo,"ax" > .... > # Var a located in register rbx > (and it stays in rbx, until the call to write is prepared) > > > > But if I comment out the "write", and uncomment the "a.w" > # Var a located at rsp+32, size=OS_64 > > Even the initial 2 lines will then NOT use a register for "a"? > The Self parameter of a type helper is a pointer, so the compiler needs to be able to take the address which in turn prohibits the use of the regvar optimization for that variable. Ok, I see (well mostly....) Does that need to affect (all the) code in which the pointer is used as just a pointer? I mean, ok, (if) for the last statement (where the type helper is called) it needs to be on the stackframe, then the variable could be stored then. (and there after) But for section of the code where it isn't using the type helper, a copy could be in a register? => afaik if there are more vars than registers, then one register can be used for more than one var, just in different places? So then vars are swapped between frame and register? Well, ok, the type helper could store a copy of self (pointer to the pointer) somewhere, and that could be accessed. But then - any code before the first call to the type helper should be safe to optimize - code after would be tricky, as anything could be that copied pointer (maybe when "pure" functions exists, and the type helper method is pure)

In theory that would be possible, but currently the compiler doesn't keep track *when* an address is taken, only *that* it is.

It also raises the question (I could test that, but...) what happens if I take a pointer of any other local var => will the compiler see that, and prevent such a local var from being optimised to a register?

As soon as the address is taken it won't be put into a register anymore as the compiler can't control/track what is done with that address. For example that would also be the case if you'd pass a single element to an open array parameter as then it's passed as a pointer as well (plus a high parameter of 0).

Regards,
Sven

Reply by email