(* This module translates [UPP] instructions into [RTL] control flow graphs. It is parameterized over a module [Env], whose signature appears below, which provides support for mapping local variables to pseudo-registers, allocating fresh pseudo-registers, and generating instructions (which requires allocating fresh control flow graph labels). *) module Make (Env : sig (* [lookup x] returns the pseudo-register that holds the local variable [x]. *) val lookup: string -> Register.t (* [allocate()] returns a fresh pseudo-register. *) val allocate: unit -> Register.t (* [generate instruction] returns a fresh instruction label, which it associates with [instruction] in the control flow graph. *) val generate: RTL.instruction -> Label.t (* [loop target] returns a fresh instruction label [label], which it associates with an unconditional branch instruction whose target is [target label]. *) val loop: (Label.t -> Label.t) -> Label.t (* [is_exit label] tells whether the label [label] is the exit label of the current procedure or function. This can be used to determine which calls are tail calls. *) val is_exit: Label.t -> bool (* [result] is [None] if this is a procedure, and [Some f] if this a function named [f]. *) val result: string option end) : sig (* [translate_instruction i destl] generates new [RTL] instructions whose effect is to execute the [UPP] instruction [i] and to transfer control to the destination label [destl]. It returns the entry label of the newly generated instructions. *) val translate_instruction: UPP.instruction -> Label.t -> Label.t end