On this page:
2.6.1 Milestone Summary
2.6.1.1 Learning Objectives
2.6.1.2 Checklist
2.6.2 Reading
2.6.3 Exercises
2.6.4 Validators and interpreters
2.6.5 Optional Exercises
8.10

2.6 Milestone 5: Adding Call

2.6.1 Milestone Summary

The goals of this milestone are to (1) introduce the procedure call abstraction (2) introduce calling conventions, an abstraction for compiling procedure calls In the process, we’ll learn a different approach to compiler design. Rather than building up layers of abstractions bottom-up, we consider how to compile a designed feature top-down. We’ll introduce an abstraction and consider how to design translations to lower the new an abstraction to existing features.

You can use the interrogator to get limited access to the reference solution: https://soft.vub.ac.be/compilers/interrogator?an=a5.

2.6.1.1 Learning Objectives
2.6.1.2 Checklist

Completely new passes

Major modifications

Minor modifications

No modifications

Removed passes
  • assign-fvars

  • assign-homes

2.6.2 Reading

The reading for this week is Procedural Abstraction: Call. As usual, this milestone description links to the documentation for each exercise in the chapter for convenience, but you are responsible for the reading the entire chapter.

2.6.3 Exercises

Exercise 1: Extend uniquify to support procedure calls in the source language. To compile procedure names, you should use fresh-label.

Exercise 2: Extend sequentialize-let with support for procedure definitions and tail calls.

Exercise 3: Extend normalize-bind with support for procedure definitions and tail calls.

Exercise 4: Design and implement impose-calling-conventions

You should use current-parameter-registers and current-return-value-register rather than hard-coding the calling convention registers. Try to reduce register pressure by ordering movs when compiling the calling convention.

Exercise 5: Extend select-instructions with support for blocks and the jump instruction.

Exercise 6: Extend uncover-locals with support for blocks and the jump instruction.

Exercise 7: Extend undead-analysis with support for blocks and the jump instruction.

Exercise 8: Extend conflict-analysis with support for blocks and the jump instruction.

Exercise 9: Extend assign-registers with support for blocks and the jump instruction.

Exercise 10: Extend replace-locations with support for blocks and the jump instruction.

Exercise 11: Extend expose-basic-blocks with support for blocks and the jump instruction in the source.

2.6.4 Validators and interpreters

In these exercises you extend the well-formedness checkers and the interpreters for the source language. Generic definitions are given for these by default which you have to replace with your own implementations. You should however prioritize the exercises above, which do not have default implementation and are therefore more important for obtaining a fully functioning compiler pipeline.

Exercise 12: Extend the function interp-values-lang, an interpreter for Values-lang v5.

Exercise 13: Design and implement check-values-lang to validate the safety of source programs. Remember that you will have to reject some safe programs.

2.6.5 Optional Exercises

Exercise 14 (optional): Extend assign-fvars to take conflicts from the calling convention into account and thereby preserve the unoptimized assign-homes pass. Note: This functionality will become necessary when you implement Procedural Abstraction: Return.