From 9ac4b110566bc1f8346260edd6917f747d749c42 Mon Sep 17 00:00:00 2001 From: Rohan Jacob-Rao Date: Fri, 31 Jul 2015 22:13:47 -0700 Subject: [PATCH] Translation of load instruction. --- infer/src/llvm/examples/load_func.ll | 5 +++++ infer/src/llvm/lAst.ml | 3 ++- infer/src/llvm/lLexer.mll | 2 +- infer/src/llvm/lParser.mly | 3 ++- infer/src/llvm/lTrans.ml | 13 ++++++++----- 5 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 infer/src/llvm/examples/load_func.ll diff --git a/infer/src/llvm/examples/load_func.ll b/infer/src/llvm/examples/load_func.ll new file mode 100644 index 000000000..bc69f89eb --- /dev/null +++ b/infer/src/llvm/examples/load_func.ll @@ -0,0 +1,5 @@ +; Definition of main function +define i32 @main() { + %a = load i32* %b + ret i32 0 +} diff --git a/infer/src/llvm/lAst.ml b/infer/src/llvm/lAst.ml index de2d378ad..a04e66614 100644 --- a/infer/src/llvm/lAst.ml +++ b/infer/src/llvm/lAst.ml @@ -34,11 +34,12 @@ type instr = | Ret of (typ * operand) option | UncondBranch of variable | CondBranch of operand * variable * variable + | Load of variable * typ * variable | Store of operand * typ * variable type func_def = FuncDef of variable * typ option * (typ * string) list * instr list type prog = Prog of func_def list -let name_of_variable : variable -> string = function +let string_of_variable : variable -> string = function | Global str | Local str -> str diff --git a/infer/src/llvm/lLexer.mll b/infer/src/llvm/lLexer.mll index 088bc3eef..a82c63211 100644 --- a/infer/src/llvm/lLexer.mll +++ b/infer/src/llvm/lLexer.mll @@ -120,7 +120,7 @@ rule token = parse (*| "insertvalue" { INSERTVALUE }*) (* memory access and addressing operations *) (*| "alloca" { ALLOCA }*) - (*| "load" { LOAD }*) + | "load" { LOAD } | "store" { STORE } (*| "fence" { FENCE }*) (*| "cmpxchg" { CMPXCHG }*) diff --git a/infer/src/llvm/lParser.mly b/infer/src/llvm/lParser.mly index 75caa6f76..0c80d909e 100644 --- a/infer/src/llvm/lParser.mly +++ b/infer/src/llvm/lParser.mly @@ -95,7 +95,7 @@ (*%token INSERTVALUE*) (* memory access and addressing operations *) (*%token ALLOCA*) -(*%token LOAD*) +%token LOAD %token STORE (*%token FENCE*) (*%token CMPXCHG*) @@ -184,6 +184,7 @@ block: instr: | term=terminator { term } | variable EQUALS binop { Ret None } (* TODO *) + | var=variable EQUALS LOAD tp=ptr_typ ptr=variable { Load (var, tp, ptr) } | STORE val_tp=typ value=operand COMMA ptr_tp=ptr_typ var=variable { Store (value, val_tp, var) } (* don't yet know why val_tp and ptr_tp would be different *) diff --git a/infer/src/llvm/lTrans.ml b/infer/src/llvm/lTrans.ml index 64eefa72a..a860cfb0f 100644 --- a/infer/src/llvm/lTrans.ml +++ b/infer/src/llvm/lTrans.ml @@ -11,9 +11,10 @@ open LAst exception ImproperTypeError of string exception Unimplemented of string -let trans_variable : LAst.variable -> Sil.exp = function (* TODO: use unique stamps *) - | Global id -> Sil.Var (Ident.create_normal (Ident.string_to_name id) 0) - | Local id -> Sil.Var (Ident.create_normal (Ident.string_to_name id) 0) +let ident_of_variable (var : LAst.variable) : Ident.t = (* TODO: use unique stamps *) + Ident.create_normal (Ident.string_to_name (LAst.string_of_variable var)) 0 + +let trans_variable (var : LAst.variable) : Sil.exp = Sil.Var (ident_of_variable var) let trans_constant : LAst.constant -> Sil.exp = function | Cint i -> Sil.Const (Sil.Cint (Sil.Int.of_int i)) @@ -37,6 +38,8 @@ let trans_instr (cfg : Cfg.cfg) (pdesc : Cfg.Procdesc.t) : LAst.instr -> Sil.ins | Ret (Some (tp, exp)) -> let ret_var = Sil.get_ret_pvar (Cfg.Procdesc.get_proc_name pdesc) in [Sil.Set (Sil.Lvar ret_var, trans_typ tp, trans_operand exp, Sil.dummy_location)] + | Load (var, tp, ptr) -> + [Sil.Letderef (ident_of_variable var, trans_variable ptr, trans_typ tp, Sil.dummy_location)] | Store (op, tp, var) -> [Sil.Set (trans_variable var, trans_typ tp, trans_operand op, Sil.dummy_location)] | _ -> raise (Unimplemented "Need to translate instruction to SIL.") @@ -60,7 +63,7 @@ let trans_func_def (cfg : Cfg.cfg) (cg: Cg.t) : LAst.func_def -> unit = function let (procdesc_builder : Cfg.Procdesc.proc_desc_builder) = let open Cfg.Procdesc in { cfg = cfg; - name = Procname.from_string_c_fun (LAst.name_of_variable func_name); + name = Procname.from_string_c_fun (LAst.string_of_variable func_name); is_defined = true; (** is defined and not just declared *) proc_attributes = proc_attrs; ret_type = (match ret_tp_opt with @@ -78,7 +81,7 @@ let trans_func_def (cfg : Cfg.cfg) (cg: Cg.t) : LAst.func_def -> unit = function let exit_kind = Cfg.Node.Exit_node procdesc in let exit_node = Cfg.Node.create cfg Sil.dummy_location exit_kind [] procdesc [] in let nodekind_of_instr : LAst.instr -> Cfg.Node.nodekind = function - | Ret _ | Store _ -> Cfg.Node.Stmt_node "method_body" + | Ret _ | Load _ | Store _ -> Cfg.Node.Stmt_node "method_body" | _ -> raise (Unimplemented "Need to get node type for instruction.") in let node_of_instr (cfg : Cfg.cfg) (procdesc : Cfg.Procdesc.t) (instr : LAst.instr) : Cfg.Node.t = Cfg.Node.create cfg Sil.dummy_location (nodekind_of_instr instr) (trans_instr cfg procdesc instr) procdesc [] in