Skip to content

alex-s168/vxcc_v3

Repository files navigation

VXCC

optimizing, small, simple, compiler backend.

VXCC uses SSA IR with block arguments instead of the commonly used phi-nodes.

VXCC is licenced under the permissive Apache 2.0 license with LLVM Exceptions

compilation stages

  • frontend generates non-SSA IR
  • backend converts it to SSA
  • backend applies optimizations
  • backend converts it to "LL IR" (non-SSA + labels) and performs some more optimizations
  • simple code generation

goals

  • easily modifyable and readable code
  • not much special knowladge required
  • easy to implement code generation for any architecture
  • make it easy for people to learn about compiler backends
  • good-ish optimizations
  • beat QBE

non-goals

  • reach complexity of GCC or even LLVM
  • beat GCC or LLVM

frontends

current status

goal progress
x86 codegen #33cc33 done but will be re-made
codegen of basic code involving loops #33cc33 done
basic optimizations #33cc33 done
struct support #ff9900 soon
proper register allocator & ISEL rework #ff9900 soon
floating point numbers #cc0000 planned

building

use the ./build.sh build

compile dependencies

clang, gcc, or tcc: automatically detected. different C compiler can be used by doing CC=someothercc ./build.sh [build|test] (test can be executed after build to run all tests)

python3: it is recommended to create a venv in the repository root using python -m venv venv

including into projects

Link with all files returned by ./build.sh libfiles (at time of writing, only build/lib.a)

using VXCC in a compiler

this is meant to be extremely easy to do (for the frontend developer)

There is some documentation in frontend_dev_doc.md. You can also uselook at the C3C fork in the src/compiler/vxcc_* files.

If you have any questions, you can ask me on Discord (alex_s168) or send me an E-Mail

contributing

all contributions are welcome! Don't hesitate to ask me if you have any questions.

please do not currently change anything related to:

  • codegen system / isel & regalloc (because I want to re-do it in a specific way)
  • assembler (^^^)

current optimizations

  • variable inlining
  • duplicate code removal
  • cmoves
  • tailcall
  • simplify loops and ifs
  • simple pattern replacement of bit extract and similar
  • compile time constant eval

code-gen example

input:

fn void strcpy(char* dest, char* src) @export 
{
    for (usz i = 0; src[i] != '\0'; i ++)
        dest[i] = src[i];
}

output:

strcpy:
  xor r11d, r11d
  .l0:
  mov r9b, byte [rsi + 1 * r11]
  test r9b, r9b
  je .l1
  mov byte [rdi + 1 * r11], r9b
  lea r8, [r11 + 1]
  mov r11, r8
  jmp .l0
  .l1:
  ret

This will improve in the close future.

adding a target

You need to complete these tasks (in any order):

  • add your target to every place with the comment // add target. (you can use git grep -Fn "// add target" to find them)
  • write a code generator (see ETC.A or X86 backend as reference) and add the file to the build.c
  • add support for it to frontends?