Register Allocation on x86_64

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Register Allocation on x86_64

Martok
Hi all,

is it possible that the register allocation on x86_64 is a bit inefficient? No
matter the optimization settings, I can never get FPC to use more than the rax
and rdx registers. Especially $Optimization REGVAR does nothing (not even for
loop variables).
Instead, two nested loops are enough to get FPC to constantly do memory
load/stores on the loop variables. If an assembler block is marked as using
['rdx', 'rax'] (i.e.: rdtsc), instead of using some other general-purpose
registers, FPC stores them to memory before and reloads after the block. That
doesn't seem very efficient...

Is there anything else that needs to be switched on? I have the target arch set
to -CpCOREAVX2.


Regards,

Martok
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Register Allocation on x86_64

Jonas Maebe-3
On 05/01/18 16:41, Martok wrote:

> is it possible that the register allocation on x86_64 is a bit inefficient? No
> matter the optimization settings, I can never get FPC to use more than the rax
> and rdx registers. Especially $Optimization REGVAR does nothing (not even for
> loop variables).
> Instead, two nested loops are enough to get FPC to constantly do memory
> load/stores on the loop variables. If an assembler block is marked as using
> ['rdx', 'rax'] (i.e.: rdtsc), instead of using some other general-purpose
> registers, FPC stores them to memory before and reloads after the block. That
> doesn't seem very efficient...

regvars have always been disabled for routines that contain assembler
blocks (on all architectures). Sometimes the compiler temporarily uses
registers for other purposes over a longer period, which is why marking
the used registers is still required.


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Register Allocation on x86_64

Martok
Am 05.01.2018 um 18:03 schrieb Jonas Maebe:
> regvars have always been disabled for routines that contain assembler
> blocks (on all architectures). Sometimes the compiler temporarily uses
> registers for other purposes over a longer period, which is why marking
> the used registers is still required.
I can see that this is safer if the assembler blocks aren't properly annotated,
but if they are, there shouldn't be any problem?

There seem to be a lot of rather non-obvious limitations around inline assembler
and assembler routines. Are they documented somewhere central?

--
Regards,
Martok

Ceterum censeo b32079 esse sanandam.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Register Allocation on x86_64

Jonas Maebe-3
On 07/01/18 23:24, Martok wrote:
> Am 05.01.2018 um 18:03 schrieb Jonas Maebe:
>> regvars have always been disabled for routines that contain assembler
>> blocks (on all architectures). Sometimes the compiler temporarily uses
>> registers for other purposes over a longer period, which is why marking
>> the used registers is still required.
> I can see that this is safer if the assembler blocks aren't properly annotated,
> but if they are, there shouldn't be any problem?

Part of it is probably legacy, and part of it is the philosophy that the
compiler does not try to understand assembly blocks and hence cannot
make any assumptions about what is and what is not safe regarding local
variables in the same routine. Unlike in e.g. gcc, there are no
annotations for assembly routines that they expect certain variables to
be in memory and/or registers, that the block may touch arbitrary memory
locations, etc. Hence, the compiler is as conservative as possible.

It is probably possible to safely increase the code quality of routines
containing assembly blocks, but that would require a proper examination
of what optimizations are safe under which conditions (and it would lead
to the need to add support for extra annotations for assembly blocks).

> There seem to be a lot of rather non-obvious limitations around inline assembler
> and assembler routines. Are they documented somewhere central?

Afaik there are only two limitations:
* routines containing assembly blocks (including pure assembly routines)
cannot be inlined
* regular procedures that contain assembly blocks will never use regvars


Jonas
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Register Allocation on x86_64

Martok
Hi,

> variables in the same routine. Unlike in e.g. gcc, there are no
> annotations for assembly routines that they expect certain variables to
> be in memory and/or registers, that the block may touch arbitrary memory
> locations, etc. Hence, the compiler is as conservative as possible.
This took me a while to understand, but what you're saying is that the issue is
not so much about what registers might be modified (we could just say that if
the annotation exists, it is assumed to be complete), but that the assembler
code might try to take the address of a variable (possibly with indirections),
which must therefore not be a regvar?
That makes sense. Unfortunately...

> Afaik there are only two limitations:
> * routines containing assembly blocks (including pure assembly routines)
> cannot be inlined> * regular procedures that contain assembly blocks will never use regvars
Somehow I have a feeling that the fix for one would also fix the other...

I'd add the manual RIP addressing that was mentioned on the bugtracker recently
(OT: is -Cg supposed to work on platforms where it is not set by default?).


For the original issue, since manually using assembler blocks makes things
complicated, is there a way to "strongly suggest" to the compiler that a
variable should become a regvar if the entire routine is pure Pascal? Something
like the (purely decorative) {register} comments in
/packages/pasjpeg/src/jdcolor.pas?


--
Regards,
Martok

Ceterum censeo b32079 esse sanandam.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Register Allocation on x86_64

Jonas Maebe-3
On 10/01/18 17:06, Martok wrote:
>
>> Afaik there are only two limitations:
>> * routines containing assembly blocks (including pure assembly routines)
>> cannot be inlined> * regular procedures that contain assembly blocks will never use regvars
> Somehow I have a feeling that the fix for one would also fix the other...

They are orthogonal issues.

> I'd add the manual RIP addressing that was mentioned on the bugtracker recently

That's not a limitation. Not supporting absolute addressing on x86-64
would be a limitation.

> (OT: is -Cg supposed to work on platforms where it is not set by default?).

I think it does, although I don't think it does anything on Win64 (as
its code is already position-independent by default).

> For the original issue, since manually using assembler blocks makes things
> complicated, is there a way to "strongly suggest" to the compiler that a
> variable should become a regvar if the entire routine is pure Pascal? Something
> like the (purely decorative) {register} comments in
> /packages/pasjpeg/src/jdcolor.pas?

No, and I don't think it would be a good idea to spend time on
complicating the compiler with such functionality. Over time, such hints
become more of a burden than a gain (I believe all modern C compilers
completely ignore such hints).


Jonas

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal