Code Generation

In this part of the project we will translate a MiniJava AST into equivalent code in the intermediate representation used by the LLVM compiler project.

Usage

java -jar mjavac.jar unmarshal compile inputProg.xml out.ll

will write to out.ll a translation of program represented by inputProg.xml into the textual format of LLVM IR.

Examples

Here (see the readme).

LLVM assembly/IR

The LLVM language is documented in the LLVM Language Reference Manual, although you will use only a subset of the instructions, which is described below.

Execution

An LLVM assembly/IR textual file (*.ll) can be executed in at least 3 ways on an Ubuntu machine:
  1. Interpreted directly using the lli tool:
    lli <prog>.ll
    On Ubuntu, it can be installed by sudo apt install llvm-runtime. Make sure lli -version prints version 6.0.0 or higher (otherwise the distribution you're using is too old).

  2. Compiled to the native assembly and executed:
    clang -o out code.ll
    ./out
    On Ubuntu, it can be installed by sudo apt install clang. Make sure clang --version prints version 6.0.0 or higher (otherwise the distribution you're using is too old).

  3. There is also an online interpreter by TIO.

Types

Instructions

Generating Code from a Well-Typed MiniJava AST

Given an AST of a well-typed MiniJava program, your task is to generate a program in LLVM assembly/IR that has the same behavior.

Defined and Undefined Behavior

(Or, "Assume that Everything is OK, And Make Sure Everything is OK")

Memory

Static Typing Information Required for Code Generation

Helper Functions for Your Convenience

You may define the following helper methods once in your output files, in order to be able to call @calloc, @print_int and @throw_oob.
declare i8* @calloc(i32, i32)
declare i32 @printf(i8*, ...)
declare void @exit(i32)

@_cint = constant [4 x i8] c"%d\0a\00"
@_cOOB = constant [15 x i8] c"Out of bounds\0a\00"
define void @print_int(i32 %i) {
    %_str = bitcast [4 x i8]* @_cint to i8*
    call i32 (i8*, ...) @printf(i8* %_str, i32 %i)
    ret void
}

define void @throw_oob() {
    %_str = bitcast [15 x i8]* @_cOOB to i8*
    call i32 (i8*, ...) @printf(i8* %_str)
    call void @exit(i32 1)
    ret void
}

Tips

Submission guidelines

As specified for all assignments. The LLVM code you generate has to execute without errors with LLVM 6.0.0.

Good luck!