diff options
| author | Alasdair Armstrong | 2018-06-13 21:26:35 +0100 |
|---|---|---|
| committer | Alasdair Armstrong | 2018-06-13 21:26:35 +0100 |
| commit | 4b6732fdddebc07f072e012a52f7d9541e4d657c (patch) | |
| tree | ea66e08af8607e64ac95f3631cfefc4e8bf577f8 /src | |
| parent | d96cd3e8d74b303ff89716294d173754c70cd6b7 (diff) | |
Tracing instrumentation for C backend
Diffstat (limited to 'src')
| -rw-r--r-- | src/bitfield.ml | 18 | ||||
| -rw-r--r-- | src/c_backend.ml | 58 | ||||
| -rw-r--r-- | src/sail.ml | 3 | ||||
| -rw-r--r-- | src/sail_lib.ml | 4 | ||||
| -rw-r--r-- | src/value.ml | 3 |
5 files changed, 84 insertions, 2 deletions
diff --git a/src/bitfield.ml b/src/bitfield.ml index 161908cd..afdd5baf 100644 --- a/src/bitfield.ml +++ b/src/bitfield.ml @@ -83,6 +83,22 @@ let rec translate_indices hi lo = else (hi / 64, hi mod 64, 0) :: translate_indices (hi - (hi mod 64 + 1)) lo +let constructor name order start stop = + let indices = translate_indices start stop in + let size = if start > stop then start - (stop - 1) else stop - (start - 1) in + let constructor_val = Printf.sprintf "val Mk_%s : %s -> %s" name (bitvec size order) name in + let body (chunk, hi, lo) = + Printf.sprintf "%s_chunk_%i = v[%i .. %i]" + name chunk ((hi + chunk * 64) - stop) ((lo + chunk * 64) - stop) + in + let constructor_function = String.concat "\n" + [ Printf.sprintf "function Mk_%s v = struct {" name; + Printf.sprintf " %s" (Util.string_of_list ",\n " body indices); + "}" + ] + in + combine [ast_of_def_string order constructor_val; ast_of_def_string order constructor_function] + (* For every index range, create a getter and setter *) let index_range_getter name field order start stop = let indices = translate_indices start stop in @@ -149,4 +165,4 @@ let field_accessor name order (id, ir) = index_range_accessor name (string_of_id let macro id size order ranges = let name = string_of_id id in let ranges = (mk_id "bits", BF_aux (BF_range (Big_int.of_int (size - 1), Big_int.of_int 0), Parse_ast.Unknown)) :: ranges in - combine ([newtype name size order] @ List.map (field_accessor name order) ranges) + combine ([newtype name size order; constructor name order (size - 1) 0] @ List.map (field_accessor name order) ranges) diff --git a/src/c_backend.ml b/src/c_backend.ml index e088b5e5..96cd9ed7 100644 --- a/src/c_backend.ml +++ b/src/c_backend.ml @@ -59,6 +59,7 @@ module Big_int = Nat_big_num let c_verbosity = ref 1 let opt_ddump_flow_graphs = ref false +let opt_trace = ref false (* Optimization flags *) let optimize_primops = ref false @@ -990,8 +991,10 @@ let analyze_primop' ctx env l id args typ = | "and_bits", [AV_C_fragment (v1, typ1); AV_C_fragment (v2, typ2)] -> AE_val (AV_C_fragment (F_op (v1, "&", v2), typ)) + (* | "not_bits", [AV_C_fragment (v, _)] -> AE_val (AV_C_fragment (F_unary ("~", v), typ)) + *) | "vector_subrange", [AV_C_fragment (vec, _); AV_C_fragment (f, _); AV_C_fragment (t, _)] -> let len = F_op (f, "-", F_op (t, "-", v_one)) in @@ -3231,6 +3234,59 @@ let sgen_finish = function Printf.sprintf " finish_%s();" (sgen_id id) | _ -> assert false +let instrument_tracing ctx = + let module StringSet = Set.Make(String) in + let traceable = StringSet.of_list ["uint64_t"; "sail_string"; "bv_t"; "mpz_t"; "unit"; "bool"] in + let rec instrument = function + | (I_aux (I_funcall (clexp, _, id, args, ctyp), _) as instr) :: instrs -> + let trace_start = + iraw (Printf.sprintf "trace_start(\"%s\");" (String.escaped (string_of_id id))) + in + let trace_arg cval = + let ctyp_name = sgen_ctyp_name (cval_ctyp cval) in + if StringSet.mem ctyp_name traceable then + iraw (Printf.sprintf "trace_%s(%s);" ctyp_name (sgen_cval cval)) + else + iraw "trace_unknown();" + in + let rec trace_args = function + | [] -> [] + | [cval] -> [trace_arg cval] + | cval :: cvals -> + trace_arg cval :: iraw "trace_argsep();" :: trace_args cvals + in + let trace_end = iraw "trace_end();" in + let trace_ret = + let ctyp_name = sgen_ctyp_name ctyp in + if StringSet.mem ctyp_name traceable then + iraw (Printf.sprintf "trace_%s(%s);" (sgen_ctyp_name ctyp) (sgen_clexp_pure clexp)) + else + iraw "trace_unknown();" + in + [trace_start; + iraw "g_trace_depth++;"] + @ trace_args args + @ [iraw "trace_argend();"; + instr; + iraw "g_trace_depth--;"; + trace_end; + trace_ret; + iraw "trace_retend();"] + @ instrument instrs + + | I_aux (I_block block, aux) :: instrs -> I_aux (I_block (instrument block), aux) :: instrument instrs + | I_aux (I_try_block block, aux) :: instrs -> I_aux (I_try_block (instrument block), aux) :: instrument instrs + | I_aux (I_if (cval, then_instrs, else_instrs, ctyp), aux) :: instrs -> + I_aux (I_if (cval, instrument then_instrs, instrument else_instrs, ctyp), aux) :: instrument instrs + + | instr :: instrs -> instr :: instrument instrs + | [] -> [] + in + function + | CDEF_fundef (function_id, heap_return, args, body) -> + CDEF_fundef (function_id, heap_return, args, instrument body) + | cdef -> cdef + let bytecode_ast ctx rewrites (Defs defs) = let assert_vs = Initial_check.extern_of_string dec_ord (mk_id "sail_assert") "(bool, string) -> unit effect {escape}" in let exit_vs = Initial_check.extern_of_string dec_ord (mk_id "sail_exit") "unit -> unit effect {escape}" in @@ -3258,7 +3314,7 @@ let compile_ast ctx (Defs defs) = let ctx = { ctx with tc_env = snd (Type_error.check ctx.tc_env (Defs [assert_vs; exit_vs])) } in let chunks, ctx = List.fold_left (fun (chunks, ctx) def -> let defs, ctx = compile_def ctx def in defs :: chunks, ctx) ([], ctx) defs in let cdefs = List.concat (List.rev chunks) in - let cdefs = optimize ctx cdefs in + let cdefs = List.map (instrument_tracing ctx) (optimize ctx cdefs) in let docs = List.map (codegen_def ctx) cdefs in let preamble = separate hardline diff --git a/src/sail.ml b/src/sail.ml index 36b4efd8..86c00254 100644 --- a/src/sail.ml +++ b/src/sail.ml @@ -119,6 +119,9 @@ let options = Arg.align ([ ( "-Oconstant_fold", Arg.Set Constant_fold.optimize_constant_fold, " Apply constant folding optimizations"); + ( "-c_trace", + Arg.Set C_backend.opt_trace, + " Instrument C ouput with tracing"); ( "-lem_ast", Arg.Set opt_print_lem_ast, " output a Lem AST representation of the input"); diff --git a/src/sail_lib.ml b/src/sail_lib.ml index 89056347..31b975df 100644 --- a/src/sail_lib.ml +++ b/src/sail_lib.ml @@ -575,6 +575,10 @@ let real_of_string str = (* Not a very good sqrt implementation *) let sqrt_real x = failwith "sqrt_real" (* real_of_string (string_of_float (sqrt (Num.float_of_num x))) *) +let print str = Pervasives.print_string str + +let prerr str = Pervasives.prerr_string str + let print_int (str, x) = print_endline (str ^ Big_int.to_string x) diff --git a/src/value.ml b/src/value.ml index 8ee219b7..41b52720 100644 --- a/src/value.ml +++ b/src/value.ml @@ -491,6 +491,9 @@ let primops = StringMap.empty [ ("and_bool", and_bool); ("or_bool", or_bool); + ("print", value_print); + ("prerr", fun vs -> (prerr_endline (string_of_value (List.hd vs)); V_unit)); + ("dec_str", fun _ -> V_string "X"); ("print_endline", value_print); ("prerr_endline", fun vs -> (prerr_endline (string_of_value (List.hd vs)); V_unit)); ("putchar", value_putchar); |
