pub enum Step {
Show 13 variants
Switches,
Retries,
Orderings,
Overflows,
Halves,
Widths,
Bytes,
Counts,
Quads,
Floats,
Bulk,
Rounds,
Varargs,
}Expand description
One member of the group.
The name of the variant is the name of the construct rather than the name of the function that takes it out, because the membership is a list of constructs. Which function answers for one is something this file knows and nothing outside it needs to.
Variants§
Switches
A switch, as the decision tree document 24 describes.
Retries
A read modify write this machine has no single instruction for, as a loop around the compare and exchange.
Beside the switches rather than down with the rest of the rewriting, because both of them
make blocks and nothing in crate::expand may.
Orderings
An ordered load or store, as the plain access and a barrier.
Above everything below it, since what an ordered access becomes here is a plain one and every pass below is written about a plain one by name. It is also why this is above the retries rather than below: the head of the loop they build reads with an ordered load.
Overflows
An arithmetic operation that also says whether it overflowed, as the arithmetic and the test.
Above the splitting rather than below it, because an overflow check is the one instruction whose result is two things and the splitting has no answer for that, while the arithmetic it becomes here is adds, multiplies and comparisons the splitting knows already. Nothing is lost by running it this early: the widths it is written for are the widths the machine has, so a check at any other width is refused by name either way round.
Halves
An integer wider than a register, as the two halves of one.
Ahead of the width legalisation and not part of it, because the two go in opposite directions: an integer of forty bits becomes one of sixty four down there and one of a hundred and twenty eight becomes two of sixty four here. Doing this first means a function holding both is one the step below still works on.
Widths
An integer at a width the machine does not have, as the width it is held in.
Before everything after it, because every pass after it is written about widths the machine has and an integer of forty bits is not one of them.
Bytes
A byte reversal, as the halving run of swaps it is.
Counts
A leading zero, trailing zero or set bit count, as the arithmetic that answers it.
Quads
Anything at all at the quad float format, as a call to the routine for it.
Above the float rewriting rather than part of it, because the two are written about different machines: every rewrite down there ends at an instruction this machine has, and every operation up here ends at a call because this machine has no instruction at the format at all. Running first means the step below never sees a quad.
Floats
A float constant, a negation and the conversions, as the integer work spec 10.2 asks for.
Bulk
A memcpy, a memset or a memmove, as the moves it is or as the call it is too big for.
Rounds
The size of a stack allocation, rounded up to what the stack pointer has to stay on.
The one step here that takes nothing out. It rewrites an operand of the instruction and
leaves the instruction where it is, which is why Step::opcodes answers with nothing for
it.
Varargs
A variable argument list, as spec 10.7’s split describes.
Implementations§
Source§impl Step
impl Step
Sourcepub const GROUP: &'static [Self]
pub const GROUP: &'static [Self]
The group, in the order it runs, which is the membership section 36.1 asks to see.
Sourcepub const fn construct(self) -> &'static str
pub const fn construct(self) -> &'static str
The construct it is the answer to, in the words section 36.1 uses for it.
Sourcepub const fn opcodes(self) -> &'static [Opcode]
pub const fn opcodes(self) -> &'static [Opcode]
The opcodes it is the answer to, which is what Did::found and Did::left count.
Not a promise that none of them survive. Several of these steps have a case they leave where it stands, either because the machine turns out to have the construct after all or because this is a refusal being handed to the selector to name, and both of those show up here as a count that did not reach zero. What the pair of numbers is for is telling somebody reading a dump which of those happened.
Empty for Step::Rounds, which rewrites an operand rather than taking an instruction out,
and empty for the three that work by type rather than by opcode: an integer of forty bits,
one of a hundred and twenty eight and a quad float are all spelled with the same opcodes as
anything else, and what makes them the construct is the type on the values.
Sourcepub const fn whole_function(self) -> bool
pub const fn whole_function(self) -> bool
Whether this step works on the whole function at once and says whether it rewrote it.
Two of them do. Both retype every value of a width, so either the whole function can be
rewritten or none of it can, and they answer with a boolean for that reason. A false from
one covers two different things, a function with nothing at that width in it and a function
holding something the step did not understand, and neither is an error: the second leaves
the selector to refuse by naming the construct it had no rule for.
Everything else here works instruction by instruction and has nothing to say at that scale,
which is why Did::untouched is only ever true for these two.