CS153/lec06/code/ir5.ml

95 lines
2.1 KiB
OCaml
Raw Normal View History

(* refactoring -------------------------------------------------------------- *)
module IR = struct
(* unify var and fn_name as 'global identifiers' *)
type uid = string (* Unique identifiers for temporaries. *)
type lbl = string
type gid = string (* New! global value identifiers *)
(* "gensym" -- generate a new unique identifier *)
let mk_uid : unit -> uid =
let ctr = ref 0 in
fun () ->
ctr := !ctr + 1;
Printf.sprintf "tmp%d" (!ctr)
(* operands *)
type opn =
| Id of uid
| Const of int64
(* binary arithmetic operations *)
type bop =
| Add
| Mul
(* comparison operations *)
type cmpop =
| Eq
| Lt
(* instructions *)
(* note that there is no nesting of operations! *)
(* pull out the common 'uid' element from these constructors *)
type insn =
| Binop of bop * opn * opn (* Rename let to binop *)
| Load of gid
| Store of gid * opn
| ICmp of cmpop * opn * opn
| Call of gid * (opn list)
| Alloca
type terminator =
| Ret
| Br of lbl (* unconditional branch *)
| Cbr of opn * lbl * lbl (* conditional branch *)
(* Basic blocks *)
type block = { insns: (uid * insn) list; terminator: terminator }
(* Control Flow Graph: a pair of an entry block and a set labeled blocks *)
type cfg = block * (lbl * block) list
type gdecl =
| GInt of int64
(* The only real change is to "factor out" the name of the function
and unify that concept with the "global identifier" names for
gdecl.
*)
type fdecl = { param : uid list; cfg : cfg }
type program = {
gdecls : (gid * gdecl) list;
fdecls : (gid * fdecl) list;
}
module MLMeaning = struct
let add = Int64.add
let mul = Int64.mul
let load (x : int64 ref) = (!x)
let store o (x : int64 ref) = x := o
let icmp cmpop x y = cmpop x y
let eq (x : int64) (y : int64) = x = y
let lt x y = x < y
let ret x = x
let cbr cnd lbl1 lbl2 =
if cnd then lbl1 () else lbl2 ()
let br lbl = lbl ()
let alloca () = ref 0L
let call f x = f x
end
end