Commit Graph

163 Commits

Author SHA1 Message Date
Jamey Sharp
3b76874834 cranelift-isle: Fix representation for overlap checks (#5337)
Ulrich Weigand identified two bugs in this code due to it falsely
claiming there were unreachable rules in the s390x backend. The fixes
are:

- Add constraints for pure constructors.

I didn't notice that a constructor which is declared pure (which
currently implies that it is fallible), when used on the left-hand side
of a rule, can cause the rule to fail to match. Therefore, any
constructors on the left-hand side must be noted as additional
constraints on the rule, so that overlap checking can see them.

- Ignore subset-overlaps for rules with equality constraints

This eliminates false positives when checking for unreachable rules. It
introduces false negatives instead but we prefer to fail to detect an
error instead of claiming that valid input is wrong. We can implement a
more accurate check later.
2022-11-29 11:02:12 -08:00
Jamey Sharp
ff5abfd993 cranelift-isle: Minor error-handling cleanups (#5338)
- Remove remaining references to Miette
- Borrow implementation of `line_starts` from codespan-reporting
- Clean up a use of `Result` that no longer conflicts with a local
  definition
- When printing plain errors, add a blank line between errors for
  readability
2022-11-29 03:07:05 +00:00
Jamey Sharp
044b57f334 cranelift-isle: Rewrite error reporting (#5318)
There were several issues with ISLE's existing error reporting
implementation.

- When using Miette for more readable error reports, it would panic if
  errors were reported from multiple files in the same run.
- Miette is pretty heavy-weight for what we're doing, with a lot of
  dependencies.
- The `Error::Errors` enum variant led to normalization steps in many
  places, to avoid using that variant to represent a single error.

This commit:
- replaces Miette with codespan-reporting
- gets rid of a bunch of cargo-vet exemptions
- replaces the `Error::Errors` variant with a new `Errors` type
- removes source info from `Error` variants so they're easy to construct
- adds source info only when formatting `Errors`
- formats `Errors` with a custom `Debug` impl
- shares common code between ISLE's callers, islec and cranelift-codegen
- includes a source snippet even with fancy-errors disabled

I tried to make this a series of smaller commits but I couldn't find any
good split points; everything was too entangled with everything else.
2022-11-23 14:20:48 -08:00
Jamey Sharp
54207d343e cranelift-isle: Specialize for Term at rule root (#5295)
In #5174 we decided it doesn't make sense for a rule to have a
bind-pattern at the root of its left-hand side. There's no Rust value
corresponding to the root value of such a term, because it actually
represents a function declaration with one or more arguments.

This commit takes that to its logical conclusion.

`sema::Rule` previously had an `lhs` field whose value must always be a
`Pattern::Term` variant, and anyone using that structure had to deal
with the possibility of finding the wrong variant there.

Now the relevant fields from that variant are stored directly in `Rule`
instead. Also, the (tiny!) portion of `translate_pattern` which applied
when the pattern was the root term is now inlined in `collect_rules`.

Because `translate_pattern` no longer has to special-case the root term,
we can delete its `rule_term` and `is_root` arguments. That brings it
down to a more manageable four arguments, which means many calls fit on
one line now.
2022-11-18 11:21:08 -08:00
Jamey Sharp
9a44ef7443 cranelift-isle: Unify expressions and bindings (#5294)
As it turns out, that distinction was not necessary for this
representation. Removing it eliminates some complexity around wrapping
expressions as bindings and vice versa. It also clears up some confusion
about which category to put certain constructs in (arguments and
extractors) by refusing to have different categories.

While I was writing this patch I also realized that `add_match_variant`
and `normalize_equivalence_classes` both need to do fundamentally the
same things with enum variants, so I refactored them to share code and
make their relationship clearer.

Finally, I reviewed all the comments in this file and fixed some places
where they could be more clear.
2022-11-17 16:00:59 -08:00
Jamey Sharp
70c72ee2a4 cranelift-isle: New IR and revised overlap checks (#5195)
* cranelift-isle: New IR and revised overlap checks

* Improve error reporting

* Avoid "unused argument" warnings a nicer way

* Remove unused fields

* Minimize diff and "fix" error handling

I had tried to use Miette "right" and made things worse somehow. Among
other changes, revert all my changes to unrelated parts of `error.rs`
and `error_miette.rs`.

* Review comments: Rename "unmatchable" to "unreachable"

* Review comments: newtype wrappers, not type aliases

* Review comments: more comments on overlap checks

* Review comments: Clarify `normalize_equivalence_classes`

* Review comments: use union-find instead of linked list

This saves about 50 lines of code in the trie_again module. The
union-find implementation is about twice as long as that, counting
comments and doc-tests, but that's a worth-while tradeoff.

However, this makes `normalize_equivalence_classes` slower, because now
finding all elements of an equivalence class takes time linear in the
total size of all equivalence classes. If that ever turns out to be a
problem in practice we can find some way to optimize `remove_set_of`.

* Review comments: Hide constraints HashMap

We want to enforce that consumers of this representation can't observe
non-deterministic ordering in any of its public types.

* Review comments: Normalize equivalence classes incrementally

I'm not sure whether this is a good idea. It doesn't make the logic
particularly simpler, and I think it will do more work if three or more
binding sites with enum-variant constraints get set equal to each other.

* More comments and other clarifications

* Revert "Review comments: Normalize equivalence classes incrementally"

* Even more comments
2022-11-14 02:29:22 +00:00
Jamey Sharp
95ca72a37a cranelift-isle: Misc sema cleanups (#5242)
This mostly amounts to factoring out duplicated code and turning various
uses of `unwrap_or_continue!` into iterator chains.
2022-11-11 01:53:05 +00:00
Jamey Sharp
f0fccbd18a cranelift-isle: Helpers to get type/term by name (#5241)
This is a common pattern in sema, so factor it out.

Since this version uses `intern` instead of `intern_mut`, it might be a
tiny bit faster when errors occur due to not writing names into maps
then. When no error occurs, ISLE should do exactly the same work with or
without this commit.
2022-11-10 09:51:49 -08:00
Jamey Sharp
86679489ef cranelift-isle: if-let patterns aren't root terms (#5233)
The `is_root` flag to `translate_pattern` just determines whether the
`rule_term` argument is used, which begs a larger cleanup. But that
cleanup is less clear if `is_root` is set anywhere aside from the call
in `collect_rules`. So I wanted to get confirmation that this particular
use of that flag is incorrect first.

These two arguments (`is_root` and `rule_term`) are used to prevent
expansion of a term as an internal extractor ("macro") if:
- that term is also an internal constructor
- and it's the root term on the left-hand side of the current rule
- and the pattern we're currently translating has no parents.

I'm not sure what it should mean to use the term you're currently
defining as the root pattern on the left-hand side of an if-let in the
same rule, but I don't think it should have this particular special
treatment.
2022-11-09 15:32:33 -08:00
Jamey Sharp
54998715ea cranelift-isle: Save variable names for later use (#5221)
It's nice to be able to report these names after sema analysis completes
so rule authors can recognize which names they used.

This isn't used anywhere yet, but I'm planning to use it during codegen,
and the rule-verification folks wanted something like this for debugging
output.
2022-11-09 15:21:15 -08:00
Jamey Sharp
d38631a724 cranelift-isle: Don't panic on too-large rule priorities (#5236)
Found with ISLE's fuzzer.
2022-11-09 20:36:02 +00:00
Jamey Sharp
33a192556e cranelift-isle: Do fewer term lookups (#5232)
While checking the call graph of extractors during semantic validation,
save `TermId` instead of `Sym`. The types are both just integer indexes,
but the `TermId` is more useful here. Saving it avoids needing to check
for failed map lookups twice, which simplifies the implementation.
2022-11-09 11:24:38 -08:00
wasmtime-publish
08ef518c95 Bump Wasmtime to 4.0.0 (#5209)
Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
2022-11-06 13:32:34 -06:00
Jamey Sharp
2688b44915 cranelift-isle: Factor out rule/pattern/expr visitors (#5174)
This makes some rather tricky analysis available to other users besides
the current IR. It shouldn't change current behavior, except if a rule
attempts to bind its root term to a name. There's no Rust value for a
root term, so the existing code silently ignored such bindings and would
panic saying "Variable should already be bound" if a rule attempted to
use such bindings. With this commit, the initial attempt to bind the
name reports the error instead.
2022-11-03 01:18:49 +00:00
Saúl Cabrera
f6a8c81a47 isle: Fix grammar in README (#5184) 2022-11-03 00:48:32 +00:00
Jamey Sharp
033758daaf cranelift-isle: trie construction and IR cleanups (#5171)
One big change here is to stop using `Term::extractor_sig`, which was
the only call that used a `TypeEnv`. However that function only uses
type information to construct the fully-qualified name of the extractor,
which is not used when building the IR. So removing it and removing the
now-unused `typeenv` parameters removes all uses of `TypeEnv` from the
`ir` and `trie` modules.

In addition, this completes the changes started in "More consistent use
of `add_inst`" (e63771f2d9), by always
using `add_inst` to get an `InstId`.

I also removed a number of unnecessary intermediate allocations.
2022-11-01 17:17:11 -07:00
Jamey Sharp
e079195322 Simplify overlap checking after removing Rayon (#5131)
Now that we aren't trying to do overlap checking in parallel, we can
fuse the loop that generates a list of rule pairs with the loop that
checks those pairs.

Removing the intermediate vector of pairs should save a little time and
memory. But it also means we're no longer borrowing from the `by_term`
HashMap, so we can use `into_iter` instead of `values` to move ownership
out of the map. That in turn means that we can use `into_iter` on each
vector of rules as well, which turns out to offer a slightly nicer idiom
for looping over all pairs, and also means we drop allocations as soon
as possible.

I also pushed grouping by priority earlier, so the O(n^2) all-pairs loop
runs over smaller lists. If we later find we want to know about overlaps
across different priorities, the definition of the map key is an easy
place to make that change.
2022-10-26 19:49:08 +00:00
bjorn3
470070ab71 Remove rayon dependency of cranelift-isle (#5101)
Using rayon adds a lot of dependencies to Cranelift. The total
unparallelized time the code that uses rayon takes is less than half a
second and it runs at compile time, so there is pretty much no benefit
to parallelizing it.
2022-10-23 15:13:14 -07:00
Chris Fallin
2be12a5167 egraph-based midend: draw the rest of the owl (productionized). (#4953)
* egraph-based midend: draw the rest of the owl.

* Rename `egg` submodule of cranelift-codegen to `egraph`.

* Apply some feedback from @jsharp during code walkthrough.

* Remove recursion from find_best_node by doing a single pass.

Rather than recursively computing the lowest-cost node for a given
eclass and memoizing the answer at each eclass node, we can do a single
forward pass; because every eclass node refers only to earlier nodes,
this is sufficient. The behavior may slightly differ from the earlier
behavior because we cannot short-circuit costs to zero once a node is
elaborated; but in practice this should not matter.

* Make elaboration non-recursive.

Use an explicit stack instead (with `ElabStackEntry` entries,
alongside a result stack).

* Make elaboration traversal of the domtree non-recursive/stack-safe.

* Work analysis logic in Cranelift-side egraph glue into a general analysis framework in cranelift-egraph.

* Apply static recursion limit to rule application.

* Fix aarch64 wrt dynamic-vector support -- broken rebase.

* Topo-sort cranelift-egraph before cranelift-codegen in publish script, like the comment instructs me to!

* Fix multi-result call testcase.

* Include `cranelift-egraph` in `PUBLISHED_CRATES`.

* Fix atomic_rmw: not really a load.

* Remove now-unnecessary PartialOrd/Ord derivations.

* Address some code-review comments.

* Review feedback.

* Review feedback.

* No overlap in mid-end rules, because we are defining a multi-constructor.

* rustfmt

* Review feedback.

* Review feedback.

* Review feedback.

* Review feedback.

* Remove redundant `mut`.

* Add comment noting what rules can do.

* Review feedback.

* Clarify comment wording.

* Update `has_memory_fence_semantics`.

* Apply @jameysharp's improved loop-level computation.

Co-authored-by: Jamey Sharp <jamey@minilop.net>

* Fix suggestion commit.

* Fix off-by-one in new loop-nest analysis.

* Review feedback.

* Review feedback.

* Review feedback.

* Use `Default`, not `std::default::Default`, as per @fitzgen

Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>

* Apply @fitzgen's comment elaboration to a doc-comment.

Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>

* Add stat for hitting the rewrite-depth limit.

* Some code motion in split prelude to make the diff a little clearer wrt `main`.

* Take @jameysharp's suggested `try_into()` usage for blockparam indices.

Co-authored-by: Jamey Sharp <jamey@minilop.net>

* Take @jameysharp's suggestion to avoid double-match on load op.

Co-authored-by: Jamey Sharp <jamey@minilop.net>

* Fix suggestion (add import).

* Review feedback.

* Fix stack_load handling.

* Remove redundant can_store case.

* Take @jameysharp's suggested improvement to FuncEGraph::build() logic

Co-authored-by: Jamey Sharp <jamey@minilop.net>

* Tweaks to FuncEGraph::build() on top of suggestion.

* Take @jameysharp's suggested clarified condition

Co-authored-by: Jamey Sharp <jamey@minilop.net>

* Clean up after suggestion (unused variable).

* Fix loop analysis.

* loop level asserts

* Revert constant-space loop analysis -- edge cases were incorrect, so let's go with the simple thing for now.

* Take @jameysharp's suggestion re: result_tys

Co-authored-by: Jamey Sharp <jamey@minilop.net>

* Fix up after suggestion

* Take @jameysharp's suggestion to use fold rather than reduce

Co-authored-by: Jamey Sharp <jamey@minilop.net>

* Fixup after suggestion

* Take @jameysharp's suggestion to remove elaborate_eclass_use's return value.

* Clarifying comment in terminator insts.

Co-authored-by: Jamey Sharp <jamey@minilop.net>
Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
2022-10-11 18:15:53 -07:00
wasmtime-publish
a9be4a9b56 Bump Wasmtime to 3.0.0 (#5016)
Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
2022-10-05 09:30:55 -05:00
Trevor Elliott
e63771f2d9 More consistent use of add_inst (#5012)
Use the InstId returned by add_inst rather than creating it eagerly, when possible.
2022-10-04 15:59:30 -07:00
Trevor Elliott
a209cb63f5 ISLE: Enable the overlap checker (#5011)
This PR turns the overlap checker on by default, requiring the use of priorities to resolve overlap between rules.
2022-10-04 21:56:49 +00:00
Trevor Elliott
46e42601eb ISLE: Always default the priority to 0 (#4983)
* Always default priorities to 0 in the ISLE IR
* Fix a hidden overlap in the x64 backend
2022-09-29 15:32:29 -07:00
Trevor Elliott
7d5b2b5bb2 ISLE: Add the overlap_errors pragma (#4981)
* Add the overlap_errors pragma to ISLE
* Enable overlap errors in the x64 backend
2022-09-29 12:40:39 -07:00
Trevor Elliott
bf2fa40e4e Stabilize the error output order (#4976) 2022-09-28 17:23:54 -07:00
Trevor Elliott
2e954668c7 Sort overlap errors by position (#4975) 2022-09-28 13:23:31 -07:00
Trevor Elliott
faf31f6216 ISLE: Resolve overlap in prelude.isle and x64/inst.isle (#4941)
Resolve overlap in the ISLE prelude and the x64 inst module by introducing new types that allow better sharing of extractor resuls, or falling back on priorities.
2022-09-28 10:54:39 -07:00
Alex Crichton
7b311004b5 Leverage Cargo's workspace inheritance feature (#4905)
* Leverage Cargo's workspace inheritance feature

This commit is an attempt to reduce the complexity of the Cargo
manifests in this repository with Cargo's workspace-inheritance feature
becoming stable in Rust 1.64.0. This feature allows specifying fields in
the root workspace `Cargo.toml` which are then reused throughout the
workspace. For example this PR shares definitions such as:

* All of the Wasmtime-family of crates now use `version.workspace =
  true` to have a single location which defines the version number.
* All crates use `edition.workspace = true` to have one default edition
  for the entire workspace.
* Common dependencies are listed in `[workspace.dependencies]` to avoid
  typing the same version number in a lot of different places (e.g. the
  `wasmparser = "0.89.0"` is now in just one spot.

Currently the workspace-inheritance feature doesn't allow having two
different versions to inherit, so all of the Cranelift-family of crates
still manually specify their version. The inter-crate dependencies,
however, are shared amongst the root workspace.

This feature can be seen as a method of "preprocessing" of sorts for
Cargo manifests. This will help us develop Wasmtime but shouldn't have
any actual impact on the published artifacts -- everything's dependency
lists are still the same.

* Fix wasi-crypto tests
2022-09-26 11:30:01 -05:00
Chris Fallin
b652ce2fb1 ISLE: add support for multi-extractors and multi-constructors. (#4908)
* ISLE: add support for multi-extractors and multi-constructors.

This support allows for rules that process multiple matching values per
extractor call on the left-hand side, and as a result, can produce
multiple values from the constructor whose body they define.

This is useful in situations where we are matching on an input data
structure that can have multiple "nodes" for a given value or ID, for
example in an e-graph.

* Review feedback: all multi-ctors and multi-etors return iterators; no `Vec` case.

* Add additional warning suppressions to generated-code toplevels to be consistent with new islec output.
2022-09-21 23:36:50 +00:00
Trevor Elliott
b167172715 Add an overlap checker to ISLE (#4906)
https://github.com/bytecodealliance/wasmtime/pull/4906

Co-authored-by: Jamey Sharp <jsharp@fastly.com>
2022-09-21 14:07:59 -07:00
Trevor Elliott
9d99eff6f9 Flatten and patterns in ISLE (#4915)
Flatten nested and patterns into a single vector in the ISLE front-end.
2022-09-15 17:40:37 +00:00
Alex Crichton
65930640f8 Bump Wasmtime to 2.0.0 (#4874)
This commit replaces #4869 and represents the actual version bump that
should have happened had I remembered to bump the in-tree version of
Wasmtime to 1.0.0 prior to the branch-cut date. Alas!
2022-09-06 13:49:56 -05:00
Chris Fallin
c664fb6f70 Update ISLE error message: unknown term in expr, not pattern. (#4775)
This was likely a copy-paste from the `ast::Pattern` case, but here it
is checking a term name in `ast::Expr` and so should say "... in
expression", not "... in pattern".
2022-08-24 22:07:29 +00:00
Trevor Elliott
6b6fc9ec3e ISLE: Fix a bug with extractor ordering (#4661)
https://github.com/bytecodealliance/wasmtime/pull/4661

Co-authored-by: Chris Fallin <chris@cfallin.org>
2022-08-09 19:19:32 +00:00
wasmtime-publish
412fa04911 Bump Wasmtime to 0.41.0 (#4620)
Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
2022-08-04 20:02:19 -05:00
Trevor Elliott
586ec95c11 ISLE: Allow shadowing in let expressions (#4562)
* Support shadowing in isle

* Re-run the isle build.rs if the examples change

* Print error messages when isle tests fail

* Move run tests

* Refactor `let` uses that don't need to introduce unique names
2022-08-01 21:10:28 +00:00
Chris Fallin
8e9e9c52a1 ISLE: support more flexible integer constants. (#4559)
The ISLE language's lexer previously used a very primitive
`i64::from_str_radix` call to parse integer constants, allowing values
in the range -2^63..2^63 only. Also, underscores to separate digits (as
is allwoed in Rust) were not supported. Finally, 128-bit constants were
not supported at all.

This PR addresses all issues above:
- Integer constants are internally stored as 128-bit values.
- Parsing supports either signed (-2^127..2^127) or unsigned (0..2^128)
  range. Negation works independently of that, so one can write
  `-0xffff..ffff` (128 bits wide, i.e., -(2^128-1)) to get a `1`.
- Underscores are supported to separate groups of digits, so one can
  write `0xffff_ffff`.
- A minor oversight was fixed: hex constants can start with `0X`
  (uppercase) as well as `0x`, for consistency with Rust and C.

This PR also adds a new kind of ISLE test that actually runs a driver
linked to compiled ISLE code; we previously didn't have any such tests,
but it is now quite useful to assert correct interpretation of constant
values.
2022-07-29 21:52:14 +00:00
Alex Crichton
b9e63fe77a Update miette dependency to 5.1 (#4412)
Just some dependency gardening, no other external motivation.
2022-07-07 22:20:09 +00:00
Dan Gohman
371ae80ac3 Migrate most of wasmtime from lazy_static to once_cell (#4368)
* Update tracing-core to a version which doesn't depend on lazy-static.

* Update crossbeam-utils to a version that doesn't depend on lazy-static.

* Update crossbeam-epoch to a version that doesn't depend on lazy-static.

* Update clap to a version that doesn't depend on lazy-static.

* Convert Wasmtime's own use of lazy_static to once_cell.

* Make `GDB_REGISTRATION`'s comment a doc comment.

* Fix compilation on Windows.
2022-07-05 10:52:48 -07:00
wasmtime-publish
7c428bbd62 Bump Wasmtime to 0.40.0 (#4378)
Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
2022-07-05 09:10:52 -05:00
Waleed Dahshan
688168b4d7 Fix a mistake in the language reference (#4352)
It is clear that the third rule does not contribute to the rewriting of the expression `(A (B (D 42)))` to `(C (D 42))` to `(E 42)`.
2022-06-29 12:17:41 -07:00
Trevor Elliott
823817595a Fix some typos in the isle language reference (#4248) 2022-06-08 16:01:14 -07:00
wasmtime-publish
55946704cb Bump Wasmtime to 0.39.0 (#4225)
Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
2022-06-06 09:12:47 -05:00
Chris Fallin
2e14a0ecc5 ISLE: provide locations in errors in basic non-miette mode. (#4151)
In #4143 we made ISLE compilation part of the normal build flow again,
to avoid the issues with the checked-in source. To make this acceptably
fast, we cut down dependencies of the ISLE compiler, so the "fancy"
error printing is now optional. When not included, it just prints error
messages to stderr in a list. However, this did not include file
locations. It might be nice to have this without enabling the "fancy
printing" and waiting for that to build.

Fortunately most of the plumbing for this was already present (we had it
at one point before switching to miette). This PR adds back locations to
the basic error output. It now looks like:

```
  Error building ISLE files: ISLE errors:

  src/isa/aarch64/inst.isle:1:1: parse error: Unexpected token Symbol("asdf")
```
2022-05-12 12:55:00 -07:00
bjorn3
9538336f82 Use HashMaps instead of BTreeMaps in isle where possible (#4147)
The HashMap implementation is significantly simpler than the BTreeMap
implementation. Because of this switching reduces compilation time of
cranelift-isle by about 10%.

# Before
$ hyperfine --prepare "cargo clean" "cargo build"
Benchmark 1: cargo build
  Time (mean ± σ):      5.221 s ±  0.094 s    [User: 10.659 s, System: 0.734 s]
  Range (min … max):    5.151 s …  5.420 s    10 runs

# After
$ hyperfine --prepare "cargo clean" "cargo build"
Benchmark 1: cargo build
  Time (mean ± σ):      4.746 s ±  0.150 s    [User: 9.109 s, System: 0.721 s]
  Range (min … max):    4.630 s …  5.144 s    10 runs
2022-05-12 10:02:23 -07:00
Chris Fallin
5d671952ee Cranelift: do not check in generated ISLE code; regenerate on every compile. (#4143)
This PR fixes #4066: it modifies the Cranelift `build.rs` workflow to
invoke the ISLE DSL compiler on every compilation, rather than only
when the user specifies a special "rebuild ISLE" feature.

The main benefit of this change is that it vastly simplifies the mental
model required of developers, and removes a bunch of failure modes
we have tried to work around in other ways. There is now just one
"source of truth", the ISLE source itself, in the repository, and so there
is no need to understand a special "rebuild" step and how to handle
merge errors. There is no special process needed to develop the compiler
when modifying the DSL. And there is no "noise" in the git history produced
by constantly-regenerated files.

The two main downsides we discussed in #4066 are:
- Compile time could increase, by adding more to the "meta" step before the main build;
- It becomes less obvious where the source definitions are (everything becomes
  more "magic"), which makes exploration and debugging harder.

This PR addresses each of these concerns:

1. To maintain reasonable compile time, it includes work to cut down the
   dependencies of the `cranelift-isle` crate to *nothing* (only the Rust stdlib),
   in the default build. It does this by putting the error-reporting bits
   (`miette` crate) under an optional feature, and the logging (`log` crate) under
   a feature-controlled macro, and manually writing an `Error` impl rather than
   using `thiserror`. This completely avoids proc macros and the `syn` build slowness.

   The user can still get nice errors out of `miette`: this is enabled by specifying
   a Cargo feature `--features isle-errors`.

2. To allow the user to optionally inspect the generated source, which nominally
   lives in a hard-to-find path inside `target/` now, this PR adds a feature `isle-in-source-tree`
   that, as implied by the name, moves the target for ISLE generated source into
   the source tree, at `cranelift/codegen/isle_generated_source/`. It seems reasonable
   to do this when an explicit feature (opt-in) is specified because this is how ISLE regeneration
   currently works as well. To prevent surprises, if the feature is *not* specified, the
   build fails if this directory exists.
2022-05-11 22:25:24 -07:00
Chris Fallin
2af8d1e93c Cranelift/ISLE: re-apply prio-trie fix, this time with fixed fix. (#4117)
* ISLE compiler: fix priority-trie interval bug. (#4093)

This PR fixes a bug in the ISLE compiler related to rule priorities.

An important note first: the bug did not affect the correctness of the
Cranelift backends, either in theory (because the rules should be
correct applied in any order, even contrary to the stated priorities)
or in practice (because the generated code actually does not change at
all with the DSL compiler fix, only with a separate minimized bug
example).

The issue was a simple swap of `min` for `max` (see first
commit). This is the minimal fix, I think, to get a correct
priority-trie with the minimized bug example in this commit.

However, while debugging this, I started to convince myself that the
complexity of merging multiple priority ranges using the sort of
hybrid interval tree / string-matching trie data structure was
unneeded. The original design was built with the assumption we might
have a bunch of different priority levels, and would need the
efficiency of merging where possible. But in practice we haven't used
priorities this way: the vast majority of lowering rules exist at the
default (priority 0), and just a few overrides are explicitly at prio
1, 2 or (rarely) 3.

So, it turns out to be a lot simpler to label trie edges with (prio,
symbol) rather than (prio-range, symbol), and delete the whole mess of
interval-splitting logic on insertion. It's easier (IMHO) to convince
oneself that the resulting insertion algorithm is correct.

I was worried that this might impact the size of the generated Rust
code or its runtime, but In fact, to my initial surprise (but it makes
sense given the above "rarely used" factor), the generated code with
this compiler fix is *exactly the same*. I rebuilt with `--features
rebuild-isle,all-arch` but... there were no diffs to commit! This is
to me the simplest evidence that we didn't really need that
complexity.

* Fix earlier commit from #4093: properly sort trie.

This commit fixes an in-hindsight-obvious bug in #4093: the trie's edges
must be sorted recursively, not just at the top level.

With this fix, the generated code differs only in one cosmetic way (a
let-binding moves) but otherwise is the same.

This includes @fitzgen's fix to the CI (from the revert in #4102) that
deletes manifests to actually check that the checked-in source is
consistent with the checked-in compiler. The force-rebuild step is now
in a shell script for convenience: anyone hacking on the ISLE compiler
itself can use this script to more easily rebuild everything.

* Add note to build.rs to remind to update force-rebuild-isle.sh
2022-05-09 16:36:48 -07:00
Nick Fitzgerald
b525661d2f Revert ISLE priority trie regression and fix ISLE rebuild CI job (#4102)
* Revert "ISLE compiler: fix priority-trie interval bug. (#4093)"

This reverts commit 2122337112.

* ci: Delete ISLE manifest files to force an ISLE rebuild

This makes it so that we actually rebuild ISLE rather than just check that the
manifests are up-to-date.
2022-05-05 13:43:22 -05:00
wasmtime-publish
9a6854456d Bump Wasmtime to 0.38.0 (#4103)
Co-authored-by: Wasmtime Publish <wasmtime-publish@users.noreply.github.com>
2022-05-05 13:43:02 -05:00
Chris Fallin
2122337112 ISLE compiler: fix priority-trie interval bug. (#4093)
This PR fixes a bug in the ISLE compiler related to rule priorities.

An important note first: the bug did not affect the correctness of the
Cranelift backends, either in theory (because the rules should be
correct applied in any order, even contrary to the stated priorities)
or in practice (because the generated code actually does not change at
all with the DSL compiler fix, only with a separate minimized bug
example).

The issue was a simple swap of `min` for `max` (see first
commit). This is the minimal fix, I think, to get a correct
priority-trie with the minimized bug example in this commit.

However, while debugging this, I started to convince myself that the
complexity of merging multiple priority ranges using the sort of
hybrid interval tree / string-matching trie data structure was
unneeded. The original design was built with the assumption we might
have a bunch of different priority levels, and would need the
efficiency of merging where possible. But in practice we haven't used
priorities this way: the vast majority of lowering rules exist at the
default (priority 0), and just a few overrides are explicitly at prio
1, 2 or (rarely) 3.

So, it turns out to be a lot simpler to label trie edges with (prio,
symbol) rather than (prio-range, symbol), and delete the whole mess of
interval-splitting logic on insertion. It's easier (IMHO) to convince
oneself that the resulting insertion algorithm is correct.

I was worried that this might impact the size of the generated Rust
code or its runtime, but In fact, to my initial surprise (but it makes
sense given the above "rarely used" factor), the generated code with
this compiler fix is *exactly the same*. I rebuilt with `--features
rebuild-isle,all-arch` but... there were no diffs to commit! This is
to me the simplest evidence that we didn't really need that
complexity.
2022-05-03 09:16:44 -07:00