-
Notifications
You must be signed in to change notification settings - Fork 145
Add support for C++ output #1437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Test Results 15 files 34 suites 0s ⏱️ Results for commit c3e95fe. ♻️ This comment has been updated with latest results. |
It's entirely for backwards compatibility really. I don't think there is much of a use case either.
Would be fine removing that option honestly, I also don't really see the point. Just need to make sure any uses of static are actually what we really want. It's less code paths for me to maintain the less options we have anyway! 😉 |
9ee0bcb to
6cf5c06
Compare
|
Ok I think this is basically done. Almost all the tests pass except a few which have custom C code and are therefore a bit awkward. I marked them as expected failures. This PR includes earlier commits to remove the The two things I'm not 100% sure about:
|
6cf5c06 to
b485440
Compare
|
I think the intent behind that flag was to just avoid including the Sail runtime headers in case you want to provide your own. I don't think there would be anyone depending on that flag so also likely safe to remove. A better way to do that would just be to have an option that removes all default header includes, then anyone who wants something custom can just use |
|
Ah ok. Yeah I think just not emitting the includes is easier, though tbh we did custom headers just by copying & pasting all of the C files elsewhere and that worked fine. I'll add a |
|
Also is there a way to see the actual output for failed tests in CI? |
|
Right now you need to go digging through the logs. Not sure the best way to pass the error messages through the various GitHub CI jobs. and |
|
Also: which I think is one of the tests that is doing some custom linking with some C code. |
|
Oh weird, I thought I marked those tests as expected failures. Should it still print the error messages for expected failures? |
|
Ah, I think you are right. It's this test The other failure is to do with the Rocq backend due to the change to |
a352b57 to
a5d003d
Compare
|
Hmm so the segfault was due to the handling of abstract types. I fixed the segfault but it still leaks. The issue is that it used to work like this in C: And in C++ it changed so The segfault was caused because In the C version it's fine because it's a global and those are zero-initialised, and a zero-initialised So I fixed that by generating However the next issue is that Valgrind now detects that it is never The obvious solution is to Any ideas? |
|
Hold on, actually I can just add a constructor & destructor. I should probably delete the copy constructor too while I'm at it, and I'll change it to |
|
Looks like it's just the ocamlformat check in the CI now? |
src/sail_c_backend/c_backend.mli
Outdated
| (** Global compilation options *) | ||
|
|
||
| (** If set generate a C++ struct for the model instead of global C functions/variables. *) | ||
| val opt_cpp : bool ref |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if these could be an option in the CODEGEN_CONFIG module type? Would avoid adding any mutable variables, as I was trying to move away from these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see. Yeah that makes sense, I'll have a go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/sail_c_backend/sail_plugin_c.ml
Outdated
| Arg.String (fun prefix -> C_backend.opt_prefix := prefix), | ||
| "prefix generated C functions" | ||
| ); | ||
| (Flag.create ~prefix:["c"] "cpp", Arg.Set C_backend.opt_cpp, "generate C++ struct instead of global C functions"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-c --c-cpp seems a bit counterintuitive. We could set this up so it's just --cpp by creating a new target, and the --c-cpp-struct-name would just be --cpp-struct-name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I agree it is weird. Guess I was just being lazy. I'll have a go at adding a new target.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably easiest way would be to do something like:
let c_target is_cpp out_file { ast; effect_info; env; default_sail_dir; _ } =
and then change the last two lines of sail_plugin_c into:
Target.register ~name:"c" ~options:c_options ~rewrites:c_rewrites ~supports_abstract_types:true
~supports_runtime_config:true (c_target false);
Target.register ~name:"cpp" ~options:cpp_options ~rewrites:c_rewrites ~supports_abstract_types:true
~supports_runtime_config:true (c_target true)
The cpp_options list would just contain the new options for the C++ generation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't totally obvious that the --c-foo options also apply to the cpp backend but I guess it will do. I changed some of the help messages from ... C ... to ... C/C++ ... which hopefully makes that clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want we could duplicate options as either --c-xyz or --cpp-xyz when they are shared. I left a comment further down.
arichardson
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great
a5d003d to
c92ae7e
Compare
Huh weird, Valgrind was definitely complaining about the leaks (correctly) when I ran it locally. Adding the constructor/destructor wasn't too hard and it fixes the leaks so I think that's best. I think a backend that fully embraced C++ would be a lot easier to write - all of the CREATE(), CONVERT_OF() etc. stuff could be handled uniformly by constructors/operator overloading. Though maintaining a whole extra backend would probably cancel all that out. :-/ Also I don't know how you remember to run |
|
I was thinking a while ago that the As for |
dbd70a4 to
8ca463c
Compare
|
Hmm moving the options seems to have totally changed the codegen in a breaking way. I can't figure it out... any ideas @Alasdair ? |
|
Oh, changing the flag to a separate
Anything that does |
|
For the options, you could do something like then |
|
Ok I think I fixed
The slightly odd thing though is it will print I was kind of surprised it was smart enough to merge them, but it isn't really what we want in this case. Also the Also what happens if you do I think it's probably better just to have the |
I think it should be possible to make it so that with |
It would be the same as if you repeated the same flag - the semantics of that depends on how the flags work. I agree it's probably best to just keep it simple for now. |
4708ea9 to
fe62785
Compare
|
Hmm there's still something missing (aside from the failing tests). It used to generate this: But now: And there's no definition or declaration of |
|
Is that something that's happening in the RISC-V model? I don't see it in any of the CI failures? |
fe62785 to
4888681
Compare
Yeah exactly, this WIP branch: https://github.com/Timmmm/sail-riscv/tree/user/timh/cpp |
|
Think it might just be that functions in I figure I should merge #1446 first then this can be rebased on that? |
|
Oh yeah of course, I forgot about that! That pesky
Yeah that would be good. I'll make a PR for the commit that removes |
47b067c to
ad29423
Compare
|
I've rebased and reorganised things so only the last commit is relevant for this PR. The others are (or will be) separate PRs. I wish Github had proper native support for stacked PRs. :-/ Also I had to make the |
ad29423 to
6882600
Compare
This adds support for generating C++ code. The model is wrapped in a `struct`, which means you can create multiple instances of it (e.g. to simulate multicore CPUs).
The structure of the C++ code is like this:
```
// Header
namespace model {
<types>
struct Model {
<function declarations>
<variable definitions>
};
}
// Impl
namespace model {
<function definitions>
}
```
This is the only way I found to do it without major changes. We can't put the types in `Model` because there's nothing like `using namespace <SomeClass>::*;` in C++.
6882600 to
c3e95fe
Compare
|
Ok this is ready now I think! |
|
Thanks! |
CHANGES: In addition to bug-fixes and smaller improvements, the following changes and improvements have been made to the language: ##### Rocq Semantics The core stepwise semantics of Sail that are currently used by the interactive REPL and during optimisation passes like constant-folding are now implemented in Rocq and extracted to OCaml. ##### Improved C++ support New C++ `--cpp` backend that is a variant of the Sail C backend. It wraps the generated model in a struct, so when using C++ multiple instances can be created. PR: rems-project/sail#1437 As part of the above work, Sail always generates a separate header file for C or C++, meaning the `--c-generate-header` option is redundant and deprecated. The `--c-static` option has been removed. Small fixes to the parsing of `-` and foreach loops. Slightly breaking as `from`, `to`, and `downto` are now treated as proper keywords and cannot be used as identifiers. ##### Other changes Arguments can now be passed via the `SAIL_FLAGS` environment variable, or via `SAIL_ENCODED_FLAGS`. PR: rems-project/sail#1374
This adds support for generating C++ code. The model is wrapped in a struct, which means you can create multiple instances of it (e.g. to simulate multicore CPUs).
The structure of the C++ code is like this:
This is the only way I found to do it without major changes. We can't put the types in Model because there's nothing like
using namespace <SomeClass>::*;in C++.