Home

Awesome

Wyrm

Wyrm is a GCC GIMPLE to LLVM IR transpiler. I built this as a research project.

Big note: This is an experimental project in an experimental state 🙂

<img align="left" src="https://github.com/jeremy-rifkin/wyrm/raw/main/res/ce.svg" height="30" /> Try it on Compiler Explorer

Simple usage:

mkdir transpiler/build
cd transpiler/build
# Any gcc is fine, it just has to match what you use later
cmake .. -GNinja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11
ninja
g++-11 ../alive-tests/2_basic_integer_arithmetic.cpp -fplugin=./libplugin.so
# or on a gimple file:
#   gcc-11 -fgimple ../alive-tests/2_basic_integer_arithmetic.cpp -fplugin=./libplugin.so
# A bunch of junk will be printed to stdout and llvm ir will be written to x.ll

Example:

int __GIMPLE(ssa)
square(int num) {
  int D_2744;
  int _2;

__BB(2):
  _2 = num_1(D) * num_1(D);
  goto __BB3;

__BB(3):
L0:
  return _2;
}
define noundef i32 @square(i32 noundef %z0) {
    %z1 = or i32 %z0, 0
    br label %bb2
bb2:
    %z2 = mul nsw i32 %z1, %z1
    br label %bb3
bb3:
    ret i32 %z2
}

Some cool things that can be done with a transpiler like this:

I have some primitive wrappers for these but haven't committed them here yet.

The transpiler currently handles most GIMPLE types, instructions, and operators but some things aren't implemented yet. Unsupported features will result in an assertion failure currently.

Differences between GIMPLE and LLVM IR

Through this project I studied semantic and design differences between GIMPLE and LLVM IR and since I haven't seen these written down anywhere so I'm documenting here. All of these are to the best of my understanding:

The last of these, calling conventions, is one of the bigger roadblocks for a full transpilation. I haven't explored implementing target calling conventions yet.