summaryrefslogtreecommitdiff
path: root/src/sail.ml
AgeCommit message (Collapse)Author
2019-04-15Merge branch 'sail2' of github.com:rems-project/sail into sail2Jon French
2019-04-15Merge branch 'sail2' into rmem_interpreterJon French
2019-04-15Basic loop termination measures for CoqBrian Campbell
Currently only supports pure termination measures for loops with effects. The user syntax uses separate termination measure declarations, as in the previous recursive termination measures, which are rewritten into the loop AST nodes before type checking (because it would be rather difficult to calculate the correct environment to type check the separate declaration in).
2019-04-05Fix: Don't remove uncalled polymorphic constructors if they are matched uponAlasdair Armstrong
Previously the specialization would remove any polymorphic union constructor that was never created anywhere in the specification. While this wasn't usually problematic, it does leave an edge case where such a constructor could be matched upon in a pattern, and then the resulting match would fail to compile as it would be matching on a constructor kind that doesn't exists. This should fix that issue by chaging the V_ctor_kind value into an F_ctor_kind fragment. Previously a polymorphic constructor-kind would have been represented by its mangled name, e.g. V_ctor_kind "zSome_unit" would now be represented as V_ctor_kind ("Some", unifiers, ty) where ty is a monomorphic version of the original constructor's type such that ctyp_unify original_ty ty = unifiers and the mangled name we generate is zencode_string ("Some_" ^ string_of_list "_" string_of_ctyp unifiers)
2019-03-27C: Generate C from sliced specificationsAlasdair Armstrong
2019-03-27Interactive: Refactor sail.ml some moreAlasdair Armstrong
Separate calling the rewriter from the backend-specific parts of sail.ml
2019-03-27Interactive: Refactor sail.mlAlasdair Armstrong
Rather than having a separate variable for each backend X, opt_print_X, just have a single variable opt_print_target, where target contains a string option, such as `Some "lem"` or `Some "ocaml"`, then we have a function target that takes that string and invokes the appropriate backend, so the main function in sail.ml goes from being a giant if-then-else block to a single call to target !opt_target ast env This allows us to implement a :compile <target> command in the interactive toplevel Also implement a :rewrites <target> command which performs all the rewrites for a specific target, so rather than doing e.g. > sail -c -O -o out $FILES one could instead interactively do > sail -i :option -undefined_gen :load $FILES :option -O :option -o out :rewrites c :compile c :quit for the same result. To support this the behavior of the interactive mode has changed slightly. It no longer performs any rewrites at all, so a :rewrites interpreter is currently needed to interpret functions in the interactive toplevel, nor does it automatically set any other flags, so -undefined_gen is needed in this case, which is usually implied by the -c flag.
2019-03-26Rewriter: Expose rewrite passes to interactive modeAlasdair Armstrong
Rather than each rewrite being an opaque function, with separate lists of rewrites for each backend, instead put all the rewrites into a single list then have each backend define which of those rewrites it wants to use and in what order. For example, rather than having let rewrite_defs_ocaml = [ ... ("rewrite_undefined", rewrite_undefined_if_gen false); ... ] we would now have let all_rewrites = [ ... ("undefined", Bool_rewriter (fun b -> Basic_rewriter (rewrite_undefined_if_gen b))); ... ] let rewriters_ocaml = [ ... ("undefined", [Bool_arg false]); ... ] let rewrite_defs_ocaml = List.map (fun (name, args) -> (name, instantiate_rewrite (List.assoc name all_rewrites) args)) rewriters_ocaml This means we can introspect on the arguments required for each rewrite, allowing a :rewrite command in the interactive mode which can parse the arguments required for each rewrite, so we can invoke the above rewrite as sail> :rewrite undefined false with completion for the rewrite name based on all_rewrites, and hints for any arguments. The idea behind this is if we want to generate a very custom slice of a specification, we can set it up as a sequence of interpreter commands, e.g. ... :rewrite split execute :slice_roots execute_LOAD :slice_cuts rX wX :slice :rewrite tuple_assignments ... where we slice a spec just after splitting the execute function. This should help in avoiding an endless proliferation of additional options and flags on the command line.
2019-03-19C: Some simplificationAlasdair Armstrong
Remove unused experimental optimizations
2019-03-15Add a rewriting pass for constant propagation in mutrecsThomas Bauereiss
Propagating constants into mutually recursive calls and removing dead branches might break mutually recursive cycles. Also make constant propagation use the existing interpreter-based constant folding to evaluate function calls with only constant arguments (as opposed to a mixture of inlining and hard-coded rewrite rules).
2019-03-14C: Some further tweaksAlasdair Armstrong
2019-03-14Merge branch 'sail2' into rmem_interpreterJon French
2019-03-13Remove prover reference from typecheck env when marshalling out defsJon French
2019-03-13C: Improve Jib IR, add SSA representationAlasdair Armstrong
Add a CL_void l-expression so we don't have redundant unit-typed variables everywhere, and add an optimization in Jib_optimize called optimize_unit which introduces these. Remove the basic control-flow graph in Jib_util and add a new mutable control-flow graph type in Jib_ssa which allows the IR to be converted into SSA form. The mutable graph allows for more efficient updates, and includes both back and forwards references making it much more convenient to traverse. Having an SSA representation should make some optimizations much simpler, and is also probably more natural for SMT generation where variables have to be defined once using declare-const anyway. Debug option -ddump_flow_graphs now outputs SSA'd graphs of the functions in a specification.
2019-03-09C: Fix miscompilation of constrained struct field accessAlasdair
For a Int-parameterised struct F('x: Int) = ... the optimizer would attempt to optimize field access in cases where 'x was known to constrain the types of the struct fields only locally. Which would create a type error in the generated C. Now we always use the type from the global struct type. However, we previously weren't using struct type quantifiers to optimize the field representation, which we now do. Also rename some utility functions to better match the List functions in the OCaml stdlib.
2019-03-08C: Refactor C backendAlasdair Armstrong
Main change is splitting apart the Sail->IR compilation stage and the C code generation and optimization phase. Rather than variously calling the intermediate language either bytecode (when it's not really) or simply IR, we give it a name: Jib (a type of Sail). Most of the types are still prefixed by c/C, and I don't think it's worth changing this. The various parts of the C backend are now in the src/jib/ subdirectory src/jib/anf.ml - Sail->ANF translation src/jib/jib_util.ml - various Jib AST processing and helper functions (formerly bytecode_util) src/jib/jib_compile.ml - Sail->Jib translation (using Sail->ANF) src/jib/c_backend.ml - Jib->C code generator and optimizations Further, bytecode.ott is now jib.ott and generates jib.ml (which still lives in src/ for now) The optimizations in c_backend.ml should eventually be moved in a separate jib_optimization file. The Sail->Jib compilation can be parameterised by two functions - one is a custom ANF->ANF optimization pass that can be specified on a per Jib backend basis, and the other is the rule for translating Sail types in Jib types. This can be more or less precise depending on how precise we want to be about bit-widths etc, i.e. we only care about <64 and >64 for C, but for SMT generation we would want to be as precise as possible. Additional improvements: The Jib IR is now agnostic about whether arguments are allocated on the heap vs the stack and this is handled by the C code generator. jib.ott now has some more comments explaining various parts of the Jib AST. A Set module and comparison function for ctyps is defined, and some functions now return ctyp sets rather than lists to avoid repeated work.
2019-03-06Add an -ir option to print the intermediate representation of a fileAlasdair Armstrong
2019-03-05More optimizations and improvments for C generationAlasdair Armstrong
Add some comments in constant_fold.ml
2019-03-05Additional optimizations for C compilationAlasdair
2019-03-04Merge branch 'sail2' into rmem_interpreterJon French
2019-03-04Marshalling: remove prover before marshallingJon French
2019-03-04Do not store type synonyms as functions in the environmentAlasdair Armstrong
2019-03-04Merge branch 'sail2' into rmem_interpreterJon French
2019-02-28Allow user-specified state to be passed through generated CAlasdair Armstrong
For example: sail -c_extra_params "CPUMIPSState *env" -c_extra_args env would pass a QEMU MIPS cpu state to every non-builtin function call. Also add documentation for each C compilation option in C_backend.mli
2019-02-27Tweaks to C compilation to make it more usable for embedding into other programsAlasdair Armstrong
Can now set a prefix for generated C functions with -c_prefix so -c_prefix sail_ would give sail_execute_CGetPerm over zexecute_CGetPerm. We still have to use our standard name-mangling scheme to avoid possible collisions within the name. Can build C that doesn't expect the standard runtime, which leaves operations like read_memory, write_memory etc to be stubbed in by another C program including the generated Sail. Things like letbindings are still an issue because we rely on a very small runtime to initialize global letbindings and similar. -c_separate_execute splits the execute function apart in the generated C
2019-02-27Make -o option work as usual with C compilationAlasdair Armstrong
2019-02-26Further work on toFromInterp backendJon French
2019-02-25Allow int-specialization for non-externs onlyAlasdair Armstrong
Add a flag in C backend ctx that allows us to generate arbitrary precision signed integer types, rather than just int64
2019-02-25Merge branch 'sail2' into rmem_interpreterJon French
2019-02-22Fix more bugs in int-specializationAlasdair Armstrong
2019-02-19Refactor specializationAlasdair Armstrong
specialize functions now take a 'specialization' parameter that specifies how they will specialize the AST. typ_ord_specialization gives the previous behaviour, whereas int_specialization allows specializing on Int-kinded arguments. Note that this can loop forever unless the appropriate case splits are inserted beforehand, presumably by monomorphisation. rename is_nat_kopt -> is_int_kopt for consistency
2019-02-19Progress on toFromInterp backend from-interp generationJon French
Produces vaguely-correct-looking-but-untested code for riscv duopod
2019-02-18Add option to linearize constraints containing exponentialsAlasdair Armstrong
When adding a constraint such as `x <= 2^n-1` to an environment containing e.g. `n in {32, 64}` or similar, we can enumerate all values of n and add `n == 32 & x <= 2^32-1 | n == 64 & x <= 2^64-1` instead. The exponentials then get simplified away, which means that we stay on the SMT solver's happy path. This is enabled by the (experimental, name subject to change) flag -smt_linearize, as this both allows some things to typecheck that didn't before (see pow_32_64.sail in test/typecheck/pass), but also may potentially cause some things that typecheck to no longer typecheck for SMT solvers like z3 that have some support for reasoning with power functions, or where we could simply treat the exponential as a uninterpreted function. Also make the -dsmt_verbose option print the smtlib2 files for the solve functions in constraint.ml. We currently ignore the -smt_solver option for these, because smtlib does not guarantee a standard format for the output of get-model, so we always use z3 in this case. Following the last commit where solve got renamed solve_unique, there are now 3 functions for solving constraints: * Constraint.solve_smt, which finds a solution if one exists * Constraint.solve_all_smt, which returns all possible solutions. Currently there's no bound, so this could loop forever if there are infinite solutions. * Constraint.solve_unique, which returns a unique solution if one exists Fix a bug where $option pragmas were dropped unnecessarily.
2019-02-15Use multiple solversAlasdair
Useful to see what constraints we are generating that are particularly hard, and which of our specs work with different solvers. Refactor code to use smt in names rather than specifically z3
2019-02-14Don't do any rewrites when checking files for EmacsAlasdair Armstrong
This makes sure we don't do any kind of re-writing or de-scatter any definitions when loading files into emacs. The difference here is that normally all files are processed together, but the emacs mode loads each file one by one. This is probably what we want to be doing anyway, so location information stays accurate for scattered functions for things like type-at-cursor commands and similar. Also fix some warnings. Fixes #32
2019-02-13Merge branch 'sail2' into rmem_interpreterJon French
2019-02-08Slightly tweak the help message.Prashanth Mundkur
2019-02-08Resurrect Sail output option (with new name: -output_sail)Brian Campbell
2019-02-08Rewrite type definitions in rewrite_nexp_idsThomas Bauereiss
For example, in type xlen : Int = 64 type xlenbits = bits(xlen) rewrite the 'xlen' in the definition of 'xlenbits' to the constant 64 in order to simplify Lem generation. In order to facilitate this, pass through the global typing environment to the rewriting steps (in the AST itself, type definitions don't carry annotations with environments).
2019-02-07Fix implicits in v8.2 public ARM specAlasdair Armstrong
2019-02-06Emacs mode understands relationships between Sail filesAlasdair
Allow a file sail.json in the same directory as the sail source file which contains the ordering and options needed for sail files involved in a specific ISA definition. I have an example for v8.5 in sail-arm. The interactive Sail process running within emacs then knows about the relationship between Sail files, so C-c C-l works for files in the ARM spec. Also added a C-c C-x command to jump to a type error. Requires yojson library to build interactive Sail.
2019-02-06Improve emacs modeAlasdair Armstrong
Can now use C-c C-s to start an interactive Sail process, C-c C-l to load a file, and C-c C-q to kill the sail process. Type errors are highlighted in the emacs buffer (like with merlin for OCaml) with a tooltip for the type-error, as well as being displayed in the minibuffer. Need to add a C-c C-x command like merlin to jump to the error, and figure out how to handle multiple files nicely, as well as hooking the save function like tuareg/merlin, but this is already enough to make working with small examples quite a bit more pleasant.
2019-02-06Fix some testsAlasdair Armstrong
2019-02-03Merge branch 'sail2' into rmem_interpreterJon French
2019-02-01Add tracing instrumention for SMTAlasdair Armstrong
Fix pretty printer bug
2019-01-30Cache compilation results to improve build times for repeated buildsAlasdair
2019-01-29Fixes for full v8.5Alasdair Armstrong
2019-01-29Add an option to crudely slice a function out of a Sail modelBrian Campbell
Not ideal because it keeps everything that's not a function, but good enough for quick tests extracted from arm.
2019-01-29Merge branch 'sail2' into asl_flow2Thomas Bauereiss
2019-01-21Add output directory option for generated Isabelle auxiliary theoriesThomas Bauereiss