Commit Graph

1571 Commits

Author SHA1 Message Date
Alex Crichton
546e901d32 aarch64: Use smaller instruction helpers in ISLE (#3618)
* aarch64: Use smaller instruction helpers in ISLE

This commit moves the aarch64 backend's ISLE to be more similar to the
x64 backend's ISLE where one-liner instruction builders are used for
various forms of instructions instead of always using the
constructor-per-variant-of-`Inst`. Overall I think this change worked
out quite well and sets up some naming idioms as well for various forms
of instructions.

* rebase conflict
2021-12-17 17:28:52 -06:00
Chris Fallin
e10171b7ea Merge pull request #3619 from cfallin/isle-manifest-siphash
Use SipHasher rather than SHA-512 for ISLE manifest.
2021-12-17 13:15:28 -08:00
Chris Fallin
5233175b06 Use SipHasher rather than SHA-512 for ISLE manifest.
Fixes #3609. It turns out that `sha2` is a nontrivial dependency for
Cranelift in many contexts, partly because it pulls in a number of other
crates as well.

One option is to remove the hash check under certain circumstances, as
implemented in #3616. However, this is undesirable for other reasons:
having different dependency options in Wasmtime in particular for
crates.io vs. local builds is not really possible, and so either we
still have the higher build cost in Wasmtime, or we turn off the checks
by default, which goes against the original intent of ensuring developer
safety (no mysterious stale-source bugs).

This PR uses `SipHash` instead, which is built into the standard
library. `SipHash` is deprecated, but it's fixed and deterministic
(across runs and across Rust versions), which is what we need, unlike
the suggested replacement `std::collections::hash_map::DefaultHasher`.
The result is only 64 bits, and is not cryptographically secure, but we
never needed that; we just need a simple check to indicate when we
forget a `rebuild-isle`.
2021-12-17 12:11:05 -08:00
bjorn3
1dbb747d59 Fix popcnt for small integers 2021-12-17 20:39:53 +01:00
Alex Crichton
e94ebc2263 aarch64: Translate rot{r,l} to ISLE (#3614)
This commit translates the `rotl` and `rotr` lowerings already existing
to ISLE. The port was relatively straightforward with the biggest
changing being the instructions generated around i128 rotl/rotr
primarily due to register changes.
2021-12-17 12:37:17 -06:00
Alex Crichton
d8974ce6bc aarch64: Migrate ishl/ushr/sshr to ISLE (#3608)
* aarch64: Migrate ishl/ushr/sshr to ISLE

This commit migrates the `ishl`, `ushr`, and `sshr` instructions to
ISLE. These involve special cases for almost all types of integers
(including vectors) and helper functions for the i128 lowerings since
the i128 lowerings look to be used for other instructions as well. This
doesn't delete the i128 lowerings in the Rust code just yet because
they're still used by Rust lowerings, but they should be deletable in
due time once those lowerings are translated to ISLE.

* Use more descriptive names for i128 lowerings

* Use a with_flags-lookalike for csel

* Use existing `with_flags_*`

* Coment backwards order

* Update generated code
2021-12-16 17:37:53 -06:00
Chris Fallin
fd171ca063 Fix OperandSize: need clamp-to-32-bit behavior in most cases, but true-width for shifts. 2021-12-16 12:32:28 -08:00
Chris Fallin
1323ae417e Fix some 16- and 8-bit behavior in x64 backend related to rotates.
Uncovered by @bjorn3 (thanks!): 8- and 16-bit rotates were not working
properly in recent versions of Cranelift with part of the lowering
migrated to ISLE.

This PR fixes a few issues:

- 8- and 16-bit rotate-left needs to mask a constant amount, if any,
  because we use a 32-bit rotate instruction and so don't get the
  appropriate shift-amount masking for free from x86 semantics.

- `operand_size_from_type` was incorrect: it only handled 32- and 64-bit
  types and silently returned `OperandSize::Size32` for everything else.
  Now uses the `OperandSize::from_ty(ty)` helper as the pre-ISLE code
  did.

Our test coverage for narrow value types is not great; this PR adds some
runtests for rotl/rotr but more would always be better!
2021-12-16 11:34:24 -08:00
Alex Crichton
4236319a53 aarch64: Migrate some bit-ops to ISLE (#3602)
* aarch64: Migrate some bit-ops to ISLE

This commit migrates these instructions to ISLE:

* `bnot`
* `band`
* `bor`
* `bxor`
* `band_not`
* `bor_not`
* `bxor_not`

The translations were relatively straightforward but the interesting
part here was trying to reduce the duplication between all these
instructions. I opted for a route that's similar to what the lowering
does today, having a `decl` which takes the `ALUOp` and then performs
further pattern matching internally. This enabled each instruction's
lowering to be pretty simple while we still get to handle all the fancy
cases of shifts, constants, etc, for each instruction.

* Actually delete previous lowerings

* Remove dead code
2021-12-15 10:41:36 -06:00
Alex Crichton
d89410ec4e aarch64: Migrate uextend/sextend to ISLE
This commit migrates the sign/zero extension instructions from
`lower_inst.rs` to ISLE. There's actually a fair amount going on in this
migration since a few other pieces needed touching up along the way as
well:

* First is the actual migration of `uextend` and `sextend`. These
  instructions are relatively simple but end up having a number of special
  cases. I've attempted to replicate all the cases here but
  double-checks would be good.

* This commit actually fixes a few issues where if the result of a vector
  extraction is sign/zero-extended into i128 that actually results in
  panics in the current backend.

* This commit adds exhaustive testing for
  extension-of-a-vector-extraction is a noop wrt extraction.

* A bugfix around ISLE glue was required to get this commit working,
  notably the case where the `RegMapper` implementation was trying to
  map an input to an output (meaning ISLE was passing through an input
  unmodified to the output) wasn't working. This requires a `mov`
  instruction to be generated and this commit updates the glue to do
  this. At the same time this commit updates the ISLE glue to share more
  infrastructure between x64 and aarch64 so both backends get this fix
  instead of just aarch64.

Overall I think that the translation to ISLE was a net benefit for these
instructions. It's relatively obvious what all the cases are now unlike
before where it took a few reads of the code and some boolean switches
to figure out which path was taken for each flavor of input. I think
there's still possible improvements here where, for example, the
`put_in_reg_{s,z}ext64` helper doesn't use this logic so technically
those helpers could also pattern match the "well atomic loads and vector
extractions automatically do this for us" but that's a possible future
improvement for later (and shouldn't be too too hard with some ISLE
refactoring).
2021-12-14 07:01:37 -08:00
Alex Crichton
20e090b114 aarch64: Migrate {s,u}{div,rem} to ISLE (#3572)
* aarch64: Migrate {s,u}{div,rem} to ISLE

This commit migrates four different instructions at once to ISLE:

* `sdiv`
* `udiv`
* `srem`
* `urem`

These all share similar codegen and center around the `div` instruction
to use internally. The main feature of these was to model the manual
traps since the `div` instruction doesn't trap on overflow, instead
requiring manual checks to adhere to the semantics of the instruction
itself.

While I was here I went ahead and implemented an optimization for these
instructions when the right-hand-side is a constant with a known value.
For `udiv`, `srem`, and `urem` if the right-hand-side is a nonzero
constant then the checks for traps can be skipped entirely. For `sdiv`
if the constant is not 0 and not -1 then additionally all checks can be
elided. Finally if the right-hand-side of `sdiv` is -1 the zero-check is
elided, but it still needs a check for `i64::MIN` on the left-hand-side
and currently there's a TODO where `-1` is still checked too.

* Rebasing and review conflicts
2021-12-13 17:27:11 -06:00
wasmtime-publish
c1c4c59670 Release Wasmtime 0.32.0 (#3589)
* Bump Wasmtime to 0.32.0

[automatically-tag-and-release-this-commit]

* Update release notes for 0.32.0

Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
Co-authored-by: Alex Crichton <alex@alexcrichton.com>
2021-12-13 13:47:30 -06:00
Andrew Brown
86611d3bbc isle: expand enums in ISLE (#3586)
* x64: expand FloatCC enum in ISLE
* isle: regenerate manifests
* isle: generate all enum fields in `clif.isle`

This expands the `gen_isle` function to write all of the immediate
`enum`s out explicitly in `clif.isle`. Non-`enum` immediates are still
`extern primitive`.

* Only compile `enum_values` with `rebuild-isle` feature
* Only compile `gen_enum_isle` with `rebuild-isle` feature
2021-12-12 18:31:42 -08:00
Nick Fitzgerald
da73952021 cranelift-codegen: port bnot lowering to ISLE in x64 2021-12-09 08:38:10 -08:00
Nick Fitzgerald
cded0989aa cranelift-codegen: Port lowering of {i,u}{max,min}` to ISLE for x64 2021-12-08 15:50:42 -08:00
Nick Fitzgerald
471c1e32a4 Consolidate XmmRmR-based instructions together 2021-12-08 15:37:24 -08:00
Nick Fitzgerald
bea0c0d886 Merge pull request #3585 from abrown/assert-tmp-dsts
x64: assert that temporary and destination registers match during renaming
2021-12-08 14:10:54 -08:00
Chris Fallin
7bc17fda39 Fix iadd_ifcout lowering in ISLE to return a register corresponding to the iflags.
This register is not initialized, but we protect against its being used
by never allowing an iflags/fflags-typed value to be used with
`put_value_in_regs`. All `iflags`/`fflags` usages should be handled by
pattern-matching: e.g., `trapif` explicitly matches an `iadd_ifcout`
input.

Eventually (#3249) we need to simplify this by removing
iflags/fflags-tyepd values and using bool flags instead,
pattern-matching to get the same efficient lowerings as today. For now,
this allows the ISLE assertions to pass.
2021-12-08 11:59:38 -08:00
Andrew Brown
acaa84068d aarch64: assert that temporary and destination registers match during renaming 2021-12-08 11:59:11 -08:00
Andrew Brown
594509b734 x64: assert that temporary and destination registers match during renaming 2021-12-08 11:58:45 -08:00
Nick Fitzgerald
6af8d2a292 Rename the isle crate to cranelift-isle
The `isle` crate name is already taken on crates.io :(
2021-12-07 14:56:26 -08:00
Nick Fitzgerald
7e80c061f2 cranelift-codegen: depend on an exact version of isle
This should (hopefully) fix our publish script.
2021-12-07 14:23:41 -08:00
Pat Hickey
cf03b2a513 cranelift codegen & filetests: silence new dead code warnings in rust 1.57 2021-12-03 10:33:09 -08:00
Alex Crichton
0e90d4b903 Update addr2line and gimli deps (#3580)
Just a routine update, figured it was good to stay close to their most
recent versions
2021-12-01 15:48:36 -06:00
Benjamin Bouvier
b34788ae8a Make miette optional in cranelift-codegen, as it's only used when rebuilding isle 2021-12-01 11:24:59 +01:00
Nick Fitzgerald
0580c84405 Merge pull request #3570 from alexcrichton/isle-3-umulhi
aarch64: Migrate `{s,u}mulhi` to ISLE
2021-11-30 09:48:47 -08:00
Chris Fallin
952ef031af Merge pull request #2953 from scottmcm/add-memcmp
Cranelift: Add `LibCall::Memcmp`
2021-11-29 18:36:12 -08:00
Alex Crichton
25b380d5fc aarch64: Migrate {s,u}mulhi to ISLE
This starts moving over some sign/zero-extend helpers also present in
lowering in Rust. Otherwise this is a relatively unsurprising transition
with the various cases of the instructions mapping well to ISLE
utilities.
2021-11-29 18:11:42 -08:00
Scott McMurray
ca7c54b5f8 Add Type::int_with_byte_size constructor 2021-11-29 16:53:54 -08:00
Alex Crichton
33dba07e6b aarch64: Migrate imul to ISLE
This commit migrates the `imul` clif instruction lowering for AArch64 to
ISLE. This is a relatively complicated instruction with lots of special
cases due to the simd proposal for wasm. Like x64, however, the special
casing lends itself to ISLE quite well and the lowerings here in theory
are pretty straightforward.

The main gotcha of this commit is that this encounters a unique
situation which hasn't been encountered yet with other lowerings, namely
the `Umlal32` instruction used in the implementation of `i64x2.mul` is
unique in the `VecRRRLongOp` class of instructions in that it both reads
and writes the destination register (`use_mod` instead of simply
`use_def`). This meant that I needed to add another helper in ISLe for
creating a `vec_rrrr_long` instruction (despite this enum variant not
actually existing) which implicitly moves the first operand into the
destination before issuing the actual `VecRRRLong` instruction.
2021-11-29 16:05:57 -08:00
Alex Crichton
fa63e7de5a aarch64: Migrate ineg to ISLE
Needed a new `vec_misc` instruction construction helper but otherwise a
pretty straightforward translation.
2021-11-29 08:03:17 -08:00
Scott McMurray
c266f7f4c3 Cranelift: Add LibCall::Memcmp
The comment says the enum is "likely to grow" and the function's been in libc since C89, so hopefully this is ok.

I'd like to use it for emitting things like array equality.
2021-11-29 01:42:59 -08:00
Chris Fallin
d1e9a7840e Merge pull request #3561 from cfallin/aarch64-isle-rule-explicit-ordering
Update aarch64 backend's ISLE code to be rule-ordering-independent.
2021-11-24 11:57:52 -08:00
Chris Fallin
bc0de464bc Update aarch64 backend's ISLE code to be rule-ordering-independent.
In [this
comment](https://github.com/bytecodealliance/wasmtime/pull/3545#discussion_r756284757)
I noted a potential subtle issue with the way that a few rules were
written that is fine now but could cause some unexpected pain when we
get around to verification.

Specifically, a set of rules of the form

```
    (rule (A (B _)) (C))
    (rule (A _) (D))
```

should, under any reasonable "default" rule ordering scheme, fire the
more specific rule `(A (B _))` when applicable, in preference to the
second "fallback" rule.

However, for future verification-specific applications of ISLE, we want
to ensure the property that a rule's meaning/validity is not dependent
on being overridden by more specific rules. In other words, if a rule
specifies a rewrite, that rewrite should always be correct; and choosing
a more specific rule can give a *better* compilation (better generated
code) but should not be necessary for correctness.

This is an admittedly under-documented part of the language, though in the
pending #3560 I added a note about rule ordering being a heuristic that
should hopefully make this slightly clearer. Ultimately I want to have
tests that choose non-default rule orderings and differentially fuzz in
order to be sure that we're following this principle; and of course once
we're actually doing verification, we'll catch issues like this upfront.

Apologies for the subtle footgun here and hopefully the reasoning is
clear enough :-)
2021-11-24 11:08:47 -08:00
Benjamin Bouvier
9f6efe0e22 Bump regalloc in Cranelift (#3558)
This regalloc version contains a performance fix around creation of
very large logs that might be unused.
2021-11-23 09:09:31 -06:00
Nick Fitzgerald
21bce8071e Merge pull request #3554 from fitzgen/isle-iabs
ISLE: port `iabs` to ISLE for x64
2021-11-19 12:09:22 -08:00
Andrew Brown
994fe41daf x64: allow vector types in select move
As reported in #3173, the `select` instruction fails an assertion when it is given `v128` types as operands. This change relaxes the assertion to allow the same type of XMM move that occurs for the f32 and f64 types. This fixes #3173 in the old `lower.rs` code temporarily until the relatively complex `select` lowering can be ported to ISLE.
2021-11-19 11:24:30 -08:00
Nick Fitzgerald
94e0de45ed ISLE: port iabs to ISLE for x64 2021-11-19 11:03:44 -08:00
Alex Crichton
ef8ea644f4 aarch64: Migrate {s,u}{sub,add}_sat to ISLE (#3551)
These were pretty straightforward! Only needed a single `rule` per
instruction with a new 128-bit vector type matcher.
2021-11-19 12:59:06 -06:00
Alex Crichton
cbf539abb8 Use with_flags for 128-bith arith in aarch64
Also move the `with_flags` bits and pieces to `prelude.isle` so it can
be shared between backends if necessary.
2021-11-19 07:08:08 -08:00
Alex Crichton
98ce029bbd Add commutative addition cases 2021-11-19 07:00:04 -08:00
Alex Crichton
7412461b7b Spelling 2021-11-19 06:53:31 -08:00
Alex Crichton
15d2542939 Rebuild ISLE 2021-11-19 06:52:01 -08:00
Alex Crichton
7d0f6ab90f aarch64: Migrate iadd and isub to ISLE
This commit is the first "meaty" instruction added to ISLE for the
AArch64 backend. I chose to pick the first two in the current lowering's
`match` statement, `isub` and `iadd`. These two turned out to be
particularly interesting for a few reasons:

* Both had clearly migratable-to-ISLE behavior along the lines of
  special-casing per type. For example 128-bit and vector arithmetic
  were both easily translateable.

* The `iadd` instruction has special cases for fusing with a
  multiplication to generate `madd` which is expressed pretty easily in
  ISLE.

* Otherwise both instructions had a number of forms where they attempted
  to interpret the RHS as various forms of constants, extends, or
  shifts. There's a bit of a design space of how best to represent this
  in ISLE and what I settled on was to have a special case for each form
  of instruction, and the special cases are somewhat duplicated between
  `iadd` and `isub`. There's custom "extractors" for the special cases
  and instructions that support these special cases will have an
  `rule`-per-case.

Overall I think the ISLE transitioned pretty well. I don't think that
the aarch64 backend is going to follow the x64 backend super closely,
though. For example the x64 backend is having a helper-per-instruction
at the moment but with AArch64 it seems to make more sense to only have
a helper-per-enum-variant-of-`MInst`. This is because the same
instruction (e.g. `ALUOp::Sub32`) can be expressed with multiple
different forms depending on the payload.

It's worth noting that the ISLE looks like it's a good deal larger than
the code actually being removed from lowering as part of this commit. I
think this is deceptive though because a lot of the logic in
`put_input_in_rse_imm12_maybe_negated` and `alu_inst_imm12` is being
inlined into the ISLE definitions for each instruction instead of having
it all packed into the helper functions. Some of the "boilerplate" here
is the addition of various ISLE utilities as well.
2021-11-19 06:51:38 -08:00
Alex Crichton
352ee2b186 Move insertlane to ISLE (#3544)
This also fixes a bug where `movsd` was incorrectly used with a memory
operand for `insertlane`, causing it to actually zero the upper bits
instead of preserving them.

Note that the insertlane logic still exists in `lower.rs` because it's
used as a helper for a few other instruction lowerings which aren't
migrated to ISLE yet. This commit also adds a helper in ISLE itself for
those other lowerings to use when they get implemented.

Closes #3216
2021-11-18 13:48:11 -06:00
bjorn3
4c75616a7c Remove unused constants from cranelift-codegen-shared (#3479) 2021-11-18 18:51:35 +01:00
Alex Crichton
1141169ff8 aarch64: Initial work to transition backend to ISLE (#3541)
* aarch64: Initial work to transition backend to ISLE

This commit is what is hoped to be the initial commit towards migrating
the aarch64 backend to ISLE. There's seemingly a lot of changes here but
it's intended to largely be code motion. The current thinking is to
closely follow the x64 backend for how all this is handled and
organized.

Major changes in this PR are:

* The `Inst` enum is now defined in ISLE. This avoids having to define
  it in two places (once in Rust and once in ISLE). I've preserved all
  the comments in the ISLE and otherwise this isn't actually a
  functional change from the Rust perspective, it's still the same enum
  according to Rust.

* Lots of little enums and things were moved to ISLE as well. As with
  `Inst` their definitions didn't change, only where they're defined.
  This will give future ISLE PRs access to all these operations.

* Initial code for lowering `iconst`, `null`, and `bconst` are
  implemented. Ironically none of this is actually used right now
  because constant lowering is handled in `put_input_in_regs` which
  specially handles constants. Nonetheless I wanted to get at least
  something simple working which shows off how to special case various
  things that are specific to AArch64. In a future PR I plan to hook up
  const-lowering in ISLE to this path so even though
  `iconst`-the-clif-instruction is never lowered this should use the
  const lowering defined in ISLE rather than elsewhere in the backend
  (eventually leading to the deletion of the non-ISLE lowering).

* The `IsleContext` skeleton is created and set up for future additions.

* Some code for ISLE that's shared across all backends now lives in
  `isle_prelude_methods!()` and is deduplicated between the AArch64
  backend and the x64 backend.

* Register mapping is tweaked to do the same thing for AArch64 that it
  does for x64. Namely mapping virtual registers is supported instead of
  just virtual to machine registers.

My main goal with this PR was to get AArch64 into a place where new
instructions can be added with relative ease. Additionally I'm hoping to
figure out as part of this change how much to share for ISLE between
AArch64 and x64 (and other backends).

* Don't use priorities with rules

* Update .gitattributes with concise syntax

* Deduplicate some type definitions

* Rebuild ISLE

* Move isa::isle to machinst::isle
2021-11-18 10:38:16 -06:00
Nick Fitzgerald
d2d0a0f36b Remove Peepmatic!!!
Peepmatic was an early attempt at a DSL for peephole optimizations, with the
idea that maybe sometime in the future we could user it for instruction
selection as well. It didn't really pan out, however:

* Peepmatic wasn't quite flexible enough, and adding new operators or snippets
  of code implemented externally in Rust was a bit of a pain.

* The performance was never competitive with the hand-written peephole
  optimizers. It was *very* size efficient, but that came at the cost of
  run-time efficiency. Everything was table-based and interpreted, rather than
  generating any Rust code.

Ultimately, because of these reasons, we never turned Peepmatic on by default.

These days, we just landed the ISLE domain-specific language, and it is better
suited than Peepmatic for all the things that Peepmatic was originally designed
to do. It is more flexible and easy to integrate with external Rust code. It is
has better time efficiency, meeting or even beating hand-written code. I think a
small part of the reason why ISLE excels in these things is because its design
was informed by Peepmatic's failures. I still plan on continuing Peepmatic's
mission to make Cranelift's peephole optimizer passes generated from DSL rewrite
rules, but using ISLE instead of Peepmatic.

Thank you Peepmatic, rest in peace!
2021-11-17 13:04:17 -08:00
Chris Fallin
dba74024aa Merge pull request #3534 from cfallin/isle-generated-code-manifest
ISLE: guard against stale generated source in default build config.
2021-11-16 15:59:52 -08:00
Chris Fallin
1697e32afa Let's try canonicalizing file paths in the manifest too... 2021-11-16 15:22:43 -08:00