(* This functor implements the central part of the translation of [RTL] to [ERTL]. It is called once for each procedure or function. It defines the translation of instructions as well as the prologue and epilogue that should be added to the procedure. *) module Make (Env : sig (* [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: ERTL.instruction -> Label.t (* [formals] is a list of the procedure's formal arguments. *) val formals: Register.t list (* [entry] is the procedure's original entry point. *) val entry: Label.t (* [result] tells whether this is a procedure or a function and, in the latter case, which pseudo-register holds the function's result when the exit label is reached. *) val result: Register.t option (* [is_self callee] determines whether [callee] refers to the current procedure or function. This can be used to recognize tail calls to self and turn them into jumps. *) val is_self: Primitive.callee -> bool end) : sig (* [translate_call odestr callee actuals l] translates the [RTL] instruction [ICall (odestr, callee, actuals, l)] into an [ERTL] sequence of instructions that transfers control to [l]. *) val translate_call: Register.t option -> Primitive.callee -> Register.t list -> Label.t -> Label.t (* [prologue] will be inserted in front of the existing code. It should transfer control to the procedure's original entry point [entry]. *) val prologue: Label.t (* [epilogue] will be appended at the end of the existing code. It should end with an [IReturn] instruction. *) val epilogue: Label.t (* [translate_tail_call callee actuals] translates the [RTL] instruction [ITailCall (callee, actuals)] into an [ERTL] sequence of instructions. *) val translate_tail_call: Primitive.callee -> Register.t list -> Label.t end