Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread José Mejuto via fpc-devel

El 16/10/2021 a las 21:57, J. Gareth Moreton via fpc-devel escribió:
Certainly possible, and would address the whole function pointer thing, 
although I do question the performance hit because of the extra jump, 
especially for small procedures, as well as the fact that the function 
overhead would still be present.  Certainly a safe start though.




Hello,

I do not know if its possible, but you can add a bunch of NOPs before 
real function, 1, 4, 8... NOPs, one group for each removed call. Of 
course a multiple times removed function can have a lot of NOPs to be 
executed before the real function body starts.



--

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread J. Gareth Moreton via fpc-devel
Certainly possible, and would address the whole function pointer thing, 
although I do question the performance hit because of the extra jump, 
especially for small procedures, as well as the fact that the function 
overhead would still be present.  Certainly a safe start though.


Gareth aka. Kit

On 16/10/2021 20:33, Yuriy Sydorov via fpc-devel wrote:


On 16.10.2021 21:45, J. Gareth Moreton via fpc-devel wrote:
I figured that virtual methods would be no-go and that this would 
only apply to static methods.  It seems a shame to dismiss it 
completely though because there's a huge number of procedures that 
compile to the same code, especially when generics come into play, 
and I have identified a fair number in the compiler itself (at least 
when compiled under x86_64-win64).


Instead of complete elimination of the duplicate function code you can 
replace it by the unconditional jump to the single copy of the 
function code.


Yuriy.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread Yuriy Sydorov via fpc-devel


On 16.10.2021 21:45, J. Gareth Moreton via fpc-devel wrote:
I figured that virtual methods would be no-go and that this would only apply to static methods.  It seems a shame to 
dismiss it completely though because there's a huge number of procedures that compile to the same code, especially when 
generics come into play, and I have identified a fair number in the compiler itself (at least when compiled under 
x86_64-win64).


Instead of complete elimination of the duplicate function code you can replace it by the unconditional jump to the 
single copy of the function code.


Yuriy.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread J. Gareth Moreton via fpc-devel
I figured that virtual methods would be no-go and that this would only 
apply to static methods.  It seems a shame to dismiss it completely 
though because there's a huge number of procedures that compile to the 
same code, especially when generics come into play, and I have 
identified a fair number in the compiler itself (at least when compiled 
under x86_64-win64).


I guess it would be something that would have to be showcased and 
thoroughly tested.  I can only try!


Gareth aka. Kit

On 16/10/2021 19:21, Jonas Maebe via fpc-devel wrote:

On 16/10/2021 19:59, J. Gareth Moreton via fpc-devel wrote:
Sounds like "procvar = @myproc" would be -O4 at best due to the 
side-effects,


That's not a kind of side-effect that would be acceptable at any 
optimisation level. That is an explicit, valid comparison in code that 
would suddenly behave wrongly.


otherwise I would wonder if it's possible to track such references, 
especially with units that are pre-compiled.


It is possible to track whether the address gets taken of a procedure 
and store that if the ppu file if you would be so inclined. This means 
it will be impossible to apply the optimisation for any virtual method 
though, since all of their addresses get implicitly taken.


For the reason mentioned in my previous message, I don't think it's a 
good optimisation to implement in a compiler though.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread J. Gareth Moreton via fpc-devel
Sounds like "procvar = @myproc" would be -O4 at best due to the 
side-effects, otherwise I would wonder if it's possible to track such 
references, especially with units that are pre-compiled.


Gareth aka. Kit

On 16/10/2021 15:32, Jonas Maebe via fpc-devel wrote:

On 13/10/2021 19:33, J. Gareth Moreton via fpc-devel wrote:
I figure this would be a whole-program optimization though due to 
inter-unit calls and comparisons and the like.


Usually this is an optimisation that is performed at link-time because 
you don't need any compiler-level information for it. And then it can 
also consider code from statically linked libraries etc. Most standard 
linkers don't have support for it, but link-time optimisation 
frameworks generally do.


One thing you have to be mindful of is that if the address of a 
routine gets taken in any way then you cannot merge it anymore, 
because there might be a comparison somewhere in the program such as


if procvar = @myproc then
  ..
end;

and if myproc gets merged with other routines, then this will return 
true in more cases.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread Jonas Maebe via fpc-devel

On 13/10/2021 19:33, J. Gareth Moreton via fpc-devel wrote:
I figure this would be a whole-program optimization though due to 
inter-unit calls and comparisons and the like.


Usually this is an optimisation that is performed at link-time because 
you don't need any compiler-level information for it. And then it can 
also consider code from statically linked libraries etc. Most standard 
linkers don't have support for it, but link-time optimisation frameworks 
generally do.


One thing you have to be mindful of is that if the address of a routine 
gets taken in any way then you cannot merge it anymore, because there 
might be a comparison somewhere in the program such as


if procvar = @myproc then
  ..
end;

and if myproc gets merged with other routines, then this will return 
true in more cases.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Merging identical procedure proposals

2021-10-16 Thread Benito van der Zander via fpc-devel

Hi,

 that is a great idea

It especially useful for generics, where each specialization can create 
a huge amount of identical methods


Best,
Benito
On 13.10.21 19:33, J. Gareth Moreton via fpc-devel wrote:

Hi everyone,

So one optimisation that has cropped up a couple of times is finding 
ways to merge subroutines that, while containing different source 
code, compile into the exact same assembly language.  For example, 
TStream.WriteData has implementations for numerous input types, and 
the compilation of "function TStream.WriteData(const Buffer: 
WideChar): NativeInt;", "function TStream.WriteData(const Buffer: 
Int16): NativeInt;", "function TStream.WriteData(const Buffer: 
UInt16): NativeInt;" all produce the following:


    leaq    -40(%rsp),%rsp
.seh_stackalloc 40
.seh_endprologue
    movq    %rcx,%rax
    movw    %dx,32(%rsp)
    leaq    32(%rsp),%rdx
    movl    $2,%r8d
    movq    (%rax),%rax
    call    *264(%rax)
    movslq    %eax,%rax
    nop
    leaq    40(%rsp),%rsp
    ret
.seh_endproc

As you can imagine, having the compiler only keep one copy of the code 
and redirect all relevant calls to it will reduce code size 
significantly for no speed penalty.


One thought I had was to keep a "code hash" for each subroutine that's 
computed via digesting the assembly language, although I'm not quite 
sure how it should handle labels.  If two hashes are identical, the 
procedures are checked more closely to determine if they are actually 
identical and it wasn't just a collision.


I figure this would be a whole-program optimization though due to 
inter-unit calls and comparisons and the like.


Gareth aka. Kit


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel