Commit Graph

2203 Commits

Author SHA1 Message Date
Chris Fallin
51f9ac2150 Merge pull request #1741 from cfallin/filetest-vcode-compile
Merge `vcode` filetest mode into `compile`.
2020-05-22 18:57:21 -07:00
Chris Fallin
48573b52b2 Merge vcode filetest mode into compile.
I hadn't realized before that the filetest backend for `test vcode` is
doing essentially what `compile` is doing, but for new (`MachInst`)
backends: it is just getting a disassembly and running it through
filecheck. There's no reason not to reuse `test compile` for the AArch64
tests as well.

This was motivated by the desire to have "this IR compiles successfully"
tests work on both x86 and AArch64. It seems this should work fine by
adding multiple `target` directives when a test case should be
compile-tested on multiple architectures.
2020-05-22 17:28:48 -07:00
Chris Fallin
73537e72c0 Merge pull request #1732 from jgouly/copysign-fpu
arm64: Use FPU instrctions for Fcopysign
2020-05-22 17:25:33 -07:00
Peter Huene
f36539130b Merge pull request #1734 from peterhuene/fix-saved-fprs
Cranelift: Fix FPR saving and shadow space allocation for Windows x64.
2020-05-22 12:06:37 -07:00
whitequark
b2e8ed4dc9 cranelift: add i64.[us]{div,rem} libcalls.
These libcalls are useful for 32-bit platforms.
2020-05-22 11:41:56 +00:00
Peter Huene
ce5f3e153b Only update XMM save unwind operation offsets when using a FP.
This commit prevents updating the XMM save unwind operation offsets when a
frame pointer is not used, even though currently Cranelift always uses a
frame pointer.

This will prevent incorrect unwind information in the future when we start
omitting frame pointers.
2020-05-21 16:46:30 -07:00
Peter Huene
2cd5ed1880 Address code review feedback. 2020-05-21 15:57:11 -07:00
Joey Gouly
02c3f238f8 arm64: Use FPU instrctions for Fcopysign
Copyright (c) 2020, Arm Limited.
2020-05-21 18:14:12 +01:00
Peter Huene
78c3091e84 Fix FPR saving and shadow space allocation for Windows x64.
This commit fixes both how FPR callee-saved registers are saved and how the
shadow space allocation occurs when laying out the stack for Windows x64
calling convention.

Importantly, this commit removes the compiler limitation of stack size for
Windows x64 that was imposed because FPR saves previously couldn't always be
represented in the unwind information.

The FPR saves are now performed without using stack slots, much like how the
callee-saved GPRs are saved. The total CSR space is given to `layout_stack` so
that it is included in the frame size and to offset the layout of spills and
explicit slots.

The FPR saves are now done via an RSP offset (post adjustment) and they always
follow the GPR saves on the stack. A simpler calculation can now be made to
determine the proper offsets of the FPR saves for representing the unwind
information.

Additionally, the shadow space is no longer treated as an incoming argument,
but an explicit stack slot that gets laid out at the lowest address possible in
the local frame. This prevents `layout_stack` from putting a spill or explicit
slot in this reserved space. In the future, `layout_stack` should take
advantage of the *caller-provided* shadow space for spills, but this commit does
not attempt to address that.

The shadow space is now omitted from the local frame for leaf functions.

Fixes #1728.
Fixes #1587.
Fixes #1475.
2020-05-20 15:37:30 -07:00
Chris Fallin
c9e3b71c39 Merge pull request #1729 from cfallin/machinst-branch-opt
Fix MachBuffer branch optimization.
2020-05-20 14:43:57 -07:00
Chris Fallin
13e12908a6 MachBuffer branch opts: comments approximating a semi-formal correctness proof. 2020-05-20 14:12:19 -07:00
Chris Fallin
80ab154d04 Update from review comments. 2020-05-20 12:35:36 -07:00
Benjamin Bouvier
1f620e1b46 cranelift: bump regalloc.rs to 0.0.24 and adapt to latest API changes; 2020-05-20 15:37:15 +02:00
Chris Fallin
e11094b28b Fix MachBuffer branch optimization.
This patch fixes a subtle bug that occurred in the MachBuffer branch
optimization: in tracking labels at the current buffer tail using a
sorted-by-offset array, the code did not update this array properly when
redirecting labels. As a result, the dead-branch removal was unsafe,
because not every label pointing to a branch is guaranteed to be
redirected properly first.

Discovered while doing performance testing: bz2 silently took a wrong
branch and exited compression early. (Eek!)

To address this problem, this patch adopts a slightly simpler data
structure: we only track the labels *at the current buffer tail*, and
*at the start of each branch*, and we're careful to update these
appropriately to maintain the invariants. I'm pretty confident that this
is correct now, but we should (still) fuzz it a bunch, because wrong
control flow scares me a nonzero amount. I should probably also actually
write out a formal proof that these data-structure updates are correct.
The optimizations are important for performance (removing useless empty
blocks, and taking advantage of any fallthrough opportunities at all),
so I don't think we would want to drop them entirely.
2020-05-19 18:09:18 -07:00
Nick Fitzgerald
9d2100e54a Limit the size of automaton keys in the peepmatic_simple_automata fuzz target
Fixes https://oss-fuzz.com/testcase-detail/5742905129172992
2020-05-19 09:12:50 -07:00
Chris Fallin
d8d6fbe58c Merge pull request #1718 from cfallin/machinst-codebuffer
Rework of MachInst isel, branch fixups and lowering, and block ordering.
2020-05-19 07:17:22 -07:00
Nick Fitzgerald
28d6df0db6 Limit the size of automaton keys in the peepmatic_fst_diff fuzz target (#1724)
This should avoid timeouts caused by large keys.

Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22251
2020-05-18 21:27:00 -05:00
Chris Fallin
bdd2873c8c Address review comments. 2020-05-18 16:25:26 -07:00
Chris Fallin
687aca00fe Update x64 backend to use new lowering APIs. 2020-05-18 16:25:15 -07:00
Chris Fallin
72e6be9342 Rework of MachInst isel, branch fixups and lowering, and block ordering.
This patch includes:

- A complete rework of the way that CLIF blocks and edge blocks are
  lowered into VCode blocks. The new mechanism in `BlockLoweringOrder`
  computes RPO over the CFG, but with a twist: it merges edge blocks intto
  heads or tails of original CLIF blocks wherever possible, and it does
  this without ever actually materializing the full nodes-plus-edges
  graph first. The backend driver lowers blocks in final order so
  there's no need to reshuffle later.

- A new `MachBuffer` that replaces the `MachSection`. This is a special
  version of a code-sink that is far more than a humble `Vec<u8>`. In
  particular, it keeps a record of label definitions and label uses,
  with a machine-pluggable `LabelUse` trait that defines various types
  of fixups (basically internal relocations).

  Importantly, it implements some simple peephole-style branch rewrites
  *inline in the emission pass*, without any separate traversals over
  the code to use fallthroughs, swap taken/not-taken arms, etc. It
  tracks branches at the tail of the buffer and can (i) remove blocks
  that are just unconditional branches (by redirecting the label), (ii)
  understand a conditional/unconditional pair and swap the conditional
  polarity when it's helpful; and (iii) remove branches that branch to
  the fallthrough PC.

  The `MachBuffer` also implements branch-island support. On
  architectures like AArch64, this is needed to allow conditional
  branches within plausibly-attainable ranges (+/- 1MB on AArch64
  specifically). It also does this inline while streaming through the
  emission, without any sort of fixpoint algorithm or later moving of
  code, by simply tracking outstanding references and "deadlines" and
  emitting an island just-in-time when we're in danger of going out of
  range.

- A rework of the instruction selector driver. This is largely following
  the same algorithm as before, but is cleaned up significantly, in
  particular in the API: the machine backend can ask for an input arg
  and get any of three forms (constant, register, producing
  instruction), indicating it needs the register or can merge the
  constant or producing instruction as appropriate. This new driver
  takes special care to emit constants right at use-sites (and at phi
  inputs), minimizing their live-ranges, and also special-cases the
  "pinned register" to avoid superfluous moves.

Overall, on `bz2.wasm`, the results are:

    wasmtime full run (compile + runtime) of bz2:

    baseline:   9774M insns, 9742M cycles, 3.918s
    w/ changes: 7012M insns, 6888M cycles, 2.958s  (24.5% faster, 28.3% fewer insns)

    clif-util wasm compile bz2:

    baseline:   2633M insns, 3278M cycles, 1.034s
    w/ changes: 2366M insns, 2920M cycles, 0.923s  (10.7% faster, 10.1% fewer insns)

    All numbers are averages of two runs on an Ampere eMAG.
2020-05-16 23:08:22 -07:00
Y-Nak
0393d101b1 Fix typo in peepmatic (#1712) 2020-05-15 09:47:16 -05:00
Nick Fitzgerald
01f46d0238 Merge pull request #1692 from fitzgen/update-to-wasmparser-0.55.0
Update to using `wasmparser` 0.55.0
2020-05-14 14:00:24 -07:00
Chris Fallin
df4028749e Merge pull request #1699 from jgouly/inst-size
Reduce arm64 Inst enum size
2020-05-14 13:44:46 -07:00
Nick Fitzgerald
1a4f3fb2df Update deps and tests for anyref --> externref
* Update to using `wasmparser` 0.55.0
* Update wasmprinter to 0.2.5
* Update `wat` to 1.0.18, and `wast` to 17.0.0
2020-05-14 12:47:37 -07:00
Nick Fitzgerald
3c0b64fef7 Merge pull request #1710 from fitzgen/remove-unused-lhs-member
peepmatic: remove unused member from `PeepholeOptimizer`
2020-05-14 12:03:31 -07:00
Nick Fitzgerald
e9ef8ea3d5 peepmatic: remove unused member from PeepholeOptimizer
This is dead code, left over from an earlier design.
2020-05-14 11:08:59 -07:00
Nick Fitzgerald
fb7a690efc Merge pull request #1687 from fitzgen/sign-extend-immediates
cranelift: Sign extend `Imm64` immediates
2020-05-14 10:09:53 -07:00
Nick Fitzgerald
c093dee79e cranelift: Let lifetime elision elide lifetimes 2020-05-14 07:52:23 -07:00
Nick Fitzgerald
923a73be7b deps: Bump z3 to 0.5.1
This fixes Windows builds.
2020-05-14 07:52:23 -07:00
Nick Fitzgerald
8d7ed0fd13 deps: Update wast to 15.0.0
This also updates `wat` in the lockfile so that the SIMD spec tests are passing
again.
2020-05-14 07:52:23 -07:00
Nick Fitzgerald
22a070ed4f peepmatic: Apply some review suggestions from @bjorn3 2020-05-14 07:52:23 -07:00
Nick Fitzgerald
fd4f08e75f peepmatic: rustfmt 2020-05-14 07:52:23 -07:00
Nick Fitzgerald
52c6ece5f3 peepmatic: Make peepmatic optional to enable
Rather than outright replacing parts of our existing peephole optimizations
passes, this makes peepmatic an optional cargo feature that can be enabled. This
allows us to take a conservative approach with enabling peepmatic everywhere,
while also allowing us to get it in-tree and make it easier to collaborate on
improving it quickly.
2020-05-14 07:52:23 -07:00
Nick Fitzgerald
6e135b3aea peepmatic: Fix a failed assertion due to extra iterations after fixed point
After replacing an instruction with an alias to an earlier value, trying to
further optimize that value is unnecessary, since we've already processed it,
and also was triggering an assertion.
2020-05-14 07:52:23 -07:00
Nick Fitzgerald
eb2dab0aa4 peepmatic: Save RHS actions as a boxed slice, not vec
A boxed slice is only two words, while a vec is three words. This should cut
down on the memory size of our automata and improve cache usage.
2020-05-14 07:52:23 -07:00
Nick Fitzgerald
210b036320 peepmatic: Represent various id types with u16
These ids end up in the automaton, so making them smaller should give us better
data cache locality and also smaller serialized sizes.
2020-05-14 07:52:23 -07:00
Nick Fitzgerald
469104c4d3 peepmatic: Make the results of match operations a smaller and more cache friendly 2020-05-14 07:52:23 -07:00
Nick Fitzgerald
9a1f8038b7 peepmatic: Do not transplant instructions whose results are potentially used elsewhere 2020-05-14 07:52:23 -07:00
Nick Fitzgerald
090d1c2d32 cranelift: Port most of simple_preopt.rs over to the peepmatic DSL
This ports all of the identity, no-op, simplification, and canonicalization
related optimizations over from being hand-coded to the `peepmatic` DSL. This
does not handle the branch-to-branch optimizations or most of the
divide-by-constant optimizations.
2020-05-14 07:52:23 -07:00
Nick Fitzgerald
1a7670f964 peepmatic: Introduce the peepmatic-fuzzing crate
This crate contains oracles, generators, and fuzz targets for use with fuzzing
engines (e.g. libFuzzer). This doesn't contain the actual
`libfuzzer_sys::fuzz_target!` definitions (those are in the `peepmatic-fuzz`
crate) but does those definitions are one liners calling out to functions
defined in this crate.
2020-05-14 07:50:58 -07:00
Nick Fitzgerald
2828da1f56 peepmatic: Introduce the peepmatic-test crate
This crate provides testing utilities for `peepmatic`, and a test-only
instruction set we can use to check that various optimizations do or don't
apply.
2020-05-14 07:50:58 -07:00
Nick Fitzgerald
de9fc63009 peepmatic: Introduce the main peepmatic crate
Peepmatic is a DSL for peephole optimizations and compiler for generating
peephole optimizers from them. The user writes a set of optimizations in the
DSL, and then `peepmatic` compiles the set of optimizations into an efficient
peephole optimizer:

```
DSL ----peepmatic----> Peephole Optimizer
```

The generated peephole optimizer has all of its optimizations' left-hand sides
collapsed into a compact automata that makes matching candidate instruction
sequences fast.

The DSL's optimizations may be written by hand or discovered mechanically with a
superoptimizer like [Souper][]. Eventually, `peepmatic` should have a verifier
that ensures that the DSL's optimizations are sound, similar to what [Alive][]
does for LLVM optimizations.

[Souper]: https://github.com/google/souper
[Alive]: https://github.com/AliveToolkit/alive2
2020-05-14 07:50:58 -07:00
Nick Fitzgerald
197a9e88cb peepmatic: Introduce the peepmatic-runtime crate
The `peepmatic-runtime` crate contains everything required to use a
`peepmatic`-generated peephole optimizer.

In short: build times and code size.

If you are just using a peephole optimizer, you shouldn't need the functions
to construct it from scratch from the DSL (and the implied code size and
compilation time), let alone even build it at all. You should just
deserialize an already-built peephole optimizer, and then use it.

That's all that is contained here in this crate.
2020-05-14 07:50:58 -07:00
Nick Fitzgerald
0f03a97475 peepmatic: Introduce the peepmatic-macro crate
This crate provides the derive macros used by `peepmatic`, notable AST-related
derives that enumerate child AST nodes, and operator-related derives that
provide helpers for type checking.
2020-05-14 07:50:58 -07:00
Nick Fitzgerald
c82326a1ae peepmatic: Introduce the peepmatic-automata crate
The `peepmatic-automata` crate builds and queries finite-state transducer
automata.

A transducer is a type of automata that has not only an input that it
accepts or rejects, but also an output. While regular automata check whether
an input string is in the set that the automata accepts, a transducer maps
the input strings to values. A regular automata is sort of a compressed,
immutable set, and a transducer is sort of a compressed, immutable key-value
dictionary. A [trie] compresses a set of strings or map from a string to a
value by sharing prefixes of the input string. Automata and transducers can
compress even better: they can share both prefixes and suffixes. [*Index
1,600,000,000 Keys with Automata and Rust* by Andrew Gallant (aka
burntsushi)][burntsushi-blog-post] is a top-notch introduction.

If you're looking for a general-purpose transducers crate in Rust you're
probably looking for [the `fst` crate][fst-crate]. While this implementation
is fully generic and has no dependencies, its feature set is specific to
`peepmatic`'s needs:

* We need to associate extra data with each state: the match operation to
  evaluate next.

* We can't provide the full input string up front, so this crate must
  support incremental lookups. This is because the peephole optimizer is
  computing the input string incrementally and dynamically: it looks at the
  current state's match operation, evaluates it, and then uses the result as
  the next character of the input string.

* We also support incremental insertion and output when building the
  transducer. This is necessary because we don't want to emit output values
  that bind a match on an optimization's left-hand side's pattern (for
  example) until after we've succeeded in matching it, which might not
  happen until we've reached the n^th state.

* We need to support generic output values. The `fst` crate only supports
  `u64` outputs, while we need to build up an optimization's right-hand side
  instructions.

This implementation is based on [*Direct Construction of Minimal Acyclic
Subsequential Transducers* by Mihov and Maurel][paper]. That means that keys
must be inserted in lexicographic order during construction.

[trie]: https://en.wikipedia.org/wiki/Trie
[burntsushi-blog-post]: https://blog.burntsushi.net/transducers/#ordered-maps
[fst-crate]: https://crates.io/crates/fst
[paper]: http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.24.3698&rep=rep1&type=pdf
2020-05-14 07:50:58 -07:00
Joey Gouly
f418b7a700 Reduce arm64 Inst enum size
This reduces the size of the Inst enum from 112 bytes to 48 bytes.

Using DHAT on a regex-rs.wasm benchmark, `valgrind --tool=dhat clif-util compile --target aarch64`

The total number of allocated bytes, drops by around 170 MB.
At t-gmax drops by 3 MB.

Using `perf stat clif-util compile --target aarch64`, the instructions count dropped by 0.6%. Cache misses dropped by 6%. Cycles dropped by 2.3%.
2020-05-14 15:45:55 +01:00
Ömer Sinan Ağacan
0592b5a995 Fix umbrella crate URL in docs/index.md (#1694) 2020-05-13 17:05:55 -07:00
Dan Gohman
fb0b9e3ae6 Change proc_exit to unwind the stack rather than exiting the host process. (#1646)
* Remove Cranelift's OutOfBounds trap, which is no longer used.

* Change proc_exit to unwind instead of exit the host process.

This implements the semantics in https://github.com/WebAssembly/WASI/pull/235.

Fixes #783.
Fixes #993.

* Fix exit-status tests on Windows.

* Revert the wiggle changes and re-introduce the wasi-common implementations.

* Move `wasi_proc_exit` into the wasmtime-wasi crate.

* Revert the spec_testsuite change.

* Remove the old proc_exit implementations.

* Make `TrapReason` an implementation detail.

* Allow exit status 2 on Windows too.

* Fix a documentation link.

* Really fix a documentation link.
2020-05-13 15:59:43 -07:00
Cerberuser
f5eab5225f Fixed links in compare-llvm.md (#1690)
Several links were broken by line-breaks between the link caption and
the link itself. This commit fixes them by moving each on its own line.

Co-authored-by: k.bagrov <k.bagrov@g.nsu.ru>
2020-05-13 11:52:36 +02:00
Benjamin Bouvier
5987cf5cda machinst: add a linear-scan checked variant too; 2020-05-13 10:56:32 +02:00