/dmjit

.dmJIT is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle! (formerly known as dm-jitaux)

Primary LanguageRustGNU Affero General Public License v3.0AGPL-3.0

WIP PRs Welcome

.dmJIT

.dmJIT is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle (such as rewriting/refactoring your DM code).

Implementation status

Roadmap

  • PoC ✔️
  • Deoptimization ✔️
  • Sleeping proc deoptimization
  • Calls ✔️
  • Virtual calls ✔️
  • Type probing deoptimization
  • Heterogenous instruction optimization
  • JITed-to-JITed direct calls
  • Tiering
  • Branch / Call counting
  • Sleeping proc support

Opcodes

OpCode Status
GetVar SetCache, Field, Src, Local, Arg
SetVar SetCache, Field, Local, Arg
Add Float
Sub Float
Tg Float
Tl Float
Tge Float
Tle Float
AugAdd Float
AugSub Float
Teq ✔️
Ret ✔️
End ✔️
Test ✔️
Jz ✔️
JmpOr ✔️
JmpAnd ✔️
Jmp ✔️
PushInt ✔️
PushVal ✔️
GetFlag ✔️
Pop ✔️
IsNull ✔️
Not ✔️
Mul Float
CallGlobal No sleep deopt
Call StaticProc, DynamicProc, No sleep deopt
CallStatement StaticProc, DynamicProc, No sleep deopt
Abs ✔️
RoundN ✔️

Dependencies

These instructions were taken directly from tgstation's rust-g documentation.

The Rust compiler:

  1. Install the Rust compiler's dependencies (primarily the system linker):

  2. Use the Rust installer, or another Rust installation method, or run the following:

    curl https://sh.rustup.rs -sSfo rustup-init.sh
    chmod +x rustup-init.sh
    # Nightly toolchain is required
    ./rustup-init.sh

    Alternatively without saving

    # Nightly toolchain is required
    curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly
  3. Set the default compiler to 32-bit:

    # Clone the `dm-jitaux` repository to a directory of your choice
    git clone https://github.com/ss220-space/dm-jitaux.git
    # in the `dm-jitaux` directory...
    cd dm-jitaux
    # Linux
    rustup target add i686-unknown-linux-gnu
    # Windows
    rustup target add i686-pc-windows-msvc
    
    # Clone the `auxtools` repository to a parent directory of dm-jitaux
    cd ..
    git clone https://github.com/ss220-space/auxtools.git --branch dm-jitaux
    # in the `auxtools` directory...
    cd auxtools
    # Linux
    rustup target add i686-unknown-linux-gnu
    # Windows
    rustup target add i686-pc-windows-msvc

System libraries:

  • Ubuntu and Debian users run:

    sudo dpkg --add-architecture i386
    sudo apt-get update
    sudo apt-get install zlib1g-dev:i386 libssl-dev:i386 pkg-config:i386
    sudo apt-get install gcc-multilib g++-multilib
  • Other Linux distributions install the appropriate 32-bit development and 32-bit runtime packages.

Building

LLVM

Windows

CMake required, can be downloaded from cmake.org

You need to build LLVM 12.0.0 on Windows with x32 target and MD CRT linking

Note: It takes 30-60 minutes to compile, 23 GB of free disk space

Download from LLVM github releases

# Unpack to path without spaces 
tar -xJf llvm-12.0.0.src.tar.xz
# Create build directory
mkdir build
cd build
# Configure 
cmake -DCMAKE_INSTALL_PREFIX=C:/LLVM -DLLVM_USE_CRT_DEBUG=MD -DLLVM_TARGETS_TO_BUILD="X86" -Thost=x86 -A Win32 ../llvm-12.0.0.src/
# Build
cmake --build .
# Install to CMAKE_INSTALL_PREFIX
cmake --build . --target install

Full guide: Building LLVM with CMake

Debian

sudo apt install llvm-12-dev:i386

Other

Checkout this for more info.

Compiling

Windows

# PowerShell
$env:LLVM_SYS_120_PREFIX = "C:\LLVM" # LLVM prefix specified before
cargo build --target i686-pc-windows-msvc
cargo test --target i686-pc-windows-msvc -- --test-threads=1

Linux

cargo build --target i686-unknown-linux-gnu
BYOND_PATH="~/byond" cargo test --target i686-unknown-linux-gnu -- --test-threads=1

See also

DM Opcode relative frequency table

opcode_counts.txt

License

dm-jitaux is licensed under the AGPL-3.0 License. See LICENSE for more details.