Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make LEB128 size calculation branchless #29

Merged
merged 1 commit into from
Oct 7, 2023
Merged

Make LEB128 size calculation branchless #29

merged 1 commit into from
Oct 7, 2023

Conversation

PaulusParssinen
Copy link
Contributor

@PaulusParssinen PaulusParssinen commented Sep 28, 2023

I saw this library being references in the C# reimplementation of ObjWriter for ILC/NativeAOT and I noticed the ULEB128 calculations which I knew neat trick for. I learned this trick from Google's AOSP source some years back and been using it since in my own libs.

It uses System.Numerics.BitOperations.LeadingZeroCount, which is not in .NET Standard but is supported from .NET Core 3 and up which also is the lowest supported TFM in .NET Standard 2.1. This is why I added it as TFM to csproj.
edit: Thanks to targeting .NET 7, we can call BitOperations.LeadingZeroCount directly 🎉

x86 Codegen (.NET 7.0)

SizeOfULEB128

; Method LibObjectFile.Dwarf.DwarfHelper:SizeOfULEB128(ulong):uint (FullOpts)
G_M000_IG01:                ;; offset=0x0000

G_M000_IG02:                ;; offset=0x0000
       or       rcx, 1
       xor      eax, eax
       lzcnt    rax, rcx
       neg      eax
       add      eax, 70
       imul     eax, eax, 37
       shr      eax, 8

G_M000_IG03:                ;; offset=0x0016
       ret      
; Total bytes of code: 23

SizeOfILEB128

; Method LibObjectFile.Dwarf.DwarfHelper:SizeOfILEB128(long):uint (FullOpts)
G_M000_IG01:                ;; offset=0x0000

G_M000_IG02:                ;; offset=0x0000
       mov      rax, rcx
       sar      rax, 63
       xor      rax, rcx
       or       rax, 1
       lzcnt    rax, rax
       neg      eax
       add      eax, 71
       imul     eax, eax, 37
       shr      eax, 8

G_M000_IG03:                ;; offset=0x001E
       ret      
; Total bytes of code: 31

This is pretty obscure bit-twiddling hack that I understand completely if it's too much of an premature optimization/hack for this library, just testing waters. 😄

@xoofx
Copy link
Owner

xoofx commented Oct 5, 2023

Sorry, took time to have a look and was not sure to introduce a .NET Core 3 support. So I preferred to switch to net7.0 (latest master)

If you don't mind to recommit a version without the #ifdef and the changes to the csproj?
Thanks!

@PaulusParssinen PaulusParssinen changed the title Make (un)signed LEB128 size calculation branchless for .NET Core 3 and up Make LEB128 size calculation branchless Oct 6, 2023
@xoofx xoofx merged commit e7a51a6 into xoofx:master Oct 7, 2023
@xoofx xoofx added the enhancement New feature or request label Oct 7, 2023
@PaulusParssinen PaulusParssinen deleted the uleb-branchless branch October 8, 2023 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants