summaryrefslogtreecommitdiff
path: root/src/c_backend.ml
AgeCommit message (Collapse)Author
2019-02-06Remove all sizeof rewriting from C compilationAlasdair
All sizeof expressions now removed by the type-checker, so it's now properly a type error if they cannot be removed rather than a bizarre re-write error. This also greatly improves compilation speed overall, at the expense of the first type-checking pass.
2019-02-04Fix behavior for fallthrough cases in catch blocksAlasdair Armstrong
Make all backends behave the same when a catch block does not catch a specific exception.
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-29Merge branch 'sail2' into asl_flow2Thomas Bauereiss
2019-01-22Add a pragma for unrolling recursive functionsAlasdair Armstrong
For example in RISC-V for the translation table walk: $optimize unroll 2 val walk32 ... function walk32 ... would create two extra copies of the walk_32 function, walk_32_unroll_1 and walk_32_unroll_2, with only walk_32_unroll_2 being recursive. Currently we only support the case where we have $optimize unroll, directly followed by a valspec, then a function, but this should be generalised in future. This optimization nearly doubles the performance of RISC-V It is implemented using a new Optimize.recheck rewrite that replaces the ordinary recheck_defs pass. It uses a new typechecker check_with_envs function that allows re-writes to utilise intermediate typechecking environments to minimize the amount of AST checking that occurs, for performance reasons. Note that older Sail versions including the current OPAM release will complain about the optimize pragma, so this cannot be used until they become up to date with this change.
2019-01-22Make sure we optimize constrained union constructorsAlasdair
2019-01-11Updates for sail-arm releaseAlasdair Armstrong
We want to ensure that no_devices.sail and devices.sail have the same effect footprint, because with a snapshot-type release in sail-arm, we can't rebuild the spec with asl_to_sail every time we switch from running elf binaries to booting OS's. This commit allows registers to have arbitrary effects, so registers that are really representing memory-mapped devices don't have to have the wmem/rmem effect.
2018-12-26More cleanupAlasdair Armstrong
Remove unused name schemes and DEF_kind
2018-12-22Improve error messages and debuggingAlasdair Armstrong
Work on improving the formatting and quality of error messages When sail is invoked with sail -i, any type errors now drop the user down to the interactive prompt, with the interactive environment being the environment at the point the type error occurred, this means the typechecker state can be interactively queried in the interpreter to help diagnose type errors.
2018-12-20Fix monomorpisation tests with typechecker changesAlasdair Armstrong
Add an extra argument for Type_check.prove for the location of the prove call (as prove __POS__) to help debug SMT related issues
2018-12-14A few additional testsAlasdair
2018-12-11Fix all tests with type checking changesAlasdair Armstrong
2018-12-10Various changes:Alasdair Armstrong
* Improve type inference for numeric if statements (if_infer test) * Correctly handle constraints for existentially quantified constructors (constraint_ctor test) * Canonicalise all numeric types in function arguments, which triggers some weird edge cases between parametric polymorphism and subtyping of numeric arguments * Because of this eq_int, eq_range, and eq_atom etc become identical * Avoid duplicating destruct_exist in Env * Handle some odd subtyping cases better
2018-12-08Compiling againAlasdair
Change Typ_arg_ to A_. We use it a lot more now typ_arg is used instead of uvar as the result of unify. Plus A_ could either stand for argument, or Any/A type which is quite appropriate in most use cases. Restore instantiation info in infer_funapp'. Ideally we would save this instead of recomputing it ever time we need it. However I checked and there are over 300 places in the code that would need to be changed to add an extra argument to E_app. Still some issues causing specialisation to fail however. Improve the error message when we swap how we infer/check an l-expression, as this could previously cause the actual cause of a type-checking failure to be effectively hidden.
2018-12-06Re-factor initial checkAlasdair Armstrong
Mostly this is to change how we desugar types in order to make us more flexible with what we can parse as a valid constraint as type. Previously the structure of the initial check forced some awkward limitations on what was parseable due to how the parse AST is set up. As part of this, I've taken the de-scattering of scattered functions out of the initial check, and moved it to a re-writing step after type-checking, where I think it logically belongs. This doesn't change much right now, but opens up some more possibilities in the future: Since scattered functions are now typechecked normally, any future module system for Sail would be able to handle them specially, and the Latex documentation backend can now document scattered functions explicitly, rather than relying on hackish 'de-scattering' logic to present documentation as the functions originally appeared. This has one slight breaking change which is that union clauses must appear before their uses in scattered functions, so union ast = Foo : unit function clause execute(Foo()) is ok, but function clause execute(Foo()) union ast = Foo : unit is not. Previously this worked because the de-scattering moved union clauses upwards before type-checking, but as this now happens after type-checking they must appear in the correct order. This doesn't occur in ARM, RISC-V, MIPS, but did appear in Cheri and I submitted a pull request to re-order the places where it happens.
2018-11-30Parser tweaks and fixesAlasdair Armstrong
- Completely remove the nexp = nexp syntax in favour of nexp == nexp. All our existing specs have already switched over. As part of this fix every test that used the old syntax, and update the generated aarch64 specs - Remove the `type when constraint` syntax. It just makes changing the parser in any way really awkward. - Change the syntax for declaring new types with multiple type parameters from: type foo('a : Type) ('n : Int), constraint = ... to type foo('a: Type, 'n: Int), constraint = ... This makes type declarations mimic function declarations, and makes the syntax for declaring types match the syntax for using types, as foo is used as foo(type, nexp). None of our specifications use types with multiple type parameters so this change doesn't actually break anything, other than some tests. The brackets around the type parameters are now mandatory. - Experiment with splitting Type/Order type parameters from Int type parameters in the parser. Currently in a type bar(x, y, z) all of x, y, and z could be either numeric expressions, orders, or types. This means that in the parser we are severely restricted in what we can parse in numeric expressions because everything has to be parseable as a type (atyp) - it also means we can't introduce boolean type variables/expressions or other minisail features (like removing ticks from type variables!) because we are heavily constrained by what we can parse unambigiously due to how these different type parameters can be mixed and interleaved. There is now experimental syntax: vector::<'o, 'a>('n) <--> vector('n, 'o, 'a) which splits the type argument list into two between Type/Order-polymorphic arguments and Int-polymorphic arguments. The exact choice of delimiters isn't set in stone - ::< and > match generics in Rust. The obvious choices of < and > / [ and ] are ambigious in various ways. Using this syntax right now triggers a warning. - Fix undefined behaviour in C compilation when concatenating a 0-length vector with a 64-length vector.
2018-11-30Improvements for ASL parserAlasdair Armstrong
- Fix pretty printing nested constraints - Add flow typing for if condition then { throw exn }; ... blocks - Add optimisations for bitvector concatenation in C
2018-11-27Fix memory leak in string_of_bitsAlasdair Armstrong
Should hopefully fix memory leak in RISC-V. Also adds an optimization pass that removes copying structs and allows some structs to simply alias each other and avoid copying their contents. This requires knowing certain things about the lifetimes of the structs involved, as can't free the struct if another variable is referencing it - therefore we conservatively only apply this optimization for variables that are lifted outside function definitions, and should therefore never get freed until the model exits - however this may cause issues outside ARMv8, as there may be cases where a struct can exist within a variant type (which are not yet subject to this lifting optimisation), that would break these assumptions - therefore this optimisation is only enabled with the -Oexperimental flag.
2018-11-27Add an optimisation pass to combine variables if possibleAlasdair Armstrong
This optimisation re-uses variables if possible, rather than allocating new ones.
2018-11-23Introduce intermediate bitvector representation in CAlasdair Armstrong
Bitvectors that aren't fixed size, but can still be shown to fit within 64-bits, now have a specialised representation. Still need to introduce more optimized functions, as right now we mostly have to convert them into large bitvectors to pass them into most functions. Nevertheless, this doubles the performance of the TLBLookup function in ARMv8.
2018-11-23C backend improvementsAlasdair Armstrong
- Propagate types more accurately to improve optimization on ANF representation. - Add a generic optimization pass to remove redundant variables that simply alias other variables. - Modify Sail interactive mode, so it can compile a specification with the :compile command, view generated intermediate representation via the :ir <function> command, and step-through the IR with :exec <exp> (although this is very incomplete) - Introduce a third bitvector representation, between fast fixed-precision bitvectors, and variable length large bitvectors. The bitvector types are now from most efficient to least * CT_fbits for fixed precision, 64-bit or less bitvectors * CT_sbits for 64-bit or less, variable length bitvectors * CT_lbits for arbitrary variable length bitvectors - Support for generating C code using CT_sbits is currently incomplete, it just exists in the intermediate representation right now. - Include ctyp in AV_C_fragment, so we don't have to recompute it
2018-11-20Add messages for assert failures without user defined messagesAlasdair Armstrong
Also fix some C optimisations
2018-11-19Don't re-check AST repeatedly in exp_lift_assign re-writeAlasdair Armstrong
This was _really_ slow - about 50secs for ARM. If this changes causes breakages we should fix them in some other way. Also using Reporting.err_unreachable in ANF translation, and fix slice optimization when creating slices larger than 64-bits in C translation
2018-11-16Various bugfixes and a simple profiling feature for rewritesAlasdair Armstrong
2018-11-06Fix bug with loop indices not being mapped to int64 in CAlasdair Armstrong
This should fix the issue in cheri128 Also introduce a feature to more easily debug the C backend: sail -dfunction Name will pretty-print the ANF and IR representation of just the Name function. I want to make this work for the type-checker as well, but it's a bit hard to get that to not fire during re-writing passes right now.
2018-11-05Ensure function quantifier is in scope when generating C return typeAlasdair Armstrong
This goes partway to resolving issue #23, as it now generates C code, but it seems like there is still an issue with the generated C.
2018-10-31Rename Reporting_basic to ReportingAlasdair Armstrong
There is no Reporting_complex, so it's not clear what the basic is intended to signify anyway. Add a GitHub issue link to any err_unreachable errors (as they are all bugs)
2018-10-31Improve error messages for unsolved function quantifiersAlasdair Armstrong
For example, for a function like ``` val aget_X : forall 'n, 0 <= 'n <= 31. int('n) -> bits(64) function test(n : int) -> unit = { let y = aget_X(n); () } ``` we get the message > Could not resolve quantifiers for aget_X (0 <= 'ex7# & 'ex7# <= 31) > > Try adding named type variables for n : atom('ex7#) > > The property (0 <= n & n <= 31) must hold which suggests adding a name for the type variable 'ex7#, and gives the property in terms of the variable n. If we give n a type variable name: ``` val test : int -> unit function test(n as 'N) = { let y = aget_X(n); () } ``` It will suggest a constraint involving the type variable name > Could not resolve quantifiers for aget_X (0 <= 'ex6# & 'ex6# <= 31) > > Try adding the constraint (0 <= 'N & 'N <= 31)
2018-10-11Change the function type in the ASTAlasdair
Changes the representation of function types in the ast from Typ_fn : typ -> typ to Typ_fn : typ list -> typ to more accurately represent their use in the various backends, where we often compile functions to either their curried representations as in Lem and Isabelle, or just multiple argument functions in C. There's still some oddity because a single pattern in a function clause can bind against multiple arguments, and maybe we want to forbid this in the future. The syntax also hasn't changed (yet), so in theory this change shouldn't break anything (but it invariably will...). In the future we would ideally require that a function with N arguments has exactly N patterns in its declaration, one for each argument so f : (x, y) -> z f _ = ... would be disallowed (as _ matches both x and y), forcing f(_, _) = z this would simply quite a few things, Also we could have a different syntax for function argument lists and tuples, because it's rather hard to define a function that actually takes a tuple with the syntax how it is now. Some issues I noticed when doing this refactoring: Line 1926 of Coq translation. untuple_args_pat is maybe no longer needed? However there's still some funnyness where a pattern can be used to bind multiple function arguments so maybe it still is. Line 2306 of monomorphisation. I simplified the logic here. I think it's equivalent now, but I could be wrong. Line 4517 of rewrites. I'm not sure what make_cstr_mappings is doing here, but hopefully the simpler version is the same.
2018-09-28Fix optimisation bug for certain if statementsAlasdair Armstrong
When converting to A-normal form I just used the type of the then branch of if statements to get the type of the whole if statement - usually they'd be the same, but with flow typing one of the branches can have a false constraint, which then allows the optimizer to fit any integer into a 64-bit integer causing an overflow. The fix is to correctly use the type the typechecker gives for the whole if statement. Also add decimal_string_of_bits to the C output. Rename is_reftyp to is_ref_typ to be more consistent with other is_X_typ functions in Ast_util.
2018-09-18Fix issues with tuple Constructors taking multiple argumentsAlasdair Armstrong
This really demonstrates why we should switch to Typ_fn being a typ list * typ constructor because the implementation here feels *really* hacky with dummy Typ_tup constructors being used to enforce single arguments for constructors.
2018-09-04C: add an option to control generation of main().Prashanth Mundkur
2018-09-04C: split out setup/init and teardown functions from main().Prashanth Mundkur
2018-08-30C: Fix a bug where function argument type becomes more specific due to flow ↵Alasdair Armstrong
typing Added a regression test as c/test/downcast_fn.sail
2018-08-30Allow additional includes to be specified for C backend.Prashanth Mundkur
2018-08-30C: Fix an issue with struct field being generalised inside polymorphic ↵Alasdair Armstrong
constructors Add a new printing function for debugging that recursively prints constructor types. Fix an interpreter bug when pattern matching on constructors with tuple types.
2018-08-29C: Fix some issues with tuples as arguments to polymorphic constructorsAlasdair Armstrong
Now all we need to do is make sure the RISC-V builtins are mapped to the correct C functions, and RISC-V in C should work (hopefully). We're still missing some of the functions in sail.c for the mappings so those have to be implemented.
2018-08-24Fix rewriter issuesAlasdair Armstrong
Allow pat_lits rewrite to map L_unit to wildcard patterns, rather than introducing eq_unit tests as guards. Add a fold_function and fold_funcl functions in rewriter.ml that apply the pattern and expression algebras to top-level functions, which means that they correctly get applied to top-level function patterns when they are used. Currently modifying the re-writing passes to do this introduces some bugs which needs investigated further. The current situation is that top-level patterns and patterns elsewhere are often treated differently because rewrite_exp doesn't (and indeed cannot, due to how the re-writer is structured) rewrite top level patterns. Fix pattern completeness check for unit literals Fix a bug in Sail->ANF transform where blocks were always annotated with type unit incorrectly. This caused issues in pattern literal re-writes where the guard was a block returning a boolean. A test case for this is added as test/c/and_block.sail. Fix a bug caused by nested polymorphic function calls and matching in top-level patterns. Test case is test/c/tl_poly_match.sail. Pass location info through codegen_conversion for better error reporting
2018-08-21C: Correctly handle the kinds of patterns generated by mappingsAlasdair Armstrong
This change allows the RISC-V spec to compile to C, but more testing is needed to ensure it works correctly.
2018-08-20Refactor tuple conversions in Sail to C compilationAlasdair Armstrong
Make the C l-expression type in Sail more generic and expressive, and refactor the generation of conversions into a seperate codegen_conversion function, which can handle more complex cases than the previous more ad-hoc method.
2018-08-18Correctly handle specialising polymorphic types in nested unionsAlasdair
Ensure that this works even when the union types are dependent in the wrong order, before topologically sorting definitions. We do this by calling fix_variant_ctyps on all cdefs by passing a list of prior cdefs to specialize_variants.
2018-08-17Improve builtins testsAlasdair Armstrong
Test the builtin functions by compiling them to C, OCaml, and OCaml via Lem. Split up some of the longer builtin test programs to avoid stack overflows when compiling to OCaml, as 3000+ line long blocks can cause issues with some re-writing steps. Also test constant-folding with builtins (this should reduce the asserts in these files to assert true), and also test constant folding with the C compilation. Fix a bug whereby vectors with heap-allocated elements were not initialized correctly. Fix a bug caused by compiling and optimising empty vector literals. Fix an OCaml test case that broke due to the ref type being used. Now uses references to registers. Fix a bug where Sail would output big integers that lem can't parse. Checks if integer is between Int32.min_int and Int32.max_int and if not, use integerOfString to represent the integer. Really this should be fixed in Lem. Make the python test runner script the default for testing builtins and running the C compilation tests in test/run_tests.sh Add a ocaml_build_dir option that sets a custom build directory for OCaml. This is needed for running OCaml tests in parallel so the builds don't clobber one another.
2018-08-16Remove unused ref typeAlasdair Armstrong
2018-08-16Various cleanups to ott grammarAlasdair Armstrong
Add additional well-formedness check when calling typing rules
2018-08-14Improve error messages from C backend, and fix issues with assigning to pointersAlasdair Armstrong
2018-08-14Remove some comments from C outputAlasdair Armstrong
Cleanup some debugging output
2018-08-13Add graph library graph.ml, and use to correctly sort type definitionsAlasdair
2018-08-13Sort ctype_defs in dependency order after specialisationAlasdair
We now generate anonymous types in the correct order, but post specialisation more dependencies can occur between named types, so an additional sorting step is needed to ensure that these happen in the correct order. In theory we could end up with circular dependencies here that don't exist at the Sail source level, but this shouldn't occur often (or ever) in practice. I think this is fixable but it would require some code generator changes.
2018-08-09Fix a bug by ensuring that monomorphic variant constructors do not get ↵Alasdair Armstrong
lifted types Add a test case for nested variant constructors