Skip to content

fxpl/trieste-miniml

Repository files navigation

MiniML-Trieste

This project implements a MiniML to LLVM IR compiler in Trieste.

The frontend for MiniML as defined by https://plzoo.andrej.com/language/miniml.html but without mandatory type annotations of functions.

Compiling the project and running the executable

To build using make (note that you still need to have ninja installed for this to work):

make

otherwise, do

mkdir build && cd build
cmake -G Ninja ../src -DCMAKE_CXX_COMPILER=clang++
ninja

to run main on a file filename located in the /examples/ folder:

make buildf f=filename 

a corresponding .trieste file will be written to out/filename.trieste and the compiled .ll file will be written to out/filename.ll.

Requirements

This project includes LLVM in order to perform generation of LLVM IR code. For Ubuntu the following apt packages are required:

  • make
  • cmake
  • ninja-build
  • clang
  • llvm (might be included in clang package)
  • zlib1g-dev (LLVM dependency)
  • libzstd-dev (LLVM dependency)

Delimitations

In its current state, the compiler only supports monomorphic MiniML programs. Any programs containing a polymorphic type will generate an error and will not be compiled to LLVM IR. Additionally, the language runtime leaks memory as heap-allocation of closures is unmanaged.

Commands for testing

To run the compiler on all .miniml files within the /examples/ directory, run:

make test

To run the compiler on the test file within /examples/llvmir_tests/, run.

make llvm

The command generates a trieste AST representation in out/test.trieste, an equivalent LLVM IR program in out/test.ll and finally a compiled executable in out/test.out. The executable prints a sequence of boolean values followed by return value of the executable to stdout. True indicates a successful test, Fail indicates a failed test.

Benchmarking

The implementation is benchmarked by generating and compiling a series of random MiniML programs, measuring the compiler's runtime using Trieste's built-in Info mode. At the end of the experiment a latex-formatted table and graphic plot of average compile time and standard deviation per program size and compiler stage are generated.

The structure of generated MiniML programs is defined in miniml_generator.py. The size of programs and number of times to generate and compile programs of each size is configurable within the run_experiments.py script.

Initialize a virtual environment by running the following commands: python3 -m venv venv source venv/bin/activate

Install required dependencies by running: pip install pandas matplotlib

To start the experiment, run:

make experiment

Reusing the LLVM IR generation logic in other Trieste projects

The code generation pass and AST representation of LLVM IR included in this project are intended to serve as a basis for a reusable LLVM IR code generation framework, suitable for other Trieste projects.

The code generation pass requires the input AST to adhere the well-formedness specification listed in llvm-lang.hh. Thus, the AST generated by the frontend of another source language must be transformed according to this specification before being passed to the code generation pass.

To use the code generation pass as a basis for emitting LLVM IR in another Trieste project, include the following files into your project:

  • src/llvm-lang.hh: Tokens and well-formedness specification for the AST representation of LLVM IR serving as input to the code generation pass.
  • src/passes/llvm-ir/code_generation.cc: The code generation pass.
  • src/runtime.cc and src/runtime.hh: Functionality required by the runtime (depends on source language and compiler implementation).
  • src/passes/llvm_utils.cc and src/passes/llvm_utils.hh: Helper functions for the code generation pass.

Note: The listed files only provide support for the subset of LLVM IR required to allow compilation of MiniML. As such, both changes and extensions to file contents might be required in order to support the subset of LLVM IR required by the source language and implementation details of other Trieste projects.

The runtime functionality (if any) is specific to the source language and the compiler implementation. Thus, runtime.cc needs to be adapted to suit the current Trieste project. Perform the following tasks to adapt the runtime to your project:

  • Define creation of the language runtime's functions and data structures in genRuntimeFunctions.
  • Define any imports of external functions (e.g. malloc and free from C) in genExternalFunctions.

About

Trieste implementation of MiniML with type inference

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages