[sledge] Add unique int ids to Llair registers

Summary:
While translating LLVM to LLAIR, compute unique integer ids for
registers.

Reviewed By: jvillard

Differential Revision: D26250534

fbshipit-source-id: 6253f38c7
master
Josh Berdine 4 years ago committed by Facebook GitHub Bot
parent 6010ec45b2
commit 0534623a63

@ -249,7 +249,7 @@ let call ~summaries ~globals:_ ~actuals ~areturn ~formals ~freturn:_
todo "Summaries not yet implemented for interval analysis" () todo "Summaries not yet implemented for interval analysis" ()
else else
let mangle r = let mangle r =
Llair.Reg.mk (Llair.Reg.typ r) ("__tmp__" ^ Llair.Reg.name r) Llair.Reg.mk (Llair.Reg.typ r) 0 ("__tmp__" ^ Llair.Reg.name r)
in in
let args = IArray.combine_exn formals actuals in let args = IArray.combine_exn formals actuals in
let q' = let q' =

@ -54,6 +54,19 @@ let invalid_llvm : string -> 'a =
(* gather names and debug locations *) (* gather names and debug locations *)
(* number of register ids used so far *)
let sym_count = ref 0
(* map frontend-synthesized register names to ids, registers that come from
LLVM are stored in sym_tbl *)
let id_memo = String.Tbl.create ()
(* lookup or generate the id for a frontend-synthesized register name *)
let get_id name =
String.Tbl.find_or_add id_memo name ~default:(fun () ->
incr sym_count ;
!sym_count )
module LlvalueTbl = HashTable.Make (struct module LlvalueTbl = HashTable.Make (struct
type t = Llvm.llvalue type t = Llvm.llvalue
@ -62,7 +75,8 @@ end)
module SymTbl = LlvalueTbl module SymTbl = LlvalueTbl
let sym_tbl : (string * Loc.t) SymTbl.t = SymTbl.create ~size:4_194_304 () let sym_tbl : (string * int * Loc.t) SymTbl.t =
SymTbl.create ~size:4_194_304 ()
module ScopeTbl = HashTable.Make (struct module ScopeTbl = HashTable.Make (struct
type t = [`Fun of Llvm.llvalue | `Mod of Llvm.llmodule] type t = [`Fun of Llvm.llvalue | `Mod of Llvm.llmodule]
@ -129,9 +143,9 @@ open struct
| None -> () | None -> ()
| Some scope -> ( | Some scope -> (
match SymTbl.find sym_tbl llv with match SymTbl.find sym_tbl llv with
| Some (name, loc0) -> | Some (name, id, loc0) ->
if Loc.equal loc0 Loc.none then if Loc.equal loc0 Loc.none then
SymTbl.set sym_tbl ~key:llv ~data:(name, loc) SymTbl.set sym_tbl ~key:llv ~data:(name, id, loc)
| None -> | None ->
let name = let name =
if Poly.(Llvm.classify_type (Llvm.type_of llv) = Void) then if Poly.(Llvm.classify_type (Llvm.type_of llv) = Void) then
@ -173,11 +187,13 @@ open struct
"\"" ^ name ^ "\"" "\"" ^ name ^ "\""
| None -> name ) | None -> name )
in in
SymTbl.set sym_tbl ~key:llv ~data:(name, loc) ) let id = 1 + SymTbl.length sym_tbl in
SymTbl.set sym_tbl ~key:llv ~data:(name, id, loc) )
end end
let scan_names_and_locs : Llvm.llmodule -> unit = let scan_names_and_locs : Llvm.llmodule -> unit =
fun m -> fun m ->
assert (!sym_count = 0) ;
let scan_global g = add_sym g (loc_of_global g) in let scan_global g = add_sym g (loc_of_global g) in
let scan_instr i = let scan_instr i =
let loc = loc_of_instr i in let loc = loc_of_instr i in
@ -206,19 +222,21 @@ open struct
Llvm.iter_blocks scan_block f Llvm.iter_blocks scan_block f
in in
Llvm.iter_globals scan_global m ; Llvm.iter_globals scan_global m ;
Llvm.iter_functions scan_function m Llvm.iter_functions scan_function m ;
sym_count := SymTbl.length sym_tbl
let find_name : Llvm.llvalue -> string = let find_name : Llvm.llvalue -> string * int =
fun v -> fun v ->
fst (SymTbl.find_exn sym_tbl v) let name, id, _ = SymTbl.find_exn sym_tbl v in
$> fun s -> assert (not (String.is_empty s)) assert (not (String.is_empty name)) ;
(name, id)
let find_loc : Llvm.llvalue -> Loc.t = let find_loc : Llvm.llvalue -> Loc.t =
fun v -> snd (SymTbl.find_exn sym_tbl v) fun v -> trd3 (SymTbl.find_exn sym_tbl v)
end end
let label_of_block : Llvm.llbasicblock -> string = let label_of_block : Llvm.llbasicblock -> string =
fun blk -> find_name (Llvm.value_of_block blk) fun blk -> fst (find_name (Llvm.value_of_block blk))
module LltypeTbl = HashTable.Make (struct module LltypeTbl = HashTable.Make (struct
type t = Llvm.lltype type t = Llvm.lltype
@ -368,7 +386,8 @@ let xlate_float : x -> Llvm.llvalue -> Exp.t =
let xlate_name x : Llvm.llvalue -> Reg.t = let xlate_name x : Llvm.llvalue -> Reg.t =
fun llv -> fun llv ->
let typ = xlate_type x (Llvm.type_of llv) in let typ = xlate_type x (Llvm.type_of llv) in
Reg.mk typ (find_name llv) let name, id = find_name llv in
Reg.mk typ id name
let xlate_name_opt : x -> Llvm.llvalue -> Reg.t option = let xlate_name_opt : x -> Llvm.llvalue -> Reg.t option =
fun x instr -> fun x instr ->
@ -476,8 +495,9 @@ and xlate_value ?(inline = false) : x -> Llvm.llvalue -> Inst.t list * Exp.t
| Function -> | Function ->
( [] ( []
, Exp.function_ , Exp.function_
(Function.mk (xlate_type x (Llvm.type_of llv)) (find_name llv)) (Function.mk
) (xlate_type x (Llvm.type_of llv))
(fst (find_name llv))) )
| GlobalVariable -> ([], Exp.global (xlate_global x llv).name) | GlobalVariable -> ([], Exp.global (xlate_global x llv).name)
| GlobalAlias -> xlate_value x (Llvm.operand llv 0) | GlobalAlias -> xlate_value x (Llvm.operand llv 0)
| ConstantInt -> ([], xlate_int x llv) | ConstantInt -> ([], xlate_int x llv)
@ -512,8 +532,8 @@ and xlate_value ?(inline = false) : x -> Llvm.llvalue -> Inst.t list * Exp.t
let pre, args = xlate_values x len (Llvm.operand llv) in let pre, args = xlate_values x len (Llvm.operand llv) in
(pre, Exp.record typ args) (pre, Exp.record typ args)
| BlockAddress -> | BlockAddress ->
let parent = find_name (Llvm.operand llv 0) in let parent, _ = find_name (Llvm.operand llv 0) in
let name = find_name (Llvm.operand llv 1) in let name, _ = find_name (Llvm.operand llv 1) in
([], Exp.label ~parent ~name) ([], Exp.label ~parent ~name)
| UndefValue -> | UndefValue ->
let llt = Llvm.type_of llv in let llt = Llvm.type_of llv in
@ -522,7 +542,8 @@ and xlate_value ?(inline = false) : x -> Llvm.llvalue -> Inst.t list * Exp.t
todo "types with undetermined size: %a" pp_lltype llt () ; todo "types with undetermined size: %a" pp_lltype llt () ;
let name = Printf.sprintf "undef_%i" !undef_count in let name = Printf.sprintf "undef_%i" !undef_count in
let loc = Loc.none in let loc = Loc.none in
let reg = Reg.mk typ name in let id = get_id name in
let reg = Reg.mk typ id name in
let msg = Llvm.string_of_llvalue llv in let msg = Llvm.string_of_llvalue llv in
([Inst.nondet ~reg:(Some reg) ~msg ~loc], Exp.reg reg) ([Inst.nondet ~reg:(Some reg) ~msg ~loc], Exp.reg reg)
| Instruction | Instruction
@ -772,7 +793,9 @@ and xlate_global : x -> Llvm.llvalue -> GlobalDefn.t =
GlobTbl.find_or_add memo_global llg ~default:(fun () -> GlobTbl.find_or_add memo_global llg ~default:(fun () ->
[%Trace.call fun {pf} -> pf "@ %a" pp_llvalue llg] [%Trace.call fun {pf} -> pf "@ %a" pp_llvalue llg]
; ;
let g = Global.mk (xlate_type x (Llvm.type_of llg)) (find_name llg) in let g =
Global.mk (xlate_type x (Llvm.type_of llg)) (fst (find_name llg))
in
let loc = find_loc llg in let loc = find_loc llg in
(* add to tbl without initializer in case of recursive occurrences in (* add to tbl without initializer in case of recursive occurrences in
its own initializer *) its own initializer *)
@ -1142,7 +1165,7 @@ let xlate_instr :
(* general function call that may not throw *) (* general function call that may not throw *)
| _ -> | _ ->
let typ = xlate_type x lltyp in let typ = xlate_type x lltyp in
let name = find_name instr in let name, _ = find_name instr in
let lbl = name ^ ".ret" in let lbl = name ^ ".ret" in
let pre_1, actuals = let pre_1, actuals =
xlate_values x num_actuals (Llvm.operand instr) xlate_values x num_actuals (Llvm.operand instr)
@ -1285,11 +1308,15 @@ let xlate_instr :
eventually jumping to the handler code following the landingpad, eventually jumping to the handler code following the landingpad,
passing a value for the selector which the handler code tests to passing a value for the selector which the handler code tests to
e.g. either cleanup or rethrow. *) e.g. either cleanup or rethrow. *)
let name = find_name instr in let name, _ = find_name instr in
let i32, tip, cxa_exception = landingpad_typs x instr in let i32, tip, cxa_exception = landingpad_typs x instr in
let pi8, _, exc_typ = exception_typs in let pi8, _, exc_typ = exception_typs in
let exc = Exp.reg (Reg.mk pi8 (find_name instr ^ ".exc")) in let exc_name = name ^ ".exc" in
let ti = Reg.mk tip (name ^ ".ti") in let exc_id = get_id exc_name in
let exc = Exp.reg (Reg.mk pi8 exc_id exc_name) in
let ti_name = name ^ ".ti" in
let ti_id = get_id ti_name in
let ti = Reg.mk tip ti_id ti_name in
(* std::type_info* ti = ((__cxa_exception* )exc - 1)->exceptionType *) (* std::type_info* ti = ((__cxa_exception* )exc - 1)->exceptionType *)
let load_ti = let load_ti =
let typ = cxa_exception in let typ = cxa_exception in
@ -1461,7 +1488,7 @@ let report_undefined func name =
let xlate_function_decl x llfunc typ k = let xlate_function_decl x llfunc typ k =
let loc = find_loc llfunc in let loc = find_loc llfunc in
let name = Function.mk typ (find_name llfunc) in let name = Function.mk typ (fst (find_name llfunc)) in
let formals = let formals =
Iter.from_iter (fun f -> Llvm.iter_params f llfunc) Iter.from_iter (fun f -> Llvm.iter_params f llfunc)
|> Iter.map ~f:(xlate_name x) |> Iter.map ~f:(xlate_name x)
@ -1470,11 +1497,15 @@ let xlate_function_decl x llfunc typ k =
let freturn = let freturn =
match typ with match typ with
| Pointer {elt= Function {return= Some typ; _}} -> | Pointer {elt= Function {return= Some typ; _}} ->
Some (Reg.mk typ "freturn") let name = "freturn" in
let id = get_id name in
Some (Reg.mk typ id name)
| _ -> None | _ -> None
in in
let _, _, exc_typ = exception_typs in let _, _, exc_typ = exception_typs in
let fthrow = Reg.mk exc_typ "fthrow" in let exc_name = "fthrow" in
let exc_id = get_id exc_name in
let fthrow = Reg.mk exc_typ exc_id exc_name in
k ~name ~formals ~freturn ~fthrow ~loc k ~name ~formals ~freturn ~fthrow ~loc
let xlate_function : x -> Llvm.llvalue -> Llair.func = let xlate_function : x -> Llvm.llvalue -> Llair.func =

@ -62,7 +62,7 @@ module T = struct
[@@deriving compare, equal, hash, sexp] [@@deriving compare, equal, hash, sexp]
type t = type t =
| Reg of {name: string; typ: Typ.t} | Reg of {id: int; name: string; typ: Typ.t}
| Global of {name: string; typ: Typ.t [@ignore]} | Global of {name: string; typ: Typ.t [@ignore]}
| Function of {name: string; typ: Typ.t [@ignore]} | Function of {name: string; typ: Typ.t [@ignore]}
| Label of {parent: string; name: string} | Label of {parent: string; name: string}
@ -118,7 +118,7 @@ module T = struct
Format.kfprintf (fun fs -> Format.pp_close_box fs ()) fs fmt Format.kfprintf (fun fs -> Format.pp_close_box fs ()) fs fmt
in in
match exp with match exp with
| Reg {name} -> pf "%%%s" name | Reg {name; id} -> pf "%%%s!%i" name id
| Global {name} -> pf "%@%s%a" name pp_demangled name | Global {name} -> pf "%@%s%a" name pp_demangled name
| Function {name} -> pf "&%s%a" name pp_demangled name | Function {name} -> pf "&%s%a" name pp_demangled name
| Label {name} -> pf "%s" name | Label {name} -> pf "%s" name
@ -302,7 +302,7 @@ module Reg = struct
| Reg _ as e -> Some (e |> check invariant) | Reg _ as e -> Some (e |> check invariant)
| _ -> None | _ -> None
let mk typ name = Reg {name; typ} |> check invariant let mk typ id name = Reg {id; name; typ} |> check invariant
end end
(** Globals are the expressions constructed by [Global] *) (** Globals are the expressions constructed by [Global] *)

@ -72,7 +72,7 @@ type opN = Record (** Record (array / struct) constant *)
[@@deriving compare, equal, hash, sexp] [@@deriving compare, equal, hash, sexp]
type t = private type t = private
| Reg of {name: string; typ: Typ.t} (** Virtual register *) | Reg of {id: int; name: string; typ: Typ.t} (** Virtual register *)
| Global of {name: string; typ: Typ.t [@ignore]} (** Global constant *) | Global of {name: string; typ: Typ.t [@ignore]} (** Global constant *)
| Function of {name: string; typ: Typ.t [@ignore]} (** Function name *) | Function of {name: string; typ: Typ.t [@ignore]} (** Function name *)
| Label of {parent: string; name: string} | Label of {parent: string; name: string}
@ -112,7 +112,7 @@ module Reg : sig
include Invariant.S with type t := t include Invariant.S with type t := t
val of_exp : exp -> t option val of_exp : exp -> t option
val mk : Typ.t -> string -> t val mk : Typ.t -> int -> string -> t
val name : t -> string val name : t -> string
val typ : t -> Typ.t val typ : t -> Typ.t
end end

@ -360,7 +360,7 @@ and dummy_func =
"dummy" "dummy"
; formals= IArray.empty ; formals= IArray.empty
; freturn= None ; freturn= None
; fthrow= Reg.mk Typ.ptr "dummy" ; fthrow= Reg.mk Typ.ptr 0 "dummy"
; locals= Reg.Set.empty ; locals= Reg.Set.empty
; entry= dummy_block ; entry= dummy_block
; loc= Loc.none } ; loc= Loc.none }

Loading…
Cancel
Save