When "binemit" tests encode instructions, keep track of the current set
of register diversions, and use the diverted locations to check operand
constraints.
This matches how constraints are applied during a real binemit phase.
These are parallels to the existing regmove instruction, but the divert
the value to and from a stack slot.
Like regmove diversions, this is a temporary diversion that must be
local to the EBB.
The register constraint solver schedules a set of move instructions to
execute before the instruction getting colored. In extreme cases, this
is not possible because there are no available registers to break cycles
in the register assignments that must be scheduled.
When that happens, we spill one register to an emergency slot so it
becomes available for implementing the assignment cycle. Then the
original register is restored.
The coloring pass can't yet understand the spill and fill move types.
This will be implemented next.
This makes it possible to materialize new RegClass references without
requiring a RegInfo reference to be passed around.
- Move the RegInfo::toprc() method to RegClassData.
- Rename RegClassData::intersect() to intersect_index() and provide a
new intersect() which returns a register class.
- Remove some &RegInfo parameters that are no longer needed.
Fixes#165.
The constraint solver's schedule_move() function sometimes need to use
an extra available register when the moves to be scheduled contains
cycles.
The pending moves have associated register classes that come from the
constraint programming. Since the moves have hard-coded to and from
registers, these register classes are only meant to indicate the
register sizes. In particular, we can use the whole top-level register
class when scavenging for a spare register to break a cycle.
The controlling type variable passed to the format constructor in the
InstBuilder trait is not just used to generate the result values. In an
EncCursor, it is also used to encode the instruction, so VOID doesn't
work.
When we detect interference between the values that have already been
merged into the candidate virtual register and an EBB argument, we first
try to resolve the conflict by splitting. We also check if the existing
interfering value is fundamentally incompatible with the branch
instruction so it needs to be removed from the virtual register,
restarting the merge operation.
However, this existing interfering value is not necessarily the only
interference, so the split is not guaranteed to resolve the conflict. If
it turns out that splitting didn't resolve the conflict, restart the
merge after removing this second conflicting value.
A value passed as an argument to a function call may live in an incoming
stack slot initially. Fix the call legalizer so it copies such an
argument into the expected outgoing stack slot for the call.
This removes the `optimize` option, as one can do that with
`--set`, eg. `--set opt_level=best`. And it adds an option to
print the compilation output.
And, it enables simple_gvn and licm for opt_level=best.
This removes the `optimize` option, as one can do that with
`--set`, eg. `--set opt_level=best`. And it adds an option to
print the compilation output.
Some REX-less encodings require an ABCD input because they are looking
at 8-bit registers. This constraint doesn't apply with a REX prefix
where the low 8 bits of all registers are addressable.
It can happen that the currently live registers are blocking a smaller
register class completely, so the only way of solving the allocation
problem is to turn some of the live-through registers into solver
variables.
When the quick_solve attempt fails, try to free up registers in the
critical register class by turning live-through values into solver
variables.
The brz and brnz instructions get support for 32-bit jump displacements
for long range branches.
Also change the way branch ranges are specified on tail recipes for the
Intel instructions. All branch displacements are relative to the end of
the instruction, so just compute the branch range origin as the
instruction size instead of trying to specify it in the tail recipe
definitions.
When the return value from a call has been spilled, the reload pass
needs to insert a spill instruction right after the call instruction
which returns its results in registers.
The x86_divmodx traps on integer overflow, but the srem instruction is
not supposed to trap with a -1 divisor.
Generate a legalization expansion for srem that special-cases the -1
divisor to simply return 0.
The extend and reduce instructions have additional type constraints.
Stop inserting sextend instructions after ctz, clz, and popcnt when
translating from WebAssembly. The Cretonne instructions have the same
signature as the WebAssembly equivalents.