Commit Graph

886 Commits

Author SHA1 Message Date
Jakob Stoklund Olesen
b3fa47cacc Add support for emergency spill slots.
- Create a new kind of stack slot: emergency_slot.
- Add a get_emergency_slot() method which finds a suitable emergency
  slot given a list of slots already in use.
- Use emergency spill slots when schedule_moves needs them.
2017-10-06 10:45:13 -07:00
Jakob Stoklund Olesen
d0b4c76262 Use a non-allocating sort algorithm.
The sort_unstable* functions are available in stable Rust now. These
functions never allocate memory.
2017-10-06 09:21:30 -07:00
Jakob Stoklund Olesen
b562fdcd5c Remove the dfg::resolve_copies() method.
This method was important back when result values couldn't be moved
between instructions. Now that results can be moved, value aliases do
everything we need.

Copy instructions are still used to break interferences in the register
allocator's coalescing phase, but there isn't really any reason to use a
copy instruction over a value alias anywhere else.

After and during register allocation, copy instructions are significant,
so we never want to "see through" them like the resolve_copies()
function did.

This is related to #166, but probably doesn't fix the underlying
problem.
2017-10-05 14:46:34 -07:00
Jakob Stoklund Olesen
30aeb57083 Add a value location verifier.
This is a verification pass that can be run after register allocation.
It verifies that value locations are consistent with constraints on
their uses, and that the register diversions are consistent.

Make it clear that register diversions are local to an EBB only. This
affects what branch relaxation is allowed to do.

The verify_locations() takes an optional Liveness parameter which is
used to check that no diverted values are live across CFG edges.
2017-10-05 13:59:18 -07:00
Jakob Stoklund Olesen
73d4bb47c0 Intel encodings for regspill and regfill.
These are always SP-based.
2017-10-04 17:02:09 -07:00
Jakob Stoklund Olesen
826d4062fb Apply register diversions during binemit tests.
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.
2017-10-04 17:02:09 -07:00
Jakob Stoklund Olesen
dda3efcbdd Add regspill and regfill instructions.
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.
2017-10-04 17:02:09 -07:00
Jakob Stoklund Olesen
d4aeec6ece Generalize RegDiversions to track stack locations too.
For emergency spilling, we need to be able to temporarily divert an SSA
value to a stack slot if there are no available registers.
2017-10-04 17:02:09 -07:00
Jakob Stoklund Olesen
e32aa8ab60 Emergency spilling for the solver's move scheduler.
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.
2017-10-04 17:02:09 -07:00
Jakob Stoklund Olesen
ce4d723a73 Give RegClassData a reference to its parent RegInfo.
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.
2017-10-04 17:02:09 -07:00
Dan Gohman
7410ddfe08 Use the WasmRuntime's signature list rather than keeping a separate list.
This way, if the runtime modifies the signature, such as to add special
arguments, they are reflected in the resulting function defintions.
2017-10-04 16:57:39 -07:00
Jakob Stoklund Olesen
fb0999ce33 Check the top-level register class for available registers.
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.
2017-10-03 14:12:18 -07:00
Jakob Stoklund Olesen
739d414d18 Convert regalloc::coloring to use an EncCursor.
No functional change intended, this is just a big fight with the borrow
checker.
2017-10-03 13:39:43 -07:00
Jakob Stoklund Olesen
7c023b2430 Don't omit the controlling typevar for instructions without results.
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.
2017-10-03 13:39:43 -07:00
Jakob Stoklund Olesen
e10b3117cb Rename enc_flt() to enc_both().
This encoding method is not only used for floating point instructions.
2017-10-03 13:27:00 -07:00
Jakob Stoklund Olesen
c091a695e6 Fix coalescer bug exposed by the gvn-unremovable-phi test.
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.
2017-10-03 11:13:46 -07:00
Jakob Stoklund Olesen
ef048b8899 Allow for call args in incoming stack slots.
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.
2017-10-03 11:13:46 -07:00
Dan Gohman
374ed3a07b Fix dominator-tree queries on unreachable nodes. 2017-10-03 11:03:06 -07:00
Dan Gohman
d585f09423 Don't silently swallow lexer errors. 2017-10-03 10:05:46 -07:00
Dan Gohman
7c7b1651d8 Do a full compile in 'cton-util wasm'.
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.
2017-10-03 09:39:07 -07:00
Dan Gohman
25b8b45a41 Avoid unnecessary BufReaders. 2017-10-03 09:34:41 -07:00
Jakob Stoklund Olesen
3a34c35f95 Don't swap the arguments to the select instruction.
Both WebAssembly and Cretonne use true-value, false-value.
2017-10-02 14:43:30 -07:00
Jakob Stoklund Olesen
5f56f81251 Resolve all value aliases when computing live ranges.
Value aliases are only in the way during register allocation, so make
sure they are all dead as we enter the register allocation passes.
2017-09-29 15:54:06 -07:00
Jakob Stoklund Olesen
c82e68efea Eliminate the ABCD register class constaint in REX encodings.
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.
2017-09-29 15:29:25 -07:00
Jakob Stoklund Olesen
51a6901a7f Implement coloring::iterate_solution().
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.
2017-09-29 14:55:35 -07:00
Jakob Stoklund Olesen
86e22e7de5 Add long-range encodings for conditional branches.
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.
2017-09-29 13:18:29 -07:00
Jakob Stoklund Olesen
50ccd000a9 Implement branch relaxation.
Now that we have the legal_encodings iterator, it is simpler to find an
alternative branch encoding with a better range.
2017-09-29 12:42:34 -07:00
Jakob Stoklund Olesen
45888ab84e Reload for spilled call return values.
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.
2017-09-29 11:25:38 -07:00
Jakob Stoklund Olesen
711e5cd644 Handle srem INT_MIN, -1 correctly.
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.
2017-09-29 08:53:49 -07:00
Jakob Stoklund Olesen
53404a9387 Check for invalid special type constraints.
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.
2017-09-28 16:30:19 -07:00
Jakob Stoklund Olesen
2888ff5bf3 Fix a corner case in fcvt_to_sint.i32.f64 legalization.
An f64 can represent multiple values in the range INT_MIN-1 < x <=
INT_MIN which all truncate to INT_MIN, so comparing the input value
against INT_MIN is not good enough.

Instead, detect overflow on x <= INT_MIN-1 when INT_MIN-1 is an exact
floating point value.
2017-09-28 14:24:39 -07:00
Jakob Stoklund Olesen
8abcdac5a1 Legalize fcvt_to_sint and fcvt_to_uint for Intel64.
We need to generate traps on NaN and overflow.
2017-09-28 12:00:38 -07:00
Jakob Stoklund Olesen
34146435e5 Legalize unsigned-to-float conversions for Intel 64.
Also make sure we generate type checks for the controlling type variable
in legalization patterns. This is not needed for encodings since the
encoding tables are already keyed on the controlling type variable.
2017-09-28 11:39:19 -07:00
Jakob Stoklund Olesen
979a22f548 Add pow2() and neg() methods for the IEEE immediate types.
These are convenient methods for creating common floating point
constants.
2017-09-28 11:34:02 -07:00
Jakob Stoklund Olesen
a274cdf275 Fix the Intel encoding of band_not.
The andnps instruction inverts its first argument while band_not inverts
is second argument.

Use a swapped-operands "fax" encoding recipe.
2017-09-27 18:14:13 -07:00
Jakob Stoklund Olesen
1d481d7897 Use the ThreadId to name cretonne.dbg in unnamed threads.
Don't use a single cretonne.dbg log file when there are multiple unnamed
threads logging. They will clobber each other.
2017-09-27 16:27:49 -07:00
Jakob Stoklund Olesen
84471a8431 Add some very basic support for the Intel32 ABI.
In 32-bit mode, all function arguments are passed on the stack, not in
registers.

This ABI support is not complete or properly tested, but at least it
doesn't try to pass arguments in r8.
2017-09-27 12:55:34 -07:00
Jakob Stoklund Olesen
b6b474a8c9 Add Intel legalization for fmin and fmax.
The native x86_fmin and x86_fmax instructions don't behave correctly for
NaN inputs and when comparing +0.0 to -0.0, so we need separate branches
for those cases.
2017-09-27 12:55:34 -07:00
Jakob Stoklund Olesen
384b04b411 Fix some misnamed TailRecipes and add a consistency check. 2017-09-27 12:55:34 -07:00
Jakob Stoklund Olesen
44eab3e158 Add Intel regmove encodings for floating point types. 2017-09-27 12:49:54 -07:00
Jakob Stoklund Olesen
1fe7890700 Add x86_fmin and x86_fmax instructions.
These Intel-specific instructions represent the semantics of the minss /
maxss Intel instructions which behave more like a C ternary operator
than the WebAssembly fmin and fmax instructions.

They will be used as building blocks for implementing the WebAssembly
semantics.
2017-09-27 09:17:09 -07:00
Jakob Stoklund Olesen
ac69f3bfdf Add an Intel-specific x86_cvtt2si instruction.
This is used to represent the non-trapping semantics of the cvttss2si and
cvttsd2si instructions (and their vectorized counterparts).

The overflow behavior of this instruction is specific to the Intel ISAs.

There is no float-to-i64 instruction on the 32-bit Intel ISA.
2017-09-26 15:44:41 -07:00
Dan Gohman
d13f29cfe4 Update to wasmparser 0.11.2. 2017-09-26 14:58:50 -07:00
Jakob Stoklund Olesen
6ff681a90d Add general legalization for the select instruction. 2017-09-26 14:16:35 -07:00
Jakob Stoklund Olesen
ce767be703 Intel encodings for floating point copies. 2017-09-26 13:54:38 -07:00
Jakob Stoklund Olesen
7fb6159a85 Add Intel encodings for the fcmp instruction.
Not all floating point condition codes are directly supported by the
ucimiss/ucomisd instructions. Some inequalities need to be reversed and
eq+ne require two separate tests.
2017-09-26 11:17:32 -07:00
Jakob Stoklund Olesen
79968a2325 Add standard expansions for fcopysign.
This is also just a sign bit manipulation.
2017-09-25 15:17:32 -07:00
Jakob Stoklund Olesen
6bec5f8507 Intel encodings for nearest/floor/ceil/trunc.
These floating point rounding operations all use the roundss/roundsd
instructions that are available in SSE 4.1.
2017-09-25 15:08:04 -07:00
Jakob Stoklund Olesen
ac343ba92a Add encodings for square root instructions. 2017-09-25 13:15:09 -07:00
Dan Gohman
36585ddc4f Wasm control stack entries only need the number of return types.
This eliminates heap-allocated vectors which stored the actual types.
2017-09-25 13:05:29 -07:00