Module Fang_ir.Pretty

Pretty-printing IR fragments.

type _ t

A pretty-printer for an IR fragment.

Pretty-printing

val pp : box Fmt.t -> value t Fmt.t

Building pretty-printers

include IR with type 'a t := 'a t
type _ t

Values

Values are 64 bit signed integers. They have type value t.

val const : int64 -> value t

A constant integer.

val add : value t -> value t -> value t

Addition.

val sub : value t -> value t -> value t

Subtraction.

val mul : value t -> value t -> value t

Multiplication.

val div : value t -> value t -> value t

Division.

val box : box -> value t

box b is the value currently stored in b.

val mem : value t -> value t

mem v is the value currently stored in memory at address v.

val loc : label -> value t

loc l is the address of the label l in memory.

val perform : effect t -> value t -> value t

perform e v is the value v after the effect e has been performed.

val call : value t -> value t list -> value t

call v vs is the result of invoking the subroutine at memory address v with the values vs as arguments.

Effects

val move : value t -> value t -> effect t

Move a value into a location.

move v1 v2 is valid when v1 evaluates to either:

  • box b, which stores v2 in b
  • mem addr, which stores v2 in memory at address addr
val def : label -> effect t

Define a label for the current memory address.

val discard : value t -> effect t

Ignore a value.

val seq : effect t -> effect t -> effect t

seq e1 e2 is the effect of first performing e1 and then performing e2.

val cjump : rel -> value t -> value t -> label -> label -> effect t

Continue execution at one of two labels, based on a relation between values.

cjump rel v1 v2 l1 l2 compares v1 and v2 according to rel. If the relation holds then execution continues at the location of l1. Otherwise, execution continues at the location of l2.

val jump : label -> effect t

Continue execution at the location of a label.

Note: Appel's jump is more complex: his takes the value of an address to jump to and a list of all possible labels that the address is referring to. The reason for this complexity is to support jumping to an address which is the result of a calculation, like a switch statement in the C programming language. For example, we may calculate the address to jump to from a base address and an offset. We must still know all the possible labels that the calculation could resolve to because that information is needed for data-flow analysis. Tiger doesn't need such functionality so we keep things simple.