-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Kill Recipes With Fire 🔥 #1141
Comments
I'm all for this. In fact, reading it through carefully I realized that a lot of what I'm trying to work around in the re-factoring I started in bytecodealliance/cranelift#1149 would be easier if we were a couple steps down this road. I started to factor out the common patterns for adding encodings ( |
Yes, this would be nice. I still think there's a need to "inherit" encodings, that is, to be able to use an Encoding as the base of another one, and then just selectively change a few bits; that would maintain factoring opportunities when only the REX.w bit value changes etc., and would effectively be the last step before removing Templates. It could be done through a special EncodingBuilder ctor, or just a function that takes an Encoding input and returns a modified copy.
If I understand correctly you're referring to binemit code, which will live in the Encoding, or ideally in a separate function that's indirectly referenced through an enum living in the Encoding, since these binemit functions may still be common to many Encodings. |
@bnjbvr Is there any need to "inherit" encodings other than to support generation (or omission) of REX prefixes? |
I think so, see |
@bnjbvr In trying to follow instructions to remove Template, I get the feeling that I'm just reinventing it on the A "recipe" is a shared function that knows how to emit instructions that share a similar byte pattern. "Kill Recipes With Fire" does not mean getting rid of these shared functions as I originally thought. (If we were to do that, then x86 wouldn't need a real Instead, this issue is to basically keep the same behavior as recipes, but just move the Do I have that right? I have been a bit confused by the direction to have more run-time decision making of REX prefix emission while simultaneously eliminating recipes, because different opcodes encode REX in a different position, so there is no simple logic that's valid in all cases (that I'm aware of). |
It sounds right to me. Note that the above plan is an outline, and there is definitely room for exploration of alternative ways to implement it.
Could we eliminate the REX-prefixed recipes without eliminating recipes as a whole at the same time, so work could remain incremental? I think the former can be implemented without the latter. |
In some cases, compute_size() is used to choose between various different Encodings before one has been assigned to an instruction. For x86, the REX.W bit is stored in the Encoding. To share recipes between REX/non-REX, that bit must be inspected by compute_size().
The new backend framework doesn't use recipes. |
Indeed; we might as well close this one now! |
(Really a meta-issue about the meta-crate!)
Nobody likes Recipes. They were supposed to contain factored-out fields of the encodings. But they're mostly one indirection layer that's hard to understand, that needs to be explained to newcomers, and doesn't solve the factoring out problem ideally. For instance, if you want to use one recipe, but just one register allocation constraint differs from the one you're looking at, you'll need to duplicate it and change the one constraint. Other things that are always unclear are whether an instruction/ISA predicate should be attached to an Encoding or to the underlying Recipe.
Let's kill recipes with fire. There's been discussions about this, and a general agreement that it's the right thing to do: it'll make the code easier to understand, more straightforward, and it'll be more pleasant for contributors in general.
The general plan is backed by the following idea:
I've thought about this, and I think the following groups can be done in chunks, so they can serve as divides of the work that's needed here:
Template
by helper functions that take an Encoding and tweak it to return a new encoding.operands_in/operands_out
right now, giving constraints to Value inputs and outputs of a given Instruction.base_size/compute_size/branch_range
). Note (I think) we don't need to move theformat
field, because an Encoding is attached to an Instruction that has its own format. (Because of recipes, one could attach different formats to the Instruction / Encoding, causing a runtime error in the build script. Good riddance!)clobbers_flags
to the Encoding.Some of these items might not be doable as I expect; I tried to imagine what the could would ideally look like, but the reality of how things are in Cranelift may have us go down a different road.
Each step will imply some work in the codegen crate too, to make sure it's still working properly, as well as opportunities for simplifications. I haven't put items for each simplification, because it's somewhat unclear in general what these could be, but they may exist. It'd be nice that each step belonged to its own PR (substeps can go in commits), to avoid boiling the ocean at once ;)
The text was updated successfully, but these errors were encountered: