Lab 5 - static frames

In this lab, we will extend our code generator for our Tiger compiler so that it can access variables declared outside the current function using the static link.

Setup

This lab must be done by enriching the work done in lab 4. The automated tests will run as soon as you create (and add in git) a src/irgen/lab5.check file in your lab4/dragon-tiger directory. This file can be empty, only its presence is required.

Frame creation

  1. Add a new void IRGenerator::generate_frame() method which will be called when analyzing a FunDecl (in irgen.cc). The steps are:

The insertion point should be set to the entry block right after its creation before calling generate_frame(), in IRGenerator::generate_function(),

At this stage, the frame will be created with the right type but will be empty.

Finding the right frame

  1. Add a new std::pair<llvm:StructType *, llvm::Value *> IRGenerator::frame_up(int levels) method (in irgen.cc) which returns either the current frame information (if levels is 0) or the information of one or several levels above (if levels is not 0). The returned pair contains the frame type and an expression to be able to access it.

A way to do it would be:

Frame assignment

  1. It is now time to put escaping variables into the frame. You will create a new llvm::Value *IRGenerator::generate_vardecl(const VarDecl &decl) method (in irgen.cc) which will take care of allocating the variable either in the frame (if it escapes) or in the stack (if it doesn’t escape) and register its address into the allocations map:

Now, you can replace your calls to alloca_in_entry from lab4 to use generate_vardecl instead. Since the tests in lab4 do not use escaping variables, this should not break them. However, you might want to try some code snippets to ensure that escaping variables (and only them and the static link) are stored into the frame.

Find the variable address

  1. Since a variable may have been created in an outer frame, we must use frame_up to find its address. Modify IRGeneratoe::address_of() in order to:

Make sure you use address_of() and not directly allocations in the visitor for Identifier and Assign.

  1. We now must pass the static link to every function which isn’t external (primitives don’t need the static link). To do so, we need to do several things:

If everything goes well, at this stage, you will be able to run code which uses variables defined above the current function.

Congratulations, your compiler is now complete as far as the code generation is concerned.