Commit Graph

2269 Commits

Author SHA1 Message Date
Jakob Stoklund Olesen
9629867d0c Encodings for load/store instructions.
We don't support the full set of Intel addressing modes yet. So far we
have:

- Register indirect, no displacement.
- Register indirect, 8-bit signed displacement.
- Register indirect, 32-bit signed displacement.

The SIB addressing modes will need new Cretonne instruction formats to
represent.
2017-05-12 16:49:39 -07:00
Jakob Stoklund Olesen
c998df6274 Add subtract and logical instruction encodings to Intel-32.
Also add versions with 8-bit and 32-bit immediate operands.
2017-05-12 15:37:12 -07:00
Jakob Stoklund Olesen
3aaa8b2f91 Return the first applicable encoding from general_encoding().
We'll arrange encoding lists such that the first suitable encoding is
the best choice for the legalizer. This is the most intuitive way of
generating the encodings.

After register allocation, we may choose a different encoding, but that
will require looking at the whole list.
2017-05-12 15:31:08 -07:00
Jakob Stoklund Olesen
4158c4e09c Implement reloc_names() for all targets.
This gets rid of the last TargetIsa method with a default
implementation.
2017-05-11 17:58:11 -07:00
Jakob Stoklund Olesen
663b50efcc Add fixed constraints for ABI arguments and return values.
We can start adding some real test cases for the move resolver now.
2017-05-11 12:02:02 -07:00
Jakob Stoklund Olesen
51fc887a5a Implement a move resolver for the register constraint solver.
After finding a register solution, it need to be executed as a sequence
of regmove instructions. This often requires a topological ordering of
the moves so they don't conflict.

When the solution contains cycles, try to grab an available scratch
register to implement the copies. Panic if that fails (later, we'll
implement emergency spilling in this case).

Make sure we handle odd aliasing in the arm32 floating point register
bank. Not everything is a simple cycle in that case, so make sure we
don't assume so.
2017-05-11 11:54:02 -07:00
Jakob Stoklund Olesen
f8e466d60e Solver variables keep track of where they came from.
The register constraint solver has two kinds of variables:

1. Live values that were already in a register, and
2. Values defined by the instruction.

Make a record of the original register holding the first kind of value.
2017-05-11 11:54:02 -07:00
Jakob Stoklund Olesen
4dda3e02f1 Simplify the dead EBB argument tracking.
It is not necessary to to a second pass over the live values to update
the set of available registers. The color_args() and color_entry_args()
functions can do that in a single pass.
2017-05-11 11:48:58 -07:00
Jakob Stoklund Olesen
9f743cf3a5 Always create live ranges for dead EBB arguments.
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.
2017-05-11 11:42:44 -07:00
Jakob Stoklund Olesen
d03a217466 Keep dead EBB arguments around in LiveValueTracker::ebb_top().
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.
2017-05-11 11:28:39 -07:00
Jakob Stoklund Olesen
9d4e23d894 Propagate a few more LiveRange properties to LiveValue.
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.
2017-05-11 11:28:39 -07:00
Dan Gohman
5ff2257b12 Check for unknown instruction attributes. (#80)
* Check for unknown instruction attributes.

* Avoid has_key, at flake8's advice.

* Use AssertionError instead of RuntimeError, per review request.
2017-05-11 10:21:59 -07:00
Dan Gohman
526feb161a Fix rustfmt diffs. 2017-05-11 06:57:55 -07:00
Dan Gohman
c571975a5c Use write! in utility code, rather than calling write_function directly. 2017-05-11 06:57:55 -07:00
Jakob Stoklund Olesen
be047ba5c4 Use a constraint solver for register coloring.
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.
2017-05-09 14:48:45 -07:00
Jakob Stoklund Olesen
0dbdd90af7 Add a register diversion tracker.
Keep track of the current location of register values as regmove
instructions are encountered throughout an EBB.
2017-05-09 14:48:45 -07:00
Jakob Stoklund Olesen
cdb3a71dd1 Add encodings for Intel dynamic shift instructions.
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".
2017-05-09 13:11:50 -07:00
Dan Gohman
db9f64d2f3 Make srem have the sign of the dividend.
This is how remainder is defined in C (as of C99), C++ (as of C++11), Rust,
and WebAssembly, for example.
2017-05-09 12:28:15 -07:00
Jakob Stoklund Olesen
5bdb61a5f1 Add the very basics of Intel 32-bit instruction encodings.
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.
2017-05-08 16:57:38 -07:00
Jakob Stoklund Olesen
3d2fdec1af Add constraint summaries to RecipeConstraints.
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.
2017-05-08 16:41:24 -07:00
Jakob Stoklund Olesen
b3b15f9c32 Add support for 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.
2017-05-08 16:31:47 -07:00
Jakob Stoklund Olesen
fedc834ecd Also return live-through values from process_inst().
The coloring algorithm will need to look at the live-through values to
check if they interfere with fixed-register outputs for calls etc.
2017-05-08 13:57:39 -07:00
Jakob Stoklund Olesen
d1d6c626d9 Add a few register utilities. 2017-05-08 13:39:26 -07:00
Jakob Stoklund Olesen
9bbeaeda24 Add a regs_overlap function to the isa module.
Test it with the arm32 register banks which have the most interesting
properties. Most other registers have a single register unit.
2017-05-08 13:36:27 -07:00
Jakob Stoklund Olesen
673279068f Run mypy in python 3 mode.
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.
2017-05-08 13:29:01 -07:00
Jakob Stoklund Olesen
7a1ba057e4 Ignore .mypy_cache
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.
2017-05-08 13:28:49 -07:00
Jakob Stoklund Olesen
8cd67f08a9 Add a regmove instruction.
This will be used to locally change the register locations of values in
order to satisfy instruction constraints.
2017-05-02 11:32:12 -07:00
Jakob Stoklund Olesen
6fe4aa2f8d Extract the topological ordering into a module.
Multiple passes will need to iterate over EBBs in a
dominator-topological order. Move that functionality into a separate
module.
2017-04-27 17:39:58 -07:00
Jakob Stoklund Olesen
a29ea664e2 Install rustfmt as a separate Travis install step.
- 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.
2017-04-27 13:55:13 -07:00
Jakob Stoklund Olesen
15606fa735 Upgrade to rustfmt 0.8.3. 2017-04-27 12:52:41 -07:00
Jakob Stoklund Olesen
962a3a6a5e Upgrade to Rust 1.17.
- Remove some uses of 'static in const and static globals that are no
  longer needed.
- Use the new struct initialization shorthand.
2017-04-27 12:46:44 -07:00
Jakob Stoklund Olesen
4c8eb85f39 Color entry block arguments using the function signature.
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.
2017-04-26 14:38:16 -07:00
Jakob Stoklund Olesen
bb8ae9a4fb Add a TargetIsa::allocatable_registers() method.
This gives the target ISA a chance to reserve registers like the stack
pointer or hard-wired 0 registers like %x0 on RISC-V.
2017-04-26 13:54:40 -07:00
Jakob Stoklund Olesen
305de3e73b Add an enable_e setting for the RV32E instruction set.
This limited RISC-V version only has registers %x0 - %x15.

Make sure the ABI lowering code doesn't use the banned registers for
arguments.
2017-04-26 13:50:52 -07:00
Jakob Stoklund Olesen
1e51f97108 Rename Affinity::Any to Affinity::None.
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.
2017-04-26 11:20:17 -07:00
Jakob Stoklund Olesen
2f866171ca Add an Affinity::display() method.
Make it possible to display affinities given a RegInfo reference.
2017-04-26 11:16:38 -07:00
Jakob Stoklund Olesen
93db01d38a Assign an affinity to function argument values.
Use the argument types from the function signature to initialize the
affinity of register and stack arguments.
2017-04-26 10:50:56 -07:00
Jakob Stoklund Olesen
cd99eee86b Add a TargetIsa::regclass_for_abi_type() function.
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.
2017-04-26 10:29:18 -07:00
Jakob Stoklund Olesen
c36aedfd03 Add an EntityMap::get_or_default() method.
This covers a common pattern for secondary entity maps: Get the value in
the map or the default value for out-of-range keys.
2017-04-25 15:53:30 -07:00
Eric Anholt
a332c3d024 Make sure that encodings has entries for all instructions after legalize().
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.
2017-04-23 17:21:32 -07:00
Eric Anholt
b13cd2321c Make sure we double back after legalizing an instruction.
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.
2017-04-23 17:21:32 -07:00
Eric Anholt
551a91178a Update a comment for the move of display_enc(). 2017-04-23 17:21:32 -07:00
Eric Anholt
100666e300 Verify that the instruction encoding matches what the ISA would encode.
Fixes #69
2017-04-23 17:21:32 -07:00
Jakob Stoklund Olesen
5d9e703e4f Run the post-regalloc verification inside the regalloc context.
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.
2017-04-21 16:25:24 -07:00
Jakob Stoklund Olesen
85f277a2fb Add a liveness verifier.
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.
2017-04-21 16:01:08 -07:00
Jakob Stoklund Olesen
225ed39fbd Run the verifier in the Context methods when it is enabled.
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.
2017-04-21 12:36:35 -07:00
Jakob Stoklund Olesen
b6105ab79b Verifier results are always void.
No need for a type parameter.
2017-04-21 12:03:05 -07:00
Jakob Stoklund Olesen
83381dadc5 Add global CtonResult and CtonError types.
These are for reporting the overall result of compiling a function.
2017-04-21 11:48:56 -07:00
Jakob Stoklund Olesen
4cf3babda0 Add an enable_verifier setting.
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.
2017-04-21 09:49:03 -07:00
Jakob Stoklund Olesen
c621770507 Move the verifier into a verifier/mod.rs file.
Make room for verifier sub-modules in separate files.
2017-04-20 14:38:03 -07:00