Home

Awesome

Diploma

This is an optimizing compiler for the subset of the C99 language producing LLVM assembler. It is my bachelor's diploma work.

There are some examples of compilable code in the directory with tests. All tests can be checked via run_tests script. To do this, one should set the path to the compiler executable via CC_tst variable inside this script. Also, one should change the value of CW39_LLC in this script (see below).

Following optimizations are implemented in this compiler:

Requirements

Following packages are used for code generation. They are optional because all code, that should be generated by them, are already included in this repository.

Building

To build this compiler one should execute following commands, which are common for most CMake projects. Executable binary (cw39) will be placed into the build directory.

mkdir build
cd build
cmake ..
make

By default, all code generators are enabled. But if you don't have such generators installed, the project can be built using already generated source files. To do this, you should call CMake with some of following options:

For example, cmake command can be executed as shown below.

cmake -DCW39_NO_BISON=TRUE -DCW39_NO_GPERF=TRUE ..

Also, if you have troubles with CMake and generators communication, you can generate source codes manually using this Makefile.

Building using Docker

Docker container can be built using the setup.sh script. After the first usage, this command should be executed if Dockerfile has been changed.

Project can be built using the build.sh script. This script will store the final binary and building files in the docker_build directory created by previous script.

Both scripts don't expect arguments and should be executed from project root (where Dockerfile is located). Optionally, one can specify number of threads used by make in the build script (default is 3).

Usage

cw39 [options] <input_file>

Output options

OptionDescription
--pprocPreprocessor output
--astAbstract syntax tree with pseudo graphics
--irIR in readable text format
--cfgCFG representation in the dot language
--llvmLLVM assembly code
--bcLLVM bitcode (binary output)
--asmAssmbly code (only in Unix-based systems)

Each of listed options can accept optional argument with path to file (e.g. --llvm=./out.ll). In this case output will be written into specified file. If path is empty or -, output will be written into stdout. Without any of these options, compiler will print nothing but errors.

Compilation options

OptionDescription
-D <macro>Define a macro with optional value
-O <lvl>Set optimization level (0-2, default is 2)
--no-s1Disable special optimization 1 (intrinsics detector)
--no-s2Disable special optimization 2 (fixpoints)
--llc-args <args>Specify arguments for llc program

There are following optimization levels:

Note, that specifying any llc argument disables default arguments: -O0 -mcpu=native.

There are some llc arguments, that can be interesting:

Other options

OptionDescription
--timesPrint elapsed time of each step
--tr-scannerEnable scanner debug mode
--tr-parserEnable parser debug mode
--helpPrint help page
--versionPrint compiler version

External programs customization

This compiler uses some external programs via fork-exec calls. This behaviour available only on Unix-based systems and correct working doesn't guarenteed for other ones.

One can specify names for used executables via environment variables listed below.

For example:

export CW39_LLC=llc-13
cw39 --asm test.c
# Or
CW39_LLC=llc-13 cw39 --asm test.c

Examples

Print LLVM code into the terminal:

cw39 --llvm test.c

Print LLVM code into the out.ll file:

cw39 --llvm=out.ll test.c

Execute generated code with arguments 1 and 2 immediately (also lli-13 and others can be used):

cw39 --llvm test.c | lli - 1 2

Draw CFG into the graph.svg file:

cw39 --cfg test.c | dot -Tsvg -o graph.svg

Create executable file from assemly code via clang.

cw39 --asm=test.s test.c
clang test.s
# Or
cw39 --asm test.c | clang -x assembler -
# Or
cw39 --llvm test.c | clang -x ir -

Create executable with LLVM optimizations.

cw39 --asm --llc-args="-O3 -mcpu=native" test.c | clang -x assembler -