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


--
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

Reply via email to