summaryrefslogtreecommitdiff
path: root/src/c_backend.ml
AgeCommit message (Collapse)Author
2018-07-10Only put static qualifier on valspecs when -static flag is usedAlasdair Armstrong
2018-07-08Add -static flag that controls whether generated C functions are staticAlasdair
By default generated functions are non-static, using the -static flag makes them static which is useful for measuring coverage using generated code. Some utility helper functions will always be static, but the compiled versions of sail functions won't be unless this flag is set.
2018-07-05Fix equality comparisons for variants in CAlasdair
Makes sure equality comparisons for variants are compiled correctly. Needed for CHERI and mips, which have structs containing variants. Also make sure that struct equality works for structs containing other structs.
2018-07-05Fix equality comparisons for structsAlasdair
Add a test case in test/c/eq_struct.sail. Ensure that the macro EQUAL(type) will always give a valid equality function for any builtin type in sail.h.
2018-07-05Fix CHERI test that was failing when compiled to CAlasdair Armstrong
Non bitvector literals for decreasing vectors were not being reversed correctly, so the list of capability registers was effectively in reverse order. Added a test case to test/c/ based on this aspect of CHERI
2018-07-05make many generated c functions static -- this gives the compiler a chance ↵Robert Norton
to notice if they are dead or inline them if appropriate, cleaning up coverage reports and potentially improving execution speed.
2018-07-03Fix a bug in foreach loopsAlasdair Armstrong
We should test before the first iteration in case 'to' starts out as less than 'from'.
2018-07-02Fix get_recursive_functions to not only pick up non-mutually recursive functionsAlasdair Armstrong
The code to do this is rather ugly. It would be nice to have a generic callgraph representation we could just query and not use the rewriter in a weird way to extract this info.
2018-06-28Add tagged memory to C rts to cheri can be compiled to CAlasdair Armstrong
2018-06-27Fix reading reals from strings in C libAlasdair Armstrong
2018-06-27RTS: Delete __SetConfig stub functionAlastair Reid
This is now directly supported from SAIL so we can call the SAIL __SetConfig function instead.
2018-06-26Add configuration registers so __SetConfig ASL can be translatedAlasdair Armstrong
Registers can now be marked as configuration registers, for example: register configuration CFG_RVBAR = 0x1300000 They work like ordinary registers except they can only be set by functions with the 'configuration' effect and have no effect when read. They also have an initialiser, like a let-binding. Internally there is a new reg_dec constructor DEC_config. They are intended to represent configuration parameters for the model, which can change between runs, but don't change during execution. Currently they'll only work when compiled to C. Internally registers can now have custom effects for reads and writes rather than just rreg and wreg, so the type signatures of Env.add_register and Env.get_register have changed, as well as the Register lvar, so in the type checker we now write: Env.add_register id read_effect write_effect typ rather than Env.add_register id typ For the corresponding change to ASL parser there's a function is_config in asl_to_sail.ml which controls what becomes a configuration register for ARM. Some things we have to keep as let-bindings because Sail can't handle them changing at runtime - e.g. the length of vectors in other top-level definitions. Luckily __SetConfig doesn't (yet) try to change those options. Together these changes allow us to translate the ASL __SetConfig function, which means we should get command-line option compatibility with ArchEx for running the ARM conformance tests.
2018-06-25Use getopt rather than argp for Mac compatibility in C runtimeAlasdair Armstrong
Also further tweaks to Sail library for C and include sail lib files for tracing
2018-06-23Split Sail->ANF translation into its own fileAlasdair
Refactor the C compilation process by moving out the conversion to A-normal form into its own file. Also make the A-normal form AST parameterised by the type of the types annotating it. The idea being we can have a typ aexp -> ctyp aexp translation, converting to low-level types at a slightly higher level before mapping into our low-level IR. This would fix some issues we have where the type of variables change due to flow typing, because we could map the sail types to low-level types in the ANF ast where we still have some knowledge about the structure of the original Sail.
2018-06-21Add command line option support for Sail->C compiled modelsAlasdair Armstrong
For example, the MIPS model can boot FreeBSD as ./mips_c --binary=0x100000,/path/to/kernel --image=/path/to/simboot.sailbin Or with short options as ./mips_c -b 0x100000,/path/to/kernel -i /path/to/simboot.sailbin The current options are: -e, --elf, which loads an elf file directly -n, --entry, which sets the entry point -i, --image, which loads an image file compiled by "sail -elf" using Linksem -b, --binary, which loads a plain binary image into memory at a specific address -l, --cyclelimit, which means the (new) cycle_count() builtin exits the model after a certain number of calls Also there are the default -? --help and --usage options.
2018-06-21Merge branch 'tracing' into sail2Alasdair Armstrong
2018-06-21Fix MIPS wrt changes to C runtimeAlasdair Armstrong
This plus changes to bitfield internals is enough to run some MIPS tests at 1Mhz.
2018-06-21Simplify the ANF->IR translationAlasdair Armstrong
Previously the ANF->IR translation cared too much about how things were allocated in C, so it had to constantly check whether things needed to be allocated on the stack or heap, and generate different cequences of IR instructions depending on either. This change removes the ialloc IR instruction, and changes iinit and idecl so that the code generator now generates different C for the same IR instructions based on the variable types involved. The next change in this vein would be to merge icopy and iconvert at the IR level so that conversions between uint64_t and large-bitvectors are inserted by the code generator. This would be good because it would make the ANF->IR translation more robust to changes in the types of variables caused by flow-typing, and optimization passes could convert large bitvectors to uint64_t as local changes.
2018-06-19Add elf parsing from AlastairAlasdair Armstrong
2018-06-19Improvements to Sail C for booting LinuxAlasdair Armstrong
2018-06-15Fixes for C RTS for aarch64 no it's split into multiple filesAlasdair Armstrong
Fix a bug involving indentifers on the left hand side of assignment statements not being shadowed correctly within foreach loops. Make the different between different types of integer division explicit in at least the C compilation for now. fdiv_int is division rounding towards -infinity (floor). while tdiv_int is truncating towards zero. Same for fmod_int and tmod_int.
2018-06-14rename all lem support files to sail2_foo to avoid conflict with sail1 in rmemJon French
2018-06-14Refactor C backend, and split RTS into multiple filesAlasdair
2018-06-13Tracing instrumentation for C backendAlasdair Armstrong
2018-06-11More efficient bitfield implementationAlasdair Armstrong
2018-06-09Fix issue in C_backend, and run C tests with undefined behavior sanitizerAlasdair
2018-06-09Fix issue with catch block return values not being compiled correctlyAlasdair
This should fix the issue raised in commit 45554f Adds a test loop_exception that tests throwing exceptions in loops, various looping constructs, and returning values from try/catch blocks. Also modified the test-suite to test C compiled output both with and without optimisations
2018-06-07Fix bug in add_bits optimizationAlasdair Armstrong
2018-06-06Factor utility functions for IR into separate file and struct update ↵Alasdair Armstrong
optimizations. Move the utility functions for graph generation and pretty printing of intermediate representation instructions into a separate file, bytecode_util.ml, by analogy with ast_util.ml. Add an optimization pass that searches for specific patterns of struct updates and removes uncessary copying of the structs involved. With this optimisation pass the time taken for u-boot to run approx 57,000,000 instructions goes down from about 11-12 minutes to 8 minutes (about 120,000 IPS).
2018-06-06Some additional fixes to C backend. Re-enable primitive optimizations.Alasdair Armstrong
Also add an additional -Oz3 flag that uses z3 to optimize some additional types. This is currently very experimental and doesn't fully work yet.
2018-06-06Some work on improving error messagesAlasdair Armstrong
We now store the location where type variables were bound, so we can use this information when printing error messages. Factor type errors out into type_error.ml. This means that Type_check.check is now Type_error.check, as it previously it handled wrapping the type_errors into reporting_basic errors. Type_check.check' has therefore been renamed to Type_check.check.
2018-06-04Fix an issue with riscv_platform involving flow typingAlasdair Armstrong
- Refactor the flow typing implementation in the type-checker. This should fix an issue involving riscv_platform. Specifically it should now work better when an if statement contains multiple conditions combined with and/or, only some of which imply constraints at the type level. This change also simplifies the implementation of flow typing, and removes some obscure features that were hardly used - specifically, flow typing could modify types, but this was fairly obscure and doesn't seem to affect any of our specifications. More testing is needed to ensure that this change hasn't inadvertantly broken anything, but it does pass all our tests and continue to typecheck arm, riscv and cheri. - Also adds a option for generating faster undefined functions for enum and variant types. Previously I tried to optimise away such functions in the C backend, because they could be slow and cause considerable uneccessary allocation, however this was error prone and it turns out a much simpler solution is to simply make the functions themselves much faster, at the cost of hard-coding certain decisions about what undefined means for these types at compile tile (which is fine for fast emulation). This almost doubles the performance of the generated C code. - Add a wrapper for right shift to avoid UB when shifting by 64 or more places.
2018-06-04Fix bug with function return types in C backendAlasdair Armstrong
2018-05-31Fixes to get ARM u-boot working in Sail.Alasdair Armstrong
Also fixes to C backend for compiling MIPS spec to C - Fix an issue with const correctness in internal_vector_update functions generated by C backend - Add builtins for MIPS to sail.h - Fix an issue where reg_deref didn't work when called on pointers to large bitvectors, i.e. vectors containing references to large bitfields as in the MIPS TLB code - Various bug fixes and changes for running U-boot on ARM model, including for interpreter and OCaml compilation. - Fix memory leak issues and incorrect shadowing for foreach loops - Update C header file. Fixes memory leak in memory read/write builtins. - Add aux constructor to ANF representation to hold environment information. - Fix undefined behavior caused by optimisation left shifting uint64_t vectors 64 or more times. Unfortunately there's more issues because the same happens for X >> 64 right shifts. It would make sense for this to be zero, because that would guarantee the property that ((X >> n) >> m) == (X >> (n + m)) but we probably need to do (X >> (n - 1) >> 1) in the optimisation to ensure that we don't cause UB. Shifting by 63 and then by 1 is well-defined, but shifting by 64 in one go isn't according to the C standard. This issue with right-shifts only occurs for zero-length vectors, so it's not a huge deal, but it's still annoying. - Add versions of print_bits and print_int that print to stderr. Follows OCaml convention of print/prerr. Should make things more explicit. Different backends had different ideas about where print should output to, not every backend needs to have this (e.g. theorem prover backends don't need to print) but having both stderr and stdout seperate and clear is useful for executable models (UART needs to be stdout, debug messages should be stderr).
2018-05-09Fix an issue with C compilationAlasdair Armstrong
2018-04-26Fix bug in rewriting of loopsThomas Bauereiss
Take into account existential types when determining bounds for the loop variable
2018-04-10Porting some minisail changes to sail2 branchAlasdair Armstrong
This commit primarily changes how existential types are bound in letbindings. Essentially, the constraints on both numeric and existentially quantified types are lifted into the surrounding type context automatically, so in ``` val f : nat -> nat let x = f(3) ``` whereas x would have had type nat by default before, it'll now have type atom('n) with a constraint that 'n >= 0 (where 'n is some fresh type variable). This has several advantages: x can be passed to functions expecting an atom argument, such as a vector indexing operation without any clunky cast functions - ex_int, ex_nat, and ex_range are no longer required. The let 'x = something() syntax is also less needed, and is now only really required when we specifically want a name to refer to x's type. This changes slightly the nature of the type pattern syntax---whereas previously it was used to cause an existential to be destructured, it now just provides names for an automatically destructured binding. Usually however, this just works the same. Also: - Fixed an issue where the rewrite_split_fun_constr_pats rewriting pass didn't add type paramemters for newly added type variables in generated function parameters. - Updated string_of_ functions in ast_util to reflect syntax changes - Fixed a C compilation issue where elements of union type constructors were not being coerced between big integers and 64-bit integers where appropriate - Type annotations in patterns now generalise, rather than restrict the type of the pattern. This should be safer and easier to handle in the various backends. I don't think any code we had was relying on this behaviour anyway. - Add inequality operator to lib/flow.sail - Fix an issue whereby top-level let bindings with annotations were checked incorrectly
2018-03-22Fix C compilation for CHERI and MIPSAlasdair Armstrong
First, the specialisation of option types has been fixed by allowing the specialisation of constructor return types - this essentially means that a constructor, such as Some : 'a -> option('a) can get specialised to int -> option(int), rather than int -> option('a). This means that these constructors are treated like GADTs internally. Since this only happens just before the C translation, I haven't put much effort into making this very robust so far. Second, there was a bug in C compilation for the typing of return expressions in non-unit contexts, which has been fixed. Finally support for vector literals that are non-bitvectors has been added.
2018-03-19Fixes to C backend for RISCV-compilationAlasdair Armstrong
Can now compile RISCV. Requires some library tweaks before it'll pass any tests, Also adds hyperlinks to wip latex output
2018-03-14Fix toplevel pattern compilationAlasdair Armstrong
Comment out partially working optimisation passes for now
2018-03-13Polymorphic option types now compile to CAlasdair Armstrong
Fixed an issue whereby an option constructor that was never constructed, but only matched on, would cause compilation to fail. Temporarily fixed an issue where union types that can be entirely stack-allocated were not being treated as such, by simply heap-allocating all unions. Need to adapt the code generator to handle this case properly. Fixed a further small issue whereby multiple union types would confuse the type specialisation pass. Added a test case for compiling option types. RISCV now generates C code, but there are still some bugs that need to be squashed before it compile and work.
2018-03-12ELF loading for C backendAlasdair Armstrong
Add a flag to Sail that allows for an image of an elf file to be dumped in a simple format using linksem, used as sail -elf test.elf -o test.bin This image file can then be used by a compiled C version of a sail spec as with ocaml simply by ./a.out test.bin
2018-03-09Specialise constructors for polymorphic unionsAlasdair Armstrong
Also work on making C backend compile RISC-V
2018-03-07Make union types consistent in the ASTAlasdair Armstrong
Previously union types could have no-argument constructors, for example the option type was previously: union option ('a : Type) = { Some : 'a, None } Now every union constructor must have a type, so option becomes: union option ('a : Type) = { Some : 'a, None : unit } The reason for this is because previously these two different types of constructors where very different in the AST, constructors with arguments were used the E_app AST node, and no-argument constructors used the E_id node. This was particularly awkward, because it meant that E_id nodes could have polymorphic types, i.e. every E_id node that was also a union constructor had to be annotated with a type quantifier, in constrast with all other identifiers that have unquantified types. This became an issue when monomorphising types, because the machinery for figuring out function instantiations can't be applied to identifier nodes. The same story occurs in patterns, where previously unions were split across P_id and P_app nodes - now the P_app node alone is used solely for unions. This is a breaking change because it changes the syntax for union constructors - where as previously option was matched as: function is_none opt = match opt { Some(_) => false, None => true } it is now matched as function is_none opt = match opt { Some(_) => false, None() => true } note that constructor() is syntactic sugar for constructor(()), i.e. a one argument constructor with unit as it's value. This is exactly the same as for functions where a unit-function can be called as f() and not as f(()). (This commit also makes exit() work consistently in the same way) An attempt to pattern match a variable with the same name as a union-constructor now gives an error as a way to guard against mistakes made because of this change. There is probably an argument for supporting the old syntax via some syntactic sugar, as it is slightly prettier that way, but for now I have chosen to keep the implementation as simple as possible. The RISCV spec, ARM spec, and tests have been updated to account for this change. Furthermore the option type can now be included from $SAIL_DIR/lib/ using $include <option.sail>
2018-03-02Use sail_lib.lem values in C backendAlasdair Armstrong
Rather than just using strings to represent literals, now use value types from sail_lib.lem to represent them. This allows for expressions to be evaluated at compile time, which will be useful for future optimisations involving constant folding and propagation, and allows the intermediate bytecode to be interpreted using the same lem builtins that the shallow embedding uses. To get this to work I had to tweak the build process slightly to allow ml files to import lem files from gen_lib/. Hopefully this doesn't break anything!
2018-03-01Cleanup intermediate bytecode representation in C backendAlasdair Armstrong
2018-02-27Fix some bugs in C compilation, and optimise struct updatesAlasdair Armstrong
Fix some issues where some early returns in functions would cause memory leaks, and optimize struct updates so the struct is not copied uneccesarily. Also make C print_bits match ocaml version output, and update tests.
2018-02-26Add some obvious optimisations to C backend.Alasdair Armstrong
With these optimisations on, now get about 10x performance over OCaml.
2018-02-23Fix some bugs in C compilationAlasdair Armstrong
Fixed an issue with pattern matching on enums Fixed an issue whereby fix_early_returns would cause memory leaks Added optimizations for some of the builtins used in the decode function. Optimizations are turned on with the -O flag.
2018-02-22More updates to C backendAlasdair Armstrong
Add support for short-ciruiting and/or. I forgot about this in the original ANF specification and not having it causes problems for the ARM spec.