The live value tracker expects them to be there.
We may eventually delete dead arguments from internal EBBs, but at least
the entry block needs to be able to handle dead function arguments.
Provide a drop_dead_args() function which deletes them instead.
We still need to assign a register to dead EBB arguments, so they can't
just be ignored.
The live value tracker goes through the trouble of looking up the live
range for each value it tracks. We can cache a few more interesting
properties from the live range in the LiveValue struct.
Most of the time, register coloring is almost trivial: just pick
available registers for the values defined by the current instruction.
However, some instructions have register operand constraints, and it may
be necessary to move live registers around to satisfy the constraints.
Sometimes the instruction's own operands can interfere with each other
in a way that you can't just pick a register assignment for each output
in order.
This is complicated enough that it is worthwhile to represent as a
constraint satisfaction problem in a separate solver module. The
representation is chosen to be very fast in the common case where the
constraints are trivial to solve.
The current implementation is still incomplete, but as functional as the
code it's replacing. Missing features:
- Handle tied operand constraints.
- Handle ABI constraints on calls and return instructions.
- Execute a constraint solution by emitting regmove instructions.
- Handling register diversions before leaving the EBB.
These instructions have a fixed register constraint; the shift amount is
passed in CL.
Add meta language syntax so a fixed register can be specified as
"GPR.rcx".
Tabulate the Intel opcode representations and implement an OP() function
which computes the encoding bits.
Implement the single-byte opcode with a reg-reg ModR/M byte.
Most instructions don't have any fixed register constraints. Add boolean
summaries that can be used to check if it is worthwhile to scan the
constraint lists when looking for a fixed register constraint.
Also add a tied_ops summary bool which indicates that the instruction
has tied operand constraints.
The register constraint for an output operand can be specified as an
integer indicating the input operand number to tie. The tied operands
must use the same register.
Generate operand constraints using ConstraintKind::Tied(n) for both the
tied operands. The n index refers to the opposite array. The input
operand refers to the outs array and vice versa.
This still picks up the 2.7 type annotations in comments.
Fix the compute_quadratic signature to allow for the ValuewView of an
OrderedDict in python 3.
A recent mypy update started writing the .mypy_cache directory which we
don't want under version control. The cache is only used by the
experimental "mypy --incremental" mode which we don't use, but it is
always written anyway.
- Add a check-rustfmt.sh script which checks if the right version of
rustfmt is installed.
- Run check-rustfmt.sh --install as an install step under travis_wait.
This is to work around the issue where cargo takes forever to build
rustfmt, causing Travis to terminate the build because it hasn't
produced any output for 10 minutes.
The arguments to the entry block arrive in registers determined by the
ABI. This information is stored in the signature.
Use a separate function for coloring entry block arguments using the
signature information. We can't handle stack arguments yet.
This value affinity doesn't mean "whatever", it means that the value
does not interact with any real instructions, where "real" means
instructions that have a legal encoding.
Update the liveness verifier to check this property:
- Encoded instructions can only use real values.
- Encoded instructions define real values.
- Ghost instructions define ghost values.
The legalize_signature() function will return ArgumentLoc::Reg arguments
that contain a register unit. However, the register also needs to be
able to associate a register class with the argument values to fully
track the used registers.
When values are defined by instructions, the register class is part for
the operand constraints for the instruction. For values defined on ABI
boundaries like function arguments and return values from a call, the
register class is provided by the new regclass_for_abi_type() function.
Provide implementations of this function in abi modules of all the
targets, even those that don't have a legalize_signature()
implementation yet.
Since we're adding abi modules to all targets, move the
legalize_signature() stubs in there and make the function mandatory in
TargetIsa. All targets will eventually need this function.
If we generated new instructions as part of legalize, and the new
instructions failed to legalize, we'd be left with a func.encodings[]
that would panic when you dereferenced the inst.
The other legalizer cases have a continue after setting the position
to double back, while this one didn't. Make sure that we do, in case
another legalizer block is added after this one.
This means that we can verify the basics with verify_context before
moving on to verifying the liveness information.
Live ranges are now verified immediately after computing them and after
register allocation is complete.
The liveness verifier will check that the live ranges are consistent
with the function. It runs as part of the register allocation pipeline
when enable_verifier is set.
The initial implementation checks the live ranges, but not the
ISA-specific constraints and affinities.
The test drivers can stop calling comp_ctx.verify because legalize() and
regalloc() do it themselves now.
This also makes it possible for those two passes to return other
CtonError codes in the future, not just verifier errors.
This is off by default, but enabled by the parser when reading a textual
IL file. Test files can still override the default to turn off
verification.
The setting enables IL verifier passes at critical points of the
compilation pipeline.
These special-purpose arguments and return values are only relevant for
the function being compiled, so add a `current` flag to
legalize_signature().
- Add the necessary argument values to the entry block to represent
the special-purpose arguments.
- Propagate the link and sret arguments to return instructions if the
legalized signature asks for it.
Enumerate a set of special purposes for function arguments that general
purpose code needs to know about. Some of these argument purposes will
only appear in the signature of the current function, representing
things the prologue and epilogues need to know about like the link
register and callee-saved registers.
Get rid of the 'inreg' argument flag. Arguments can be pre-assigned to a
specific register instead.
- The detach_secondary_results() is a leftover from the two-plane value
representation. Use detach_results() instead to remove all instruction
results.
- Make the append_* DFG methods more direct. Don't depend on calling the
corresponding attach_* methods. Just create a new value directly,
using the values.next_key() trick.