Backed out 3 changesets (bug 1547682) for build bustages: "cannot find function `init_frame` in this scope". CLOSED TREE
authorBrindusan Cristian <cbrindusan@mozilla.com>
Thu, 02 May 2019 13:54:51 +0300
changeset 531108 00ca72fd66c249afe66d16ade5d3c6597f939a95
parent 531107 815455c1634eb1ca7f51f03a6117d4fe037809b5
child 531109 56a1e86bccf1fba70b8743098b9ff57d7cce366d
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1547682
milestone68.0a1
backs out815455c1634eb1ca7f51f03a6117d4fe037809b5
7bfcf5af011d1bdad6dd065d1b83cfb31ca60f2b
9fd0c4622f00d5173824b7ebef3119edbdfdf84b
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 3 changesets (bug 1547682) for build bustages: "cannot find function `init_frame` in this scope". CLOSED TREE Backed out changeset 815455c1634e (bug 1547682) Backed out changeset 7bfcf5af011d (bug 1547682) Backed out changeset 9fd0c4622f00 (bug 1547682)
.cargo/config.in
Cargo.lock
Cargo.toml
js/src/fuzz-tests/testWasm.cpp
js/src/wasm/WasmCraneliftCompile.cpp
js/src/wasm/cranelift/src/baldrapi.rs
js/src/wasm/cranelift/src/baldrdash.rs
js/src/wasm/cranelift/src/compile.rs
js/src/wasm/cranelift/src/utils.rs
js/src/wasm/cranelift/src/wasm2clif.rs
third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
third_party/rust/cranelift-codegen-meta/src/cdsl/ast.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/cpu_modes.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/formats.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/inst.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/isa.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/mod.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/operands.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/type_inference.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/typevar.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/xform.rs
third_party/rust/cranelift-codegen-meta/src/gen_inst.rs
third_party/rust/cranelift-codegen-meta/src/gen_legalizer.rs
third_party/rust/cranelift-codegen-meta/src/isa/arm32/mod.rs
third_party/rust/cranelift-codegen-meta/src/isa/arm64/mod.rs
third_party/rust/cranelift-codegen-meta/src/isa/riscv/mod.rs
third_party/rust/cranelift-codegen-meta/src/isa/x86/legalize.rs
third_party/rust/cranelift-codegen-meta/src/isa/x86/mod.rs
third_party/rust/cranelift-codegen-meta/src/lib.rs
third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs
third_party/rust/cranelift-codegen-meta/src/shared/legalize.rs
third_party/rust/cranelift-codegen-meta/src/shared/mod.rs
third_party/rust/cranelift-codegen-meta/src/srcgen.rs
third_party/rust/cranelift-codegen-meta/src/unique_table.rs
third_party/rust/cranelift-codegen/.cargo-checksum.json
third_party/rust/cranelift-codegen/meta-python/cdsl/ast.py
third_party/rust/cranelift-codegen/src/divconst_magic_numbers.rs
third_party/rust/cranelift-codegen/src/isa/x86/enc_tables.rs
third_party/rust/cranelift-codegen/src/simple_preopt.rs
third_party/rust/cranelift-wasm/.cargo-checksum.json
third_party/rust/cranelift-wasm/Cargo.toml
third_party/rust/cranelift-wasm/src/code_translator.rs
third_party/rust/cranelift-wasm/src/environ/dummy.rs
third_party/rust/cranelift-wasm/src/environ/spec.rs
third_party/rust/cranelift-wasm/src/func_translator.rs
third_party/rust/cranelift-wasm/src/lib.rs
third_party/rust/cranelift-wasm/src/state.rs
--- a/.cargo/config.in
+++ b/.cargo/config.in
@@ -19,13 +19,13 @@ replace-with = "vendored-sources"
 
 [source."https://github.com/rust-lang-nursery/packed_simd"]
 git = "https://github.com/hsivonen/packed_simd"
 branch = "rust_1_32"
 replace-with = "vendored-sources"
 
 [source."https://github.com/CraneStation/Cranelift"]
 git = "https://github.com/CraneStation/Cranelift"
-rev = "be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
+rev = "538a0662bf90a1daa9921c10f34827ace134abf1"
 replace-with = "vendored-sources"
 
 [source.vendored-sources]
 directory = '@top_srcdir@/third_party/rust'
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -161,18 +161,18 @@ dependencies = [
  "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "baldrdash"
 version = "0.1.0"
 dependencies = [
  "bindgen 0.49.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
- "cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "base64"
 version = "0.9.3"
@@ -581,67 +581,67 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-bforest"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e#be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
-dependencies = [
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
 ]
 
 [[package]]
 name = "cranelift-codegen"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e#be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
-dependencies = [
- "cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
- "cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-codegen-meta"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e#be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
-dependencies = [
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
 ]
 
 [[package]]
 name = "cranelift-entity"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e#be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
 
 [[package]]
 name = "cranelift-frontend"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e#be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
-dependencies = [
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-wasm"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e#be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
 dependencies = [
  "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
- "cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)",
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "crc"
@@ -3640,22 +3640,22 @@ dependencies = [
 "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 "checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf"
 "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
 "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
 "checksum core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62ceafe1622ffc9a332199096841d0ff9912ec8cf8f9cde01e254a7d5217cd10"
 "checksum core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f46450d6f2397261af420b4ccce23807add2e45fa206410a03d66fb7f050ae"
 "checksum cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72fa26cb151d3ae4b70f63d67d0fed57ce04220feafafbae7f503bef7aae590d"
 "checksum cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "49726015ab0ca765144fcca61e4a7a543a16b795a777fa53f554da2fffff9a94"
-"checksum cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)" = "<none>"
-"checksum cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)" = "<none>"
-"checksum cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)" = "<none>"
-"checksum cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)" = "<none>"
-"checksum cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)" = "<none>"
-"checksum cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=be8a83132df0a277da8fa3e6a9c5d03c4a05d57e)" = "<none>"
+"checksum cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
 "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2af0e75710d6181e234c8ecc79f14a97907850a541b13b0be1dd10992f2e4620"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
 "checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a"
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -59,13 +59,13 @@ codegen-units = 1
 [patch.crates-io]
 libudev-sys = { path = "dom/webauthn/libudev-sys" }
 serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums10" }
 winapi = { git = "https://github.com/froydnj/winapi-rs", branch = "aarch64" }
 packed_simd = { git = "https://github.com/hsivonen/packed_simd", branch = "rust_1_32" }
 
 [patch.crates-io.cranelift-codegen]
 git = "https://github.com/CraneStation/Cranelift"
-rev = "be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
+rev = "538a0662bf90a1daa9921c10f34827ace134abf1"
 
 [patch.crates-io.cranelift-wasm]
 git = "https://github.com/CraneStation/Cranelift"
-rev = "be8a83132df0a277da8fa3e6a9c5d03c4a05d57e"
+rev = "538a0662bf90a1daa9921c10f34827ace134abf1"
--- a/js/src/fuzz-tests/testWasm.cpp
+++ b/js/src/fuzz-tests/testWasm.cpp
@@ -157,16 +157,22 @@ static int testWasmFuzz(const uint8_t* b
         // to baseline instead.
         if (IonCanCompile()) {
           enableWasmIon = true;
         } else {
           enableWasmBaseline = true;
         }
       }
 
+      // TODO: Cranelift is not stable for fuzzing, defer to baseline
+      if (enableWasmCranelift) {
+        enableWasmCranelift = false;
+        enableWasmBaseline = true;
+      }
+
       if (enableWasmAwaitTier2) {
         // Tier 2 needs Baseline + {Ion,Cranelift}
         enableWasmBaseline = true;
 
         if (!enableWasmIon && !enableWasmCranelift) {
           enableWasmIon = true;
         }
       }
--- a/js/src/wasm/WasmCraneliftCompile.cpp
+++ b/js/src/wasm/WasmCraneliftCompile.cpp
@@ -404,18 +404,34 @@ BD_ConstantValue global_constantValue(co
       v.u.f64 = value.f64();
       break;
     default:
       MOZ_CRASH("Bad type");
   }
   return v;
 }
 
+#ifdef DEBUG
+static bool IsCraneliftCompatible(TypeCode type) {
+  switch (type) {
+    case TypeCode::I32:
+    case TypeCode::I64:
+    case TypeCode::F32:
+    case TypeCode::F64:
+      return true;
+    default:
+      return false;
+  }
+}
+#endif
+
 TypeCode global_type(const GlobalDesc* global) {
-  return TypeCode(global->type().code());
+  TypeCode type = TypeCode(global->type().code());
+  MOZ_ASSERT(IsCraneliftCompatible(type));
+  return type;
 }
 
 size_t global_tlsOffset(const GlobalDesc* global) {
   return globalToTlsOffset(global->offset());
 }
 
 // TableDesc
 
@@ -428,16 +444,21 @@ size_t table_tlsOffset(const TableDesc* 
 
 // Sig
 
 size_t funcType_numArgs(const FuncTypeWithId* funcType) {
   return funcType->args().length();
 }
 
 const BD_ValType* funcType_args(const FuncTypeWithId* funcType) {
+#ifdef DEBUG
+  for (ValType valType : funcType->args()) {
+    MOZ_ASSERT(IsCraneliftCompatible(TypeCode(valType.code())));
+  }
+#endif
   static_assert(sizeof(BD_ValType) == sizeof(ValType), "update BD_ValType");
   return (const BD_ValType*)&funcType->args()[0];
 }
 
 TypeCode funcType_retType(const FuncTypeWithId* funcType) {
   return TypeCode(funcType->ret().code());
 }
 
--- a/js/src/wasm/cranelift/src/baldrapi.rs
+++ b/js/src/wasm/cranelift/src/baldrapi.rs
@@ -15,19 +15,16 @@
 
 //! This module exports the bindings generated by bindgen form the baldrapi.h file.
 //!
 //! The Baldr API consists of a set of C functions and some associated types.
 
 #![allow(non_upper_case_globals)]
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
-// We need to allow dead code because the Rustc compiler complains about variants never being
-// constructed in TypeCode, which is true because these values come from C++.
-#![allow(dead_code)]
 
 use cranelift_codegen::binemit::CodeOffset;
 use cranelift_codegen::entity::EntityRef;
 use cranelift_codegen::ir::SourceLoc;
 use cranelift_wasm::FuncIndex;
 
 use compile::CompiledFunc;
 
--- a/js/src/wasm/cranelift/src/baldrdash.rs
+++ b/js/src/wasm/cranelift/src/baldrdash.rs
@@ -11,102 +11,106 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 // Safe wrappers to the low-level ABI.  This re-exports all types in
 // baldrapi but none of the functions.
 
+use baldrapi::CraneliftModuleEnvironment;
 use cranelift_codegen::cursor::FuncCursor;
 use cranelift_codegen::entity::EntityRef;
 use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
 use cranelift_codegen::ir::{self, InstBuilder};
-use cranelift_wasm::{FuncIndex, GlobalIndex, SignatureIndex, TableIndex, WasmResult};
-
+use cranelift_wasm::{FuncIndex, GlobalIndex, SignatureIndex, TableIndex};
 use std::mem;
 use std::slice;
 
 use baldrapi;
-use baldrapi::BD_ValType as ValType;
-use baldrapi::CraneliftModuleEnvironment;
-use baldrapi::TypeCode;
-
-use utils::BasicError;
 
 pub use baldrapi::BD_SymbolicAddress as SymbolicAddress;
+pub use baldrapi::BD_ValType as ValType;
 pub use baldrapi::CraneliftCompiledFunc as CompiledFunc;
 pub use baldrapi::CraneliftFuncCompileInput as FuncCompileInput;
 pub use baldrapi::CraneliftMetadataEntry as MetadataEntry;
 pub use baldrapi::CraneliftStaticEnvironment as StaticEnvironment;
 pub use baldrapi::FuncTypeIdDescKind;
 pub use baldrapi::Trap;
+pub use baldrapi::TypeCode;
 
-/// Converts a `TypeCode` into the equivalent Cranelift type, if it's a known type, or an error
-/// otherwise.
-#[inline]
-fn typecode_to_type(type_code: TypeCode) -> WasmResult<Option<ir::Type>> {
-    match type_code {
-        TypeCode::I32 => Ok(Some(ir::types::I32)),
-        TypeCode::I64 => Ok(Some(ir::types::I64)),
-        TypeCode::F32 => Ok(Some(ir::types::F32)),
-        TypeCode::F64 => Ok(Some(ir::types::F64)),
-        TypeCode::BlockVoid => Ok(None),
-        _ => Err(BasicError::new(format!("unknown type code: {:?}", type_code)).into()),
+/// Convert a `TypeCode` into the equivalent Cranelift type.
+///
+/// We expect Cranelift's `VOID` type to go away in the future, so use `None` to represent a
+/// function without a return value.
+impl Into<Option<ir::Type>> for TypeCode {
+    fn into(self) -> Option<ir::Type> {
+        match self {
+            TypeCode::I32 => Some(ir::types::I32),
+            TypeCode::I64 => Some(ir::types::I64),
+            TypeCode::F32 => Some(ir::types::F32),
+            TypeCode::F64 => Some(ir::types::F64),
+            TypeCode::BlockVoid => None,
+            _ => panic!("unexpected type"),
+        }
     }
 }
 
 /// Convert a non-void `TypeCode` into the equivalent Cranelift type.
-#[inline]
-fn typecode_to_nonvoid_type(type_code: TypeCode) -> WasmResult<ir::Type> {
-    Ok(typecode_to_type(type_code)?.expect("unexpected void type"))
+impl Into<ir::Type> for TypeCode {
+    fn into(self) -> ir::Type {
+        match self.into() {
+            Some(t) => t,
+            None => panic!("unexpected void type"),
+        }
+    }
 }
 
 /// Convert a `TypeCode` into the equivalent Cranelift type.
-#[inline]
-fn valtype_to_type(val_type: ValType) -> WasmResult<ir::Type> {
-    let type_code = unsafe { baldrapi::env_unpack(val_type) };
-    typecode_to_nonvoid_type(type_code)
+impl Into<ir::Type> for ValType {
+    fn into(self) -> ir::Type {
+        unsafe { baldrapi::env_unpack(self) }.into()
+    }
 }
 
 /// Convert a u32 into a `BD_SymbolicAddress`.
 impl From<u32> for SymbolicAddress {
     fn from(x: u32) -> SymbolicAddress {
         assert!(x < SymbolicAddress::Limit as u32);
         unsafe { mem::transmute(x) }
     }
 }
 
 #[derive(Clone, Copy)]
 pub struct GlobalDesc(*const baldrapi::GlobalDesc);
 
 impl GlobalDesc {
-    pub fn value_type(self) -> WasmResult<ir::Type> {
-        let type_code = unsafe { baldrapi::global_type(self.0) };
-        typecode_to_nonvoid_type(type_code)
+    pub fn value_type(self) -> TypeCode {
+        unsafe { baldrapi::global_type(self.0) }
     }
 
     pub fn is_constant(self) -> bool {
         unsafe { baldrapi::global_isConstant(self.0) }
     }
 
     pub fn is_indirect(self) -> bool {
         unsafe { baldrapi::global_isIndirect(self.0) }
     }
 
     /// Insert an instruction at `pos` that materialized the constant value.
-    pub fn emit_constant(self, pos: &mut FuncCursor) -> WasmResult<ir::Value> {
+    pub fn emit_constant(self, pos: &mut FuncCursor) -> ir::Value {
         unsafe {
             let v = baldrapi::global_constantValue(self.0);
+            // Note that the floating point constants below
             match v.t {
-                TypeCode::I32 => Ok(pos.ins().iconst(ir::types::I32, i64::from(v.u.i32))),
-                TypeCode::I64 => Ok(pos.ins().iconst(ir::types::I64, v.u.i64)),
-                TypeCode::F32 => Ok(pos.ins().f32const(Ieee32::with_bits(v.u.i32 as u32))),
-                TypeCode::F64 => Ok(pos.ins().f64const(Ieee64::with_bits(v.u.i64 as u64))),
-                _ => Err(BasicError::new(format!("unexpected type: {}", v.t as u64)).into()),
+                TypeCode::I32 => pos.ins().iconst(ir::types::I32, i64::from(v.u.i32)),
+                TypeCode::I64 => pos.ins().iconst(ir::types::I64, v.u.i64),
+                TypeCode::F32 => pos.ins().f32const(Ieee32::with_bits(v.u.i32 as u32)),
+                TypeCode::F64 => pos.ins().f64const(Ieee64::with_bits(v.u.i64 as u64)),
+                _ => panic!("unexpected type"),
             }
         }
     }
 
     /// Get the offset from the `WasmTlsReg` to the memory representing this global variable.
     pub fn tls_offset(self) -> usize {
         unsafe { baldrapi::global_tlsOffset(self.0) }
     }
@@ -121,37 +125,33 @@ impl TableDesc {
         unsafe { baldrapi::table_tlsOffset(self.0) }
     }
 }
 
 #[derive(Clone, Copy)]
 pub struct FuncTypeWithId(*const baldrapi::FuncTypeWithId);
 
 impl FuncTypeWithId {
-    pub fn args<'a>(self) -> WasmResult<Vec<ir::Type>> {
-        let num_args = unsafe { baldrapi::funcType_numArgs(self.0) };
-        // The `funcType_args` callback crashes when there are no arguments. Also note that
-        // `slice::from_raw_parts()` requires a non-null pointer for empty slices.
-        // TODO: We should get all the parts of a signature in a single callback that returns a
-        // struct.
-        if num_args == 0 {
-            Ok(Vec::new())
-        } else {
-            let args = unsafe { slice::from_raw_parts(baldrapi::funcType_args(self.0), num_args) };
-            let mut ret = Vec::new();
-            for &arg in args {
-                ret.push(valtype_to_type(arg)?);
+    pub fn args<'a>(self) -> &'a [ValType] {
+        unsafe {
+            let num_args = baldrapi::funcType_numArgs(self.0);
+            // The `funcType_args` callback crashes when there are no arguments. Also note that
+            // `slice::from_raw_parts()` requires a non-null pointer for empty slices.
+            // TODO: We should get all the parts of a signature in a single callback that returns a
+            // struct.
+            if num_args == 0 {
+                &[]
+            } else {
+                slice::from_raw_parts(baldrapi::funcType_args(self.0), num_args)
             }
-            Ok(ret)
         }
     }
 
-    pub fn ret_type(self) -> WasmResult<Option<ir::Type>> {
-        let type_code = unsafe { baldrapi::funcType_retType(self.0) };
-        typecode_to_type(type_code)
+    pub fn ret_type(self) -> TypeCode {
+        unsafe { baldrapi::funcType_retType(self.0) }
     }
 
     pub fn id_kind(self) -> FuncTypeIdDescKind {
         unsafe { baldrapi::funcType_idKind(self.0) }
     }
 
     pub fn id_immediate(self) -> usize {
         unsafe { baldrapi::funcType_idImmediate(self.0) }
--- a/js/src/wasm/cranelift/src/compile.rs
+++ b/js/src/wasm/cranelift/src/compile.rs
@@ -104,17 +104,17 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
         &mut self,
         func: &bd::FuncCompileInput,
     ) -> WasmResult<bd::FuncTypeWithId> {
         self.context.clear();
 
         // Set up the signature before translating the WebAssembly byte code.
         // The translator refers to it.
         let index = FuncIndex::new(func.index as usize);
-        let wsig = init_sig(&mut self.context.func.signature, &self.environ, index)?;
+        let wsig = init_sig(&mut self.context.func.signature, &self.environ, index);
         self.context.func.name = wasm_function_name(index);
 
         let tenv = &mut TransEnv::new(&*self.isa, &self.environ, self.static_environ);
         self.trans.translate(
             func.bytecode(),
             func.offset_in_module as usize,
             &mut self.context.func,
             tenv,
--- a/js/src/wasm/cranelift/src/utils.rs
+++ b/js/src/wasm/cranelift/src/utils.rs
@@ -12,18 +12,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 /// Helpers common to other source files here.
 use std::error;
 use std::fmt;
 
-use cranelift_wasm::WasmError;
-
 type DashError = Box<error::Error>;
 pub type DashResult<T> = Result<T, DashError>;
 
 /// A simple error type that contains a string message, used to wrap raw Cranelift error types
 /// which don't implement std::error::Error.
 
 #[derive(Debug)]
 pub struct BasicError {
@@ -42,14 +40,8 @@ impl fmt::Display for BasicError {
     }
 }
 
 impl error::Error for BasicError {
     fn description(&self) -> &str {
         &self.msg
     }
 }
-
-impl Into<WasmError> for BasicError {
-    fn into(self) -> WasmError {
-        WasmError::User(self.into())
-    }
-}
--- a/js/src/wasm/cranelift/src/wasm2clif.rs
+++ b/js/src/wasm/cranelift/src/wasm2clif.rs
@@ -63,51 +63,49 @@ fn imm64(offset: usize) -> ir::immediate
 }
 
 /// Convert a usize offset into a `Uimm64`.
 fn uimm64(offset: usize) -> ir::immediates::Uimm64 {
     (offset as u64).into()
 }
 
 /// Initialize a `Signature` from a wasm signature.
-fn init_sig_from_wsig(sig: &mut ir::Signature, wsig: bd::FuncTypeWithId) -> WasmResult<()> {
+fn init_sig_from_wsig(sig: &mut ir::Signature, wsig: bd::FuncTypeWithId) {
     sig.clear(CallConv::Baldrdash);
-    for arg in wsig.args()? {
-        sig.params.push(ir::AbiParam::new(arg));
+    for &arg in wsig.args() {
+        sig.params.push(ir::AbiParam::new(arg.into()));
     }
 
-    if let Some(ret_type) = wsig.ret_type()? {
+    if let Some(ret_type) = wsig.ret_type().into() {
         let ret = match ret_type {
             // Spidermonkey requires i32 returns to have their high 32 bits
             // zero so that it can directly box them.
             ir::types::I32 => ir::AbiParam::new(ret_type).uext(),
             _ => ir::AbiParam::new(ret_type),
         };
         sig.returns.push(ret);
     }
 
     // Add a VM context pointer argument.
     // This corresponds to SpiderMonkey's `WasmTlsReg` hidden argument.
     sig.params.push(ir::AbiParam::special(
         native_pointer_type(),
         ir::ArgumentPurpose::VMContext,
     ));
-
-    Ok(())
 }
 
 /// Initialize the signature `sig` to match the function with `index` in `env`.
 pub fn init_sig(
     sig: &mut ir::Signature,
     env: &bd::ModuleEnvironment,
     func_index: FuncIndex,
-) -> WasmResult<bd::FuncTypeWithId> {
+) -> bd::FuncTypeWithId {
     let wsig = env.function_signature(func_index);
-    init_sig_from_wsig(sig, wsig)?;
-    Ok(wsig)
+    init_sig_from_wsig(sig, wsig);
+    wsig
 }
 
 /// A `TargetIsa` and `ModuleEnvironment` joined so we can implement `FuncEnvironment`.
 pub struct TransEnv<'a, 'b, 'c> {
     isa: &'a TargetIsa,
     env: &'b bd::ModuleEnvironment<'b>,
     static_env: &'c bd::StaticEnvironment,
 
@@ -385,29 +383,25 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
     fn target_config(&self) -> TargetFrontendConfig {
         self.isa.frontend_config()
     }
 
     fn pointer_type(&self) -> ir::Type {
         native_pointer_type()
     }
 
-    fn make_global(
-        &mut self,
-        func: &mut ir::Function,
-        index: GlobalIndex,
-    ) -> WasmResult<GlobalVariable> {
+    fn make_global(&mut self, func: &mut ir::Function, index: GlobalIndex) -> GlobalVariable {
         let global = self.env.global(index);
         if global.is_constant() {
             // Constant globals have a known value at compile time. We insert an instruction to
             // materialize the constant at the front of the entry block.
             let mut pos = FuncCursor::new(func);
             pos.next_ebb().expect("empty function");
             pos.next_inst();
-            return Ok(GlobalVariable::Const(global.emit_constant(&mut pos)?));
+            return GlobalVariable::Const(global.emit_constant(&mut pos));
         }
 
         // This is a global variable. Here we don't care if it is mutable or not.
         let vmctx_gv = self.get_vmctx_gv(func);
         let offset = global.tls_offset();
 
         // Some globals are represented as a pointer to the actual data, in which case we
         // must do an extra dereference to get to them.
@@ -418,26 +412,24 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
                 global_type: native_pointer_type(),
                 readonly: false,
             });
             (gv, 0.into())
         } else {
             (vmctx_gv, offset32(offset))
         };
 
-        let mem_ty = global.value_type()?;
-
-        Ok(GlobalVariable::Memory {
+        GlobalVariable::Memory {
             gv: base_gv,
-            ty: mem_ty,
+            ty: global.value_type().into(),
             offset,
-        })
+        }
     }
 
-    fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult<ir::Heap> {
+    fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> ir::Heap {
         assert_eq!(index.index(), 0, "Only one WebAssembly memory supported");
         // Get the address of the `TlsData::memoryBase` field.
         let base_addr = self.get_vmctx_gv(func);
         // Get the `TlsData::memoryBase` field. We assume this is never modified during execution
         // of the function.
         let base = func.create_global_value(ir::GlobalValueData::Load {
             base: base_addr,
             offset: offset32(0),
@@ -458,46 +450,42 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
                 base: base_addr,
                 offset: native_pointer_size().into(),
                 global_type: ir::types::I32,
                 readonly: false,
             });
             ir::HeapStyle::Dynamic { bound_gv }
         };
 
-        Ok(func.create_heap(ir::HeapData {
+        func.create_heap(ir::HeapData {
             base,
             min_size,
             offset_guard_size: guard_size,
             style,
             index_type: ir::types::I32,
-        }))
+        })
     }
 
-    fn make_indirect_sig(
-        &mut self,
-        func: &mut ir::Function,
-        index: SignatureIndex,
-    ) -> WasmResult<ir::SigRef> {
+    fn make_indirect_sig(&mut self, func: &mut ir::Function, index: SignatureIndex) -> ir::SigRef {
         let mut sigdata = ir::Signature::new(CallConv::Baldrdash);
         let wsig = self.env.signature(index);
-        init_sig_from_wsig(&mut sigdata, wsig)?;
+        init_sig_from_wsig(&mut sigdata, wsig);
 
         if wsig.id_kind() != bd::FuncTypeIdDescKind::None {
             // A signature to be used for an indirect call also takes a signature id.
             sigdata.params.push(ir::AbiParam::special(
                 native_pointer_type(),
                 ir::ArgumentPurpose::SignatureId,
             ));
         }
 
-        Ok(func.import_signature(sigdata))
+        func.import_signature(sigdata)
     }
 
-    fn make_table(&mut self, func: &mut ir::Function, index: TableIndex) -> WasmResult<ir::Table> {
+    fn make_table(&mut self, func: &mut ir::Function, index: TableIndex) -> ir::Table {
         let table_desc = self.get_table(func, index);
 
         // TODO we'd need a better way to synchronize the shape of GlobalDataDesc and these
         // offsets.
         let bound_gv = func.create_global_value(ir::GlobalValueData::Load {
             base: table_desc.global,
             offset: 0.into(),
             global_type: ir::types::I32,
@@ -506,40 +494,36 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
 
         let base_gv = func.create_global_value(ir::GlobalValueData::Load {
             base: table_desc.global,
             offset: offset32(native_pointer_size() as usize),
             global_type: native_pointer_type(),
             readonly: false,
         });
 
-        Ok(func.create_table(ir::TableData {
+        func.create_table(ir::TableData {
             base_gv,
             min_size: ir::immediates::Uimm64::new(0),
             bound_gv,
             element_size: ir::immediates::Uimm64::new(u64::from(self.pointer_bytes()) * 2),
             index_type: ir::types::I32,
-        }))
+        })
     }
 
-    fn make_direct_func(
-        &mut self,
-        func: &mut ir::Function,
-        index: FuncIndex,
-    ) -> WasmResult<ir::FuncRef> {
+    fn make_direct_func(&mut self, func: &mut ir::Function, index: FuncIndex) -> ir::FuncRef {
         // Create a signature.
         let mut sigdata = ir::Signature::new(CallConv::Baldrdash);
-        init_sig(&mut sigdata, &self.env, index)?;
+        init_sig(&mut sigdata, &self.env, index);
         let signature = func.import_signature(sigdata);
 
-        Ok(func.import_function(ir::ExtFuncData {
+        func.import_function(ir::ExtFuncData {
             name: wasm_function_name(index),
             signature,
             colocated: true,
-        }))
+        })
     }
 
     fn translate_call_indirect(
         &mut self,
         mut pos: FuncCursor,
         table_index: TableIndex,
         table: ir::Table,
         sig_index: SignatureIndex,
@@ -763,20 +747,19 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
             .special_param(ir::ArgumentPurpose::VMContext)
             .expect("Missing vmctx arg");
         let addr = pos.ins().func_addr(native_pointer_type(), fnref);
         let call = pos.ins().call_indirect(sigref, addr, &[instance, vmctx]);
         self.switch_to_wasm_tls_realm(&mut pos);
         Ok(pos.func.dfg.first_result(call))
     }
 
-    fn translate_loop_header(&mut self, mut pos: FuncCursor) -> WasmResult<()> {
+    fn translate_loop_header(&mut self, mut pos: FuncCursor) {
         let interrupt = self.load_interrupt_flag(&mut pos);
         pos.ins().trapnz(interrupt, ir::TrapCode::Interrupt);
-        Ok(())
     }
 
     fn return_mode(&self) -> ReturnMode {
         // Since we're using SM's epilogue insertion code, we can only handle a single return
         // instruction at the end of the function.
         ReturnMode::FallthroughReturn
     }
 }
--- a/third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
+++ b/third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"253c80832ab598570d604ae8a8108ea9835b8eef8d9b9645408ed025ce3b574a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"3406fec29fe80c979dc938a0fddda354ed96611276068b951e2b5b23ad018338","src/cdsl/cpu_modes.rs":"57c40621115a58faa7af1c729ecaf8cda01c2b143008bde6d8c70885e7c3fd75","src/cdsl/formats.rs":"858f0a6ea62580a2812a8f2ff68dd25298b6ea4c2413657c41630a044492ea0d","src/cdsl/inst.rs":"ed31c12876ab384d0ddd2f6395a64bf3a2f847a4864147b4bb52308cdeef4980","src/cdsl/isa.rs":"201e57e580defead2d1eac82762d629de3882a6bc1c53a9726025a1eef7fd752","src/cdsl/mod.rs":"e0501574efc5d17003496ed3e1cf3cc0a15d80b687dce374f12bc689d6f525b6","src/cdsl/operands.rs":"5217258f2c4911b5be29ca020e9f7460b85182a74d485e027a3bd8336fbf2891","src/cdsl/regs.rs":"b99f24c3ecb46691625dc177b4e18d53e02265bc85a2f827a8d18381fe8f39bb","src/cdsl/settings.rs":"4ddeadf1542cc2ddec0f9e6c22d1637050da519586cd9fec0243c3eab9619f82","src/cdsl/type_inference.rs":"2771631701c150e077c5dcf705c8ae8705944d86ab945ae9e7adc82f3ca5447a","src/cdsl/types.rs":"4cc1f20eb8383fdee6a9e7ca0f7758e563a4fb715056b5edbd4db72f8dfd471b","src/cdsl/typevar.rs":"bd63d403e1ab12130c484100e5bc54b32120f27163a38cee3f546f56b9819325","src/cdsl/xform.rs":"87aeb183ef4282e05c442046df4028d771be63acc3e0250def17cdca7a953477","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_inst.rs":"971104519426da5eebeae2118439e2f7fe011ac0ee54f470f6311a12ae1045b9","src/gen_legalizer.rs":"268e9922f2742c611cace9763d3904f9c113f6869ee9588ed3d19b53f6d57d56","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"77ee330b85a255c49247222f4d071da839b0520eddd3dc561867f7ae84e199ac","src/gen_types.rs":"3935da6c6a53f9332e06f74bc3a46270656b4d4231ad28ed2648d7b1d2774e90","src/isa/arm32/mod.rs":"39c168a2fc979ee1ccaddf303d590f6b50019f1a0733a426c81e9bc5d57ee90c","src/isa/arm64/mod.rs":"335e238ff1a61026c88c11b55585030960c3938cccf901ffb7d1ce3c0fa6db41","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/mod.rs":"21bb24fd01d529e981948eacbeea09f7a780df985280aca4a6ed46381e04e374","src/isa/x86/instructions.rs":"bd6b02ccc79984ed4a5615ae3b20a60a4da3777495b72f771762a886f87d2335","src/isa/x86/legalize.rs":"67316297edffbb2bdf0b19ff353a634f1f609a60bd2858410c9140ad0d7ca2bf","src/isa/x86/mod.rs":"ca6fbf1e9f97ee5fe8c180521a0d5cd7758c0aa1a6c9bfb741cdaf71147a1919","src/lib.rs":"614ca19320a968db23ddcae1eb401763b9fd2e7812fe70e8b227c890f87dc7d9","src/shared/entities.rs":"e7a44d5f621d726479c3812384e78dd25e8c063d074c64d0908b3667e7d28af1","src/shared/formats.rs":"20908b1048c5e71a185de6b6ded79cdff2c26ddb38ba7b134b7a27f37e8324f3","src/shared/immediates.rs":"ac3653ce7f83372833136d28e1809d23b1dc65e7de29ffa26b5e381fcb94d25b","src/shared/instructions.rs":"2a0993279b3529b2c31aa8e83589636104a005351463ec2d3b81b5ffe569d276","src/shared/legalize.rs":"6fc4bebca916bf68b3289f4750ed11148365181b04d497d1d1c1913db7a6fe19","src/shared/mod.rs":"7029cb0c5f7ad59cb2a7ea5f8b91b0fbb363d0704df208dcf8c069da6bfa4c13","src/shared/settings.rs":"bad2dc0e1d71ee6fec6418aa79234296aa918e499a1671c3e5c1d4b0d84b6f49","src/shared/types.rs":"158d73840185e6aa8385463bbf6568efdda0c8de8284cf6b4e565f425ec5d921","src/srcgen.rs":"79fee2f603b33f76f7c9c8b9452c745a363d732c40c0814d84001ff3ef805677","src/unique_table.rs":"90b7203b29241a1ede70f0a3e50d96799e0b41d8f7455170d6ffb127f87f3cc3"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"253c80832ab598570d604ae8a8108ea9835b8eef8d9b9645408ed025ce3b574a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/formats.rs":"98ab61698ad4c1fb81541b1820bd1c1561810bdcff2796dec541c98b4b1901d7","src/cdsl/inst.rs":"d5130c1a36a4e33d1374f9867119c3f2d79c384f12afc12e7b7b4518cf1f74b3","src/cdsl/isa.rs":"dd52d35fa963494b7da892a4a04a4f9978079bb2d86c6af4273a8dfdb82bdf51","src/cdsl/mod.rs":"2d2e216f8c3a81978a5113213559a5ab659bc112b6194cbe08a752313aad7f46","src/cdsl/operands.rs":"cc579fd543e36cf8e82938db331c145b77e29855ee2aa8c5dd949678f980796d","src/cdsl/regs.rs":"b99f24c3ecb46691625dc177b4e18d53e02265bc85a2f827a8d18381fe8f39bb","src/cdsl/settings.rs":"4ddeadf1542cc2ddec0f9e6c22d1637050da519586cd9fec0243c3eab9619f82","src/cdsl/type_inference.rs":"8aedb2e99dee299abbc327ce3a604d48f161580776225d2438a54bbec5b725fe","src/cdsl/types.rs":"4cc1f20eb8383fdee6a9e7ca0f7758e563a4fb715056b5edbd4db72f8dfd471b","src/cdsl/typevar.rs":"605786e2bf367879da500327fc003a4d2a663259c2dee76c87e5b99b6f6331ee","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_inst.rs":"795d30588a5e87e69f3510606c9aee1b8670d5aee5f3d54067f6c7508a67e565","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"77ee330b85a255c49247222f4d071da839b0520eddd3dc561867f7ae84e199ac","src/gen_types.rs":"3935da6c6a53f9332e06f74bc3a46270656b4d4231ad28ed2648d7b1d2774e90","src/isa/arm32/mod.rs":"6ed3be790b28d3115421be282a06b8c376295e1776c4b77243443799015ab70d","src/isa/arm64/mod.rs":"5c46082f68c958e83ffc636de893e2ff49fd8ce21ef357f359837ca48a60eaa5","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/mod.rs":"785f0da2b04458793cb2d493c5e1eeb7ea339bc721df76dda69db3b49bcdfd27","src/isa/x86/instructions.rs":"bd6b02ccc79984ed4a5615ae3b20a60a4da3777495b72f771762a886f87d2335","src/isa/x86/mod.rs":"ba7c11aedb190f58432226a6dec8a125b385cc18fd2f70c46703d077904a3112","src/lib.rs":"99aec646c7b756c01544a181e9b56ba14fccfb2bce205a8c1f63fb31905630ca","src/shared/entities.rs":"e7a44d5f621d726479c3812384e78dd25e8c063d074c64d0908b3667e7d28af1","src/shared/formats.rs":"20908b1048c5e71a185de6b6ded79cdff2c26ddb38ba7b134b7a27f37e8324f3","src/shared/immediates.rs":"1e64836f82045d05da7c151e60cf1e66666af3e0c19179de3f37e72dc81e1bbd","src/shared/instructions.rs":"2a0993279b3529b2c31aa8e83589636104a005351463ec2d3b81b5ffe569d276","src/shared/mod.rs":"696c166d3c19bd84604583a7b8d7ec4f6671622ed581bfce8bee375d02067cbe","src/shared/settings.rs":"bad2dc0e1d71ee6fec6418aa79234296aa918e499a1671c3e5c1d4b0d84b6f49","src/shared/types.rs":"158d73840185e6aa8385463bbf6568efdda0c8de8284cf6b4e565f425ec5d921","src/srcgen.rs":"ad39143ae50f3b19f18a43131bdd3308852c70a9e532cc99f97624e7380b00d8","src/unique_table.rs":"bec9d48ee040216a7c9deab6d2c5050d7ce70e38482cc8957105fd7cbca3c33a"},"package":null}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/ast.rs
+++ /dev/null
@@ -1,653 +0,0 @@
-use crate::cdsl::formats::FormatRegistry;
-use crate::cdsl::inst::{BoundInstruction, Instruction, InstructionPredicate};
-use crate::cdsl::operands::{OperandKind, OperandKindFields};
-use crate::cdsl::types::{LaneType, ValueType};
-use crate::cdsl::typevar::{TypeSetBuilder, TypeVar};
-
-use cranelift_entity::{entity_impl, PrimaryMap};
-
-use std::fmt;
-
-pub enum Expr {
-    Var(VarIndex),
-    Literal(Literal),
-    Apply(Apply),
-}
-
-impl Expr {
-    pub fn maybe_literal(&self) -> Option<&Literal> {
-        match &self {
-            Expr::Literal(lit) => Some(lit),
-            _ => None,
-        }
-    }
-
-    pub fn maybe_var(&self) -> Option<VarIndex> {
-        if let Expr::Var(var) = &self {
-            Some(*var)
-        } else {
-            None
-        }
-    }
-
-    pub fn unwrap_var(&self) -> VarIndex {
-        self.maybe_var()
-            .expect("tried to unwrap a non-Var content in Expr::unwrap_var")
-    }
-
-    pub fn to_rust_code(&self, var_pool: &VarPool) -> String {
-        match self {
-            Expr::Var(var_index) => var_pool.get(*var_index).to_rust_code(),
-            Expr::Literal(literal) => literal.to_rust_code(),
-            Expr::Apply(a) => a.to_rust_code(var_pool),
-        }
-    }
-}
-
-/// An AST definition associates a set of variables with the values produced by an expression.
-pub struct Def {
-    pub apply: Apply,
-    pub defined_vars: Vec<VarIndex>,
-}
-
-impl Def {
-    pub fn to_comment_string(&self, var_pool: &VarPool) -> String {
-        let results = self
-            .defined_vars
-            .iter()
-            .map(|&x| var_pool.get(x).name)
-            .collect::<Vec<_>>();
-
-        let results = if results.len() == 1 {
-            results[0].to_string()
-        } else {
-            format!("({})", results.join(", "))
-        };
-
-        format!("{} << {}", results, self.apply.to_comment_string(var_pool))
-    }
-}
-
-pub struct DefPool {
-    pool: PrimaryMap<DefIndex, Def>,
-}
-
-impl DefPool {
-    pub fn new() -> Self {
-        Self {
-            pool: PrimaryMap::new(),
-        }
-    }
-    pub fn get(&self, index: DefIndex) -> &Def {
-        self.pool.get(index).unwrap()
-    }
-    pub fn get_mut(&mut self, index: DefIndex) -> &mut Def {
-        self.pool.get_mut(index).unwrap()
-    }
-    pub fn next_index(&self) -> DefIndex {
-        self.pool.next_key()
-    }
-    pub fn create(&mut self, apply: Apply, defined_vars: Vec<VarIndex>) -> DefIndex {
-        self.pool.push(Def {
-            apply,
-            defined_vars,
-        })
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct DefIndex(u32);
-entity_impl!(DefIndex);
-
-#[derive(Debug, Clone)]
-enum LiteralValue {
-    /// A value of an enumerated immediate operand.
-    ///
-    /// Some immediate operand kinds like `intcc` and `floatcc` have an enumerated range of values
-    /// corresponding to a Rust enum type. An `Enumerator` object is an AST leaf node representing one
-    /// of the values.
-    Enumerator(&'static str),
-
-    /// A bitwise value of an immediate operand, used for bitwise exact floating point constants.
-    Bits(u64),
-
-    /// A value of an integer immediate operand.
-    Int(i64),
-}
-
-#[derive(Clone)]
-pub struct Literal {
-    kind: OperandKind,
-    value: LiteralValue,
-}
-
-impl fmt::Debug for Literal {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        write!(
-            fmt,
-            "Literal(kind={}, value={:?})",
-            self.kind.name, self.value
-        )
-    }
-}
-
-impl Literal {
-    pub fn enumerator_for(kind: &OperandKind, value: &'static str) -> Self {
-        if let OperandKindFields::ImmEnum(values) = &kind.fields {
-            assert!(
-                values.get(value).is_some(),
-                format!(
-                    "nonexistent value '{}' in enumeration '{}'",
-                    value, kind.name
-                )
-            );
-        } else {
-            panic!("enumerator is for enum values");
-        }
-        Self {
-            kind: kind.clone(),
-            value: LiteralValue::Enumerator(value),
-        }
-    }
-
-    pub fn bits(kind: &OperandKind, bits: u64) -> Self {
-        match kind.fields {
-            OperandKindFields::ImmValue => {}
-            _ => panic!("bits_of is for immediate scalar types"),
-        }
-        Self {
-            kind: kind.clone(),
-            value: LiteralValue::Bits(bits),
-        }
-    }
-
-    pub fn constant(kind: &OperandKind, value: i64) -> Self {
-        match kind.fields {
-            OperandKindFields::ImmValue => {}
-            _ => panic!("bits_of is for immediate scalar types"),
-        }
-        Self {
-            kind: kind.clone(),
-            value: LiteralValue::Int(value),
-        }
-    }
-
-    pub fn to_rust_code(&self) -> String {
-        let maybe_values = match &self.kind.fields {
-            OperandKindFields::ImmEnum(values) => Some(values),
-            OperandKindFields::ImmValue => None,
-            _ => panic!("impossible per construction"),
-        };
-
-        match self.value {
-            LiteralValue::Enumerator(value) => {
-                format!("{}::{}", self.kind.rust_type, maybe_values.unwrap()[value])
-            }
-            LiteralValue::Bits(bits) => format!("{}::with_bits({:#x})", self.kind.rust_type, bits),
-            LiteralValue::Int(val) => val.to_string(),
-        }
-    }
-}
-
-#[derive(Clone, Copy, Debug)]
-pub enum PatternPosition {
-    Source,
-    Destination,
-}
-
-/// A free variable.
-///
-/// When variables are used in `XForms` with source and destination patterns, they are classified
-/// as follows:
-///
-/// Input values: Uses in the source pattern with no preceding def. These may appear as inputs in
-/// the destination pattern too, but no new inputs can be introduced.
-///
-/// Output values: Variables that are defined in both the source and destination pattern.  These
-/// values may have uses outside the source pattern, and the destination pattern must compute the
-/// same value.
-///
-/// Intermediate values: Values that are defined in the source pattern, but not in the destination
-/// pattern. These may have uses outside the source pattern, so the defining instruction can't be
-/// deleted immediately.
-///
-/// Temporary values are defined only in the destination pattern.
-pub struct Var {
-    pub name: &'static str,
-
-    /// The `Def` defining this variable in a source pattern.
-    pub src_def: Option<DefIndex>,
-
-    /// The `Def` defining this variable in a destination pattern.
-    pub dst_def: Option<DefIndex>,
-
-    /// TypeVar representing the type of this variable.
-    type_var: Option<TypeVar>,
-
-    /// Is this the original type variable, or has it be redefined with set_typevar?
-    is_original_type_var: bool,
-}
-
-impl Var {
-    fn new(name: &'static str) -> Self {
-        Self {
-            name,
-            src_def: None,
-            dst_def: None,
-            type_var: None,
-            is_original_type_var: false,
-        }
-    }
-
-    /// Is this an input value to the src pattern?
-    pub fn is_input(&self) -> bool {
-        self.src_def.is_none() && self.dst_def.is_none()
-    }
-
-    /// Is this an output value, defined in both src and dst patterns?
-    pub fn is_output(&self) -> bool {
-        self.src_def.is_some() && self.dst_def.is_some()
-    }
-
-    /// Is this an intermediate value, defined only in the src pattern?
-    pub fn is_intermediate(&self) -> bool {
-        self.src_def.is_some() && self.dst_def.is_none()
-    }
-
-    /// Is this a temp value, defined only in the dst pattern?
-    pub fn is_temp(&self) -> bool {
-        self.src_def.is_none() && self.dst_def.is_some()
-    }
-
-    /// Get the def of this variable according to the position.
-    pub fn get_def(&self, position: PatternPosition) -> Option<DefIndex> {
-        match position {
-            PatternPosition::Source => self.src_def,
-            PatternPosition::Destination => self.dst_def,
-        }
-    }
-
-    pub fn set_def(&mut self, position: PatternPosition, def: DefIndex) {
-        assert!(
-            self.get_def(position).is_none(),
-            format!("redefinition of variable {}", self.name)
-        );
-        match position {
-            PatternPosition::Source => {
-                self.src_def = Some(def);
-            }
-            PatternPosition::Destination => {
-                self.dst_def = Some(def);
-            }
-        }
-    }
-
-    /// Get the type variable representing the type of this variable.
-    pub fn get_or_create_typevar(&mut self) -> TypeVar {
-        match &self.type_var {
-            Some(tv) => tv.clone(),
-            None => {
-                // Create a new type var in which we allow all types.
-                let tv = TypeVar::new(
-                    format!("typeof_{}", self.name),
-                    format!("Type of the pattern variable {:?}", self),
-                    TypeSetBuilder::all(),
-                );
-                self.type_var = Some(tv.clone());
-                self.is_original_type_var = true;
-                tv
-            }
-        }
-    }
-    pub fn get_typevar(&self) -> Option<TypeVar> {
-        self.type_var.clone()
-    }
-    pub fn set_typevar(&mut self, tv: TypeVar) {
-        self.is_original_type_var = if let Some(previous_tv) = &self.type_var {
-            *previous_tv == tv
-        } else {
-            false
-        };
-        self.type_var = Some(tv);
-    }
-
-    /// Check if this variable has a free type variable. If not, the type of this variable is
-    /// computed from the type of another variable.
-    pub fn has_free_typevar(&self) -> bool {
-        match &self.type_var {
-            Some(tv) => tv.base.is_none() && self.is_original_type_var,
-            None => false,
-        }
-    }
-
-    pub fn to_rust_code(&self) -> String {
-        self.name.into()
-    }
-    fn rust_type(&self) -> String {
-        self.type_var.as_ref().unwrap().to_rust_code()
-    }
-}
-
-impl fmt::Debug for Var {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        fmt.write_fmt(format_args!(
-            "Var({}{}{})",
-            self.name,
-            if self.src_def.is_some() { ", src" } else { "" },
-            if self.dst_def.is_some() { ", dst" } else { "" }
-        ))
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct VarIndex(u32);
-entity_impl!(VarIndex);
-
-pub struct VarPool {
-    pool: PrimaryMap<VarIndex, Var>,
-}
-
-impl VarPool {
-    pub fn new() -> Self {
-        Self {
-            pool: PrimaryMap::new(),
-        }
-    }
-    pub fn get(&self, index: VarIndex) -> &Var {
-        self.pool.get(index).unwrap()
-    }
-    pub fn get_mut(&mut self, index: VarIndex) -> &mut Var {
-        self.pool.get_mut(index).unwrap()
-    }
-    pub fn create(&mut self, name: &'static str) -> VarIndex {
-        self.pool.push(Var::new(name))
-    }
-}
-
-pub enum ApplyTarget {
-    Inst(Instruction),
-    Bound(BoundInstruction),
-}
-
-impl ApplyTarget {
-    pub fn inst(&self) -> &Instruction {
-        match &self {
-            ApplyTarget::Inst(inst) => inst,
-            ApplyTarget::Bound(bound_inst) => &bound_inst.inst,
-        }
-    }
-}
-
-impl Into<ApplyTarget> for &Instruction {
-    fn into(self) -> ApplyTarget {
-        ApplyTarget::Inst(self.clone())
-    }
-}
-
-impl Into<ApplyTarget> for BoundInstruction {
-    fn into(self) -> ApplyTarget {
-        ApplyTarget::Bound(self)
-    }
-}
-
-pub fn bind(target: impl Into<ApplyTarget>, lane_type: impl Into<LaneType>) -> BoundInstruction {
-    let value_type = ValueType::from(lane_type.into());
-
-    let (inst, value_types) = match target.into() {
-        ApplyTarget::Inst(inst) => (inst, vec![value_type]),
-        ApplyTarget::Bound(bound_inst) => {
-            let mut new_value_types = bound_inst.value_types;
-            new_value_types.push(value_type);
-            (bound_inst.inst, new_value_types)
-        }
-    };
-
-    match &inst.polymorphic_info {
-        Some(poly) => {
-            assert!(
-                value_types.len() <= 1 + poly.other_typevars.len(),
-                format!("trying to bind too many types for {}", inst.name)
-            );
-        }
-        None => {
-            panic!(format!(
-                "trying to bind a type for {} which is not a polymorphic instruction",
-                inst.name
-            ));
-        }
-    }
-
-    BoundInstruction { inst, value_types }
-}
-
-/// Apply an instruction to arguments.
-///
-/// An `Apply` AST expression is created by using function call syntax on instructions. This
-/// applies to both bound and unbound polymorphic instructions.
-pub struct Apply {
-    pub inst: Instruction,
-    pub args: Vec<Expr>,
-    pub value_types: Vec<ValueType>,
-}
-
-impl Apply {
-    pub fn new(target: ApplyTarget, args: Vec<Expr>) -> Self {
-        let (inst, value_types) = match target.into() {
-            ApplyTarget::Inst(inst) => (inst, Vec::new()),
-            ApplyTarget::Bound(bound_inst) => (bound_inst.inst, bound_inst.value_types),
-        };
-
-        // Basic check on number of arguments.
-        assert!(
-            inst.operands_in.len() == args.len(),
-            format!("incorrect number of arguments in instruction {}", inst.name)
-        );
-
-        // Check that the kinds of Literals arguments match the expected operand.
-        for &imm_index in &inst.imm_opnums {
-            let arg = &args[imm_index];
-            if let Some(literal) = arg.maybe_literal() {
-                let op = &inst.operands_in[imm_index];
-                assert!(
-                    op.kind.name == literal.kind.name,
-                    format!(
-                        "Passing literal of kind {} to field of wrong kind {}",
-                        literal.kind.name, op.kind.name
-                    )
-                );
-            }
-        }
-
-        Self {
-            inst,
-            args,
-            value_types,
-        }
-    }
-
-    fn to_comment_string(&self, var_pool: &VarPool) -> String {
-        let args = self
-            .args
-            .iter()
-            .map(|arg| arg.to_rust_code(var_pool))
-            .collect::<Vec<_>>()
-            .join(", ");
-
-        let mut inst_and_bound_types = vec![self.inst.name.to_string()];
-        inst_and_bound_types.extend(self.value_types.iter().map(|vt| vt.to_string()));
-        let inst_name = inst_and_bound_types.join(".");
-
-        format!("{}({})", inst_name, args)
-    }
-
-    fn to_rust_code(&self, var_pool: &VarPool) -> String {
-        let args = self
-            .args
-            .iter()
-            .map(|arg| arg.to_rust_code(var_pool))
-            .collect::<Vec<_>>()
-            .join(", ");
-        format!("{}({})", self.inst.name, args)
-    }
-
-    fn inst_predicate(
-        &self,
-        format_registry: &FormatRegistry,
-        var_pool: &VarPool,
-    ) -> InstructionPredicate {
-        let iform = format_registry.get(self.inst.format);
-
-        let mut pred = InstructionPredicate::new();
-        for (format_field, &op_num) in iform.imm_fields.iter().zip(self.inst.imm_opnums.iter()) {
-            let arg = &self.args[op_num];
-            if arg.maybe_var().is_some() {
-                // Ignore free variables for now.
-                continue;
-            }
-            pred = pred.and(InstructionPredicate::new_is_field_equal(
-                &format_field,
-                arg.to_rust_code(var_pool),
-            ));
-        }
-
-        // Add checks for any bound secondary type variables.  We can't check the controlling type
-        // variable this way since it may not appear as the type of an operand.
-        if self.value_types.len() > 1 {
-            let poly = self
-                .inst
-                .polymorphic_info
-                .as_ref()
-                .expect("must have polymorphic info if it has bounded types");
-            for (bound_type, type_var) in
-                self.value_types[1..].iter().zip(poly.other_typevars.iter())
-            {
-                pred = pred.and(InstructionPredicate::new_typevar_check(
-                    &self.inst, type_var, bound_type,
-                ));
-            }
-        }
-
-        pred
-    }
-
-    /// Same as `inst_predicate()`, but also check the controlling type variable.
-    pub fn inst_predicate_with_ctrl_typevar(
-        &self,
-        format_registry: &FormatRegistry,
-        var_pool: &VarPool,
-    ) -> InstructionPredicate {
-        let mut pred = self.inst_predicate(format_registry, var_pool);
-
-        if !self.value_types.is_empty() {
-            let bound_type = &self.value_types[0];
-            let poly = self.inst.polymorphic_info.as_ref().unwrap();
-            let type_check = if poly.use_typevar_operand {
-                InstructionPredicate::new_typevar_check(&self.inst, &poly.ctrl_typevar, bound_type)
-            } else {
-                InstructionPredicate::new_ctrl_typevar_check(&bound_type)
-            };
-            pred = pred.and(type_check);
-        }
-
-        pred
-    }
-
-    pub fn rust_builder(&self, defined_vars: &Vec<VarIndex>, var_pool: &VarPool) -> String {
-        let mut args = self
-            .args
-            .iter()
-            .map(|expr| expr.to_rust_code(var_pool))
-            .collect::<Vec<_>>()
-            .join(", ");
-
-        // Do we need to pass an explicit type argument?
-        if let Some(poly) = &self.inst.polymorphic_info {
-            if !poly.use_typevar_operand {
-                args = format!("{}, {}", var_pool.get(defined_vars[0]).rust_type(), args);
-            }
-        }
-
-        format!("{}({})", self.inst.snake_name(), args)
-    }
-}
-
-// Simple helpers for legalize actions construction.
-
-pub enum DummyExpr {
-    Var(DummyVar),
-    Literal(Literal),
-    Apply(ApplyTarget, Vec<DummyExpr>),
-}
-
-#[derive(Clone)]
-pub struct DummyVar {
-    pub name: &'static str,
-}
-
-impl Into<DummyExpr> for DummyVar {
-    fn into(self) -> DummyExpr {
-        DummyExpr::Var(self)
-    }
-}
-impl Into<DummyExpr> for Literal {
-    fn into(self) -> DummyExpr {
-        DummyExpr::Literal(self)
-    }
-}
-
-pub fn var(name: &'static str) -> DummyVar {
-    DummyVar { name }
-}
-
-pub struct DummyDef {
-    pub expr: DummyExpr,
-    pub defined_vars: Vec<DummyVar>,
-}
-
-pub struct ExprBuilder {
-    expr: DummyExpr,
-}
-
-impl ExprBuilder {
-    pub fn apply(inst: ApplyTarget, args: Vec<DummyExpr>) -> Self {
-        let expr = DummyExpr::Apply(inst, args);
-        Self { expr }
-    }
-
-    pub fn assign_to(self, defined_vars: Vec<DummyVar>) -> DummyDef {
-        DummyDef {
-            expr: self.expr,
-            defined_vars,
-        }
-    }
-}
-
-macro_rules! def_rhs {
-    // inst(a, b, c)
-    ($inst:ident($($src:expr),*)) => {
-        ExprBuilder::apply($inst.into(), vec![$($src.clone().into()),*])
-    };
-
-    // inst.type(a, b, c)
-    ($inst:ident.$type:ident($($src:expr),*)) => {
-        ExprBuilder::apply(bind($inst, $type).into(), vec![$($src.clone().into()),*])
-    };
-}
-
-// Helper macro to define legalization recipes.
-macro_rules! def {
-    // x = ...
-    ($dest:ident = $($tt:tt)*) => {
-        def_rhs!($($tt)*).assign_to(vec![$dest.clone()])
-    };
-
-    // (x, y, ...) = ...
-    (($($dest:ident),*) = $($tt:tt)*) => {
-        def_rhs!($($tt)*).assign_to(vec![$($dest.clone()),*])
-    };
-
-    // An instruction with no results.
-    ($($tt:tt)*) => {
-        def_rhs!($($tt)*).assign_to(Vec::new())
-    }
-}
deleted file mode 100644
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/cpu_modes.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use crate::cdsl::types::LaneType;
-use crate::cdsl::xform::{TransformGroup, TransformGroupIndex, TransformGroups};
-
-use std::collections::{HashMap, HashSet};
-use std::iter::FromIterator;
-
-pub struct CpuMode {
-    _name: &'static str,
-    default_legalize: Option<TransformGroupIndex>,
-    monomorphic_legalize: Option<TransformGroupIndex>,
-    typed_legalize: HashMap<String, TransformGroupIndex>,
-}
-
-impl CpuMode {
-    pub fn new(name: &'static str) -> Self {
-        Self {
-            _name: name,
-            default_legalize: None,
-            monomorphic_legalize: None,
-            typed_legalize: HashMap::new(),
-        }
-    }
-    pub fn legalize_monomorphic(&mut self, group: &TransformGroup) {
-        assert!(self.monomorphic_legalize.is_none());
-        self.monomorphic_legalize = Some(group.id);
-    }
-    pub fn legalize_default(&mut self, group: &TransformGroup) {
-        assert!(self.default_legalize.is_none());
-        self.default_legalize = Some(group.id);
-    }
-    pub fn legalize_type(&mut self, lane_type: impl Into<LaneType>, group: &TransformGroup) {
-        assert!(self
-            .typed_legalize
-            .insert(lane_type.into().to_string(), group.id)
-            .is_none());
-    }
-
-    /// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the
-    /// transitive set of TransformGroup this TargetIsa uses.
-    pub fn transitive_transform_groups(
-        &self,
-        all_groups: &TransformGroups,
-    ) -> Vec<TransformGroupIndex> {
-        let mut roots = Vec::new();
-        if let Some(i) = &self.default_legalize {
-            roots.push(*i);
-        }
-        if let Some(i) = &self.monomorphic_legalize {
-            roots.push(*i);
-        }
-        roots.extend(self.typed_legalize.values().cloned());
-
-        let mut set = HashSet::new();
-        for root in roots {
-            set.insert(root);
-            let mut base = root;
-            // Follow the chain of chain_with.
-            while let Some(chain_with) = &all_groups.get(base).chain_with {
-                set.insert(*chain_with);
-                base = *chain_with;
-            }
-        }
-
-        let mut ret = Vec::from_iter(set);
-        ret.sort();
-        ret
-    }
-
-    /// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly
-    /// reachable set of TransformGroup this TargetIsa uses.
-    pub fn direct_transform_groups(&self) -> Vec<TransformGroupIndex> {
-        let mut set = HashSet::new();
-        if let Some(i) = &self.default_legalize {
-            set.insert(*i);
-        }
-        if let Some(i) = &self.monomorphic_legalize {
-            set.insert(*i);
-        }
-        set.extend(self.typed_legalize.values().cloned());
-        let mut ret = Vec::from_iter(set);
-        ret.sort();
-        ret
-    }
-}
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/formats.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/formats.rs
@@ -5,54 +5,61 @@ use std::fmt;
 use std::slice;
 
 use cranelift_entity::{entity_impl, PrimaryMap};
 
 /// An immediate field in an instruction format.
 ///
 /// This corresponds to a single member of a variant of the `InstructionData`
 /// data type.
+///
+/// :param iform: Parent `InstructionFormat`.
+/// :param kind: Immediate Operand kind.
+/// :param member: Member name in `InstructionData` variant.
 #[derive(Debug)]
 pub struct FormatField {
     /// Immediate operand number in parent.
     immnum: usize,
 
     /// Immediate operand kind.
     pub kind: OperandKind,
 
-    /// Member name in InstructionData variant.
+    /// Member name in InstructionDate variant.
     pub member: &'static str,
 }
 
-/// Every instruction opcode has a corresponding instruction format which determines the number of
-/// operands and their kinds. Instruction formats are identified structurally, i.e., the format of
-/// an instruction is derived from the kinds of operands used in its declaration.
+/// Every instruction opcode has a corresponding instruction format which
+/// determines the number of operands and their kinds. Instruction formats are
+/// identified structurally, i.e., the format of an instruction is derived from
+/// the kinds of operands used in its declaration.
 ///
-/// The instruction format stores two separate lists of operands: Immediates and values. Immediate
-/// operands (including entity references) are represented as explicit members in the
-/// `InstructionData` variants. The value operands are stored differently, depending on how many
-/// there are.  Beyond a certain point, instruction formats switch to an external value list for
-/// storing value arguments. Value lists can hold an arbitrary number of values.
+/// The instruction format stores two separate lists of operands: Immediates
+/// and values. Immediate operands (including entity references) are
+/// represented as explicit members in the `InstructionData` variants. The
+/// value operands are stored differently, depending on how many there are.
+/// Beyond a certain point, instruction formats switch to an external value
+/// list for storing value arguments. Value lists can hold an arbitrary number
+/// of values.
 ///
-/// All instruction formats must be predefined in the meta shared/formats.rs module.
+/// All instruction formats must be predefined in the meta shared/formats module.
+///
+/// :param kinds: List of `OperandKind` objects describing the operands.
+/// :param name: Instruction format name in CamelCase. This is used as a Rust
+///     variant name in both the `InstructionData` and `InstructionFormat`
+///     enums.
+/// :param typevar_operand: Index of the value input operand that is used to
+///     infer the controlling type variable. By default, this is `0`, the first
+///     `value` operand. The index is relative to the values only, ignoring
+///     immediate operands.
 #[derive(Debug)]
 pub struct InstructionFormat {
-    /// Instruction format name in CamelCase. This is used as a Rust variant name in both the
-    /// `InstructionData` and `InstructionFormat` enums.
     pub name: &'static str,
-
     pub num_value_operands: usize,
-
     pub has_value_list: bool,
-
     pub imm_fields: Vec<FormatField>,
-
-    /// Index of the value input operand that is used to infer the controlling type variable. By
-    /// default, this is `0`, the first `value` operand. The index is relative to the values only,
-    /// ignoring immediate operands.
     pub typevar_operand: Option<usize>,
 }
 
 impl fmt::Display for InstructionFormat {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         let args = self
             .imm_fields
             .iter()
@@ -150,17 +157,17 @@ impl InstructionFormatBuilder {
             num_value_operands: self.num_value_operands,
             has_value_list: self.has_value_list,
             imm_fields: self.imm_fields,
             typevar_operand,
         }
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct InstructionFormatIndex(u32);
 entity_impl!(InstructionFormatIndex);
 
 pub struct FormatRegistry {
     /// Map (immediate kinds names, number of values, has varargs) to an instruction format index
     /// in the actual map.
     sig_to_index: HashMap<(Vec<String>, usize, bool), InstructionFormatIndex>,
     map: PrimaryMap<InstructionFormatIndex, InstructionFormat>,
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/inst.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/inst.rs
@@ -1,20 +1,15 @@
 use crate::cdsl::camel_case;
-use crate::cdsl::formats::{
-    FormatField, FormatRegistry, InstructionFormat, InstructionFormatIndex,
-};
+use crate::cdsl::formats::{FormatRegistry, InstructionFormat, InstructionFormatIndex};
 use crate::cdsl::operands::Operand;
 use crate::cdsl::type_inference::Constraint;
-use crate::cdsl::types::ValueType;
 use crate::cdsl::typevar::TypeVar;
 
 use std::fmt;
-use std::ops;
-use std::rc::Rc;
 use std::slice;
 
 /// Every instruction must belong to exactly one instruction group. A given
 /// target architecture can support instructions from multiple groups, and it
 /// does not necessarily support all instructions in a group.
 pub struct InstructionGroup {
     _name: &'static str,
     _doc: &'static str,
@@ -32,45 +27,38 @@ impl InstructionGroup {
 
     pub fn push(&mut self, inst: Instruction) {
         self.instructions.push(inst);
     }
 
     pub fn iter(&self) -> slice::Iter<Instruction> {
         self.instructions.iter()
     }
-
-    pub fn by_name(&self, name: &'static str) -> &Instruction {
-        self.instructions
-            .iter()
-            .find(|inst| inst.name == name)
-            .expect(&format!("unexisting instruction with name {}", name))
-    }
 }
 
 pub struct PolymorphicInfo {
     pub use_typevar_operand: bool,
     pub ctrl_typevar: TypeVar,
     pub other_typevars: Vec<TypeVar>,
 }
 
-pub struct InstructionContent {
+pub struct Instruction {
     /// Instruction mnemonic, also becomes opcode name.
     pub name: &'static str,
     pub camel_name: String,
 
     /// Documentation string.
     doc: &'static str,
 
     /// Input operands. This can be a mix of SSA value operands and other operand kinds.
     pub operands_in: Vec<Operand>,
     /// Output operands. The output operands must be SSA values or `variable_args`.
     pub operands_out: Vec<Operand>,
     /// Instruction-specific TypeConstraints.
-    pub constraints: Vec<Constraint>,
+    _constraints: Vec<Constraint>,
 
     /// Instruction format, automatically derived from the input operands.
     pub format: InstructionFormatIndex,
 
     /// One of the input or output operands is a free type variable. None if the instruction is not
     /// polymorphic, set otherwise.
     pub polymorphic_info: Option<PolymorphicInfo>,
 
@@ -97,28 +85,16 @@ pub struct InstructionContent {
     /// Can this instruction cause a trap?
     pub can_trap: bool,
     /// Does this instruction have other side effects besides can_* flags?
     pub other_side_effects: bool,
     /// Does this instruction write to CPU flags?
     pub writes_cpu_flags: bool,
 }
 
-#[derive(Clone)]
-pub struct Instruction {
-    content: Rc<InstructionContent>,
-}
-
-impl ops::Deref for Instruction {
-    type Target = InstructionContent;
-    fn deref(&self) -> &Self::Target {
-        &*self.content
-    }
-}
-
 impl Instruction {
     pub fn snake_name(&self) -> &'static str {
         if self.name == "return" {
             "return_"
         } else {
             self.name
         }
     }
@@ -127,27 +103,16 @@ impl Instruction {
         for line in self.doc.split("\n") {
             let stripped = line.trim();
             if stripped.len() > 0 {
                 return stripped;
             }
         }
         ""
     }
-
-    pub fn all_typevars(&self) -> Vec<&TypeVar> {
-        match &self.polymorphic_info {
-            Some(poly) => {
-                let mut result = vec![&poly.ctrl_typevar];
-                result.extend(&poly.other_typevars);
-                result
-            }
-            None => Vec::new(),
-        }
-    }
 }
 
 impl fmt::Display for Instruction {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
         if self.operands_out.len() > 0 {
             let operands_out = self
                 .operands_out
                 .iter()
@@ -302,50 +267,42 @@ impl InstructionBuilder {
         let format = format_registry.get(format_index);
         let polymorphic_info =
             verify_polymorphic(&operands_in, &operands_out, &format, &value_opnums);
 
         // Infer from output operands whether an instruciton clobbers CPU flags or not.
         let writes_cpu_flags = operands_out.iter().any(|op| op.is_cpu_flags());
 
         Instruction {
-            content: Rc::new(InstructionContent {
-                name: self.name,
-                camel_name: camel_case(self.name),
-                doc: self.doc,
-                operands_in,
-                operands_out,
-                constraints: self.constraints.unwrap_or_else(Vec::new),
-                format: format_index,
-                polymorphic_info,
-                value_opnums,
-                value_results,
-                imm_opnums,
-                is_terminator: self.is_terminator,
-                is_branch: self.is_branch,
-                is_indirect_branch: self.is_indirect_branch,
-                is_call: self.is_call,
-                is_return: self.is_return,
-                is_ghost: self.is_ghost,
-                can_load: self.can_load,
-                can_store: self.can_store,
-                can_trap: self.can_trap,
-                other_side_effects: self.other_side_effects,
-                writes_cpu_flags,
-            }),
+            name: self.name,
+            camel_name: camel_case(self.name),
+            doc: self.doc,
+            operands_in,
+            operands_out,
+            _constraints: self.constraints.unwrap_or_else(Vec::new),
+            format: format_index,
+            polymorphic_info,
+            value_opnums,
+            value_results,
+            imm_opnums,
+            is_terminator: self.is_terminator,
+            is_branch: self.is_branch,
+            is_indirect_branch: self.is_indirect_branch,
+            is_call: self.is_call,
+            is_return: self.is_return,
+            is_ghost: self.is_ghost,
+            can_load: self.can_load,
+            can_store: self.can_store,
+            can_trap: self.can_trap,
+            other_side_effects: self.other_side_effects,
+            writes_cpu_flags,
         }
     }
 }
 
-#[derive(Clone)]
-pub struct BoundInstruction {
-    pub inst: Instruction,
-    pub value_types: Vec<ValueType>,
-}
-
 /// Check if this instruction is polymorphic, and verify its use of type variables.
 fn verify_polymorphic(
     operands_in: &Vec<Operand>,
     operands_out: &Vec<Operand>,
     format: &InstructionFormat,
     value_opnums: &Vec<usize>,
 ) -> Option<PolymorphicInfo> {
     // The instruction is polymorphic if it has one free input or output operand.
@@ -494,107 +451,8 @@ fn verify_ctrl_typevar(
             continue;
         }
 
         return Err("type variable in output not derived from ctrl_typevar".into());
     }
 
     Ok(other_typevars)
 }
-
-/// A basic node in an instruction predicate: either an atom, or an AND of two conditions.
-pub enum InstructionPredicateNode {
-    /// Is the field member (first member) equal to the actual argument (which name is the second
-    /// field)?
-    IsFieldEqual(String, String),
-
-    /// Is the value argument (at the index designated by the first member) the same type as the
-    /// type name (second member)?
-    TypeVarCheck(usize, String),
-
-    /// Is the controlling type variable the same type as the one designated by the type name
-    /// (only member)?
-    CtrlTypeVarCheck(String),
-
-    /// A combination of two other predicates.
-    And(Vec<InstructionPredicateNode>),
-}
-
-impl InstructionPredicateNode {
-    fn rust_predicate(&self) -> String {
-        match self {
-            InstructionPredicateNode::IsFieldEqual(field_name, arg) => {
-                let new_args = vec![field_name.clone(), arg.clone()];
-                format!("crate::predicates::is_equal({})", new_args.join(", "))
-            }
-            InstructionPredicateNode::TypeVarCheck(index, value_type_name) => format!(
-                "func.dfg.value_type(args[{}]) == {}",
-                index, value_type_name
-            ),
-            InstructionPredicateNode::CtrlTypeVarCheck(value_type_name) => {
-                format!("func.dfg.ctrl_typevar(inst) == {}", value_type_name)
-            }
-            InstructionPredicateNode::And(nodes) => nodes
-                .iter()
-                .map(|x| x.rust_predicate())
-                .collect::<Vec<_>>()
-                .join(" &&\n"),
-        }
-    }
-}
-
-pub struct InstructionPredicate {
-    node: Option<InstructionPredicateNode>,
-}
-
-impl InstructionPredicate {
-    pub fn new() -> Self {
-        Self { node: None }
-    }
-
-    pub fn new_typevar_check(
-        inst: &Instruction,
-        type_var: &TypeVar,
-        value_type: &ValueType,
-    ) -> InstructionPredicateNode {
-        let index = inst
-            .value_opnums
-            .iter()
-            .enumerate()
-            .filter(|(_, &op_num)| inst.operands_in[op_num].type_var().unwrap() == type_var)
-            .next()
-            .unwrap()
-            .0;
-        InstructionPredicateNode::TypeVarCheck(index, value_type.rust_name())
-    }
-
-    pub fn new_is_field_equal(
-        format_field: &FormatField,
-        imm_value: String,
-    ) -> InstructionPredicateNode {
-        InstructionPredicateNode::IsFieldEqual(format_field.member.into(), imm_value)
-    }
-
-    pub fn new_ctrl_typevar_check(value_type: &ValueType) -> InstructionPredicateNode {
-        InstructionPredicateNode::CtrlTypeVarCheck(value_type.rust_name())
-    }
-
-    pub fn and(mut self, new_node: InstructionPredicateNode) -> Self {
-        let node = self.node;
-        let mut and_nodes = match node {
-            Some(node) => match node {
-                InstructionPredicateNode::And(nodes) => nodes,
-                _ => vec![node],
-            },
-            _ => Vec::new(),
-        };
-        and_nodes.push(new_node);
-        self.node = Some(InstructionPredicateNode::And(and_nodes));
-        self
-    }
-
-    pub fn rust_predicate(&self) -> String {
-        match &self.node {
-            Some(root) => root.rust_predicate(),
-            None => "true".into(),
-        }
-    }
-}
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/isa.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/isa.rs
@@ -1,61 +1,26 @@
-use crate::cdsl::cpu_modes::CpuMode;
 use crate::cdsl::inst::InstructionGroup;
 use crate::cdsl::regs::IsaRegs;
 use crate::cdsl::settings::SettingGroup;
-use crate::cdsl::xform::{TransformGroupIndex, TransformGroups};
-
-use std::collections::HashSet;
-use std::iter::FromIterator;
 
 pub struct TargetIsa {
     pub name: &'static str,
     pub instructions: InstructionGroup,
     pub settings: SettingGroup,
     pub regs: IsaRegs,
-    pub cpu_modes: Vec<CpuMode>,
 }
 
 impl TargetIsa {
     pub fn new(
         name: &'static str,
         instructions: InstructionGroup,
         settings: SettingGroup,
         regs: IsaRegs,
-        cpu_modes: Vec<CpuMode>,
     ) -> Self {
         Self {
             name,
             instructions,
             settings,
             regs,
-            cpu_modes,
         }
     }
-
-    /// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the
-    /// transitive set of TransformGroup this TargetIsa uses.
-    pub fn transitive_transform_groups(
-        &self,
-        all_groups: &TransformGroups,
-    ) -> Vec<TransformGroupIndex> {
-        let mut set = HashSet::new();
-        for cpu_mode in &self.cpu_modes {
-            set.extend(cpu_mode.transitive_transform_groups(all_groups));
-        }
-        let mut vec = Vec::from_iter(set);
-        vec.sort();
-        vec
-    }
-
-    /// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly
-    /// reachable set of TransformGroup this TargetIsa uses.
-    pub fn direct_transform_groups(&self) -> Vec<TransformGroupIndex> {
-        let mut set = HashSet::new();
-        for cpu_mode in &self.cpu_modes {
-            set.extend(cpu_mode.direct_transform_groups());
-        }
-        let mut vec = Vec::from_iter(set);
-        vec.sort();
-        vec
-    }
 }
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/mod.rs
@@ -1,26 +1,22 @@
 //! Cranelift DSL classes.
 //!
 //! This module defines the classes that are used to define Cranelift
 //! instructions and other entities.
 
-#[macro_use]
-pub mod ast;
-pub mod cpu_modes;
 pub mod formats;
 pub mod inst;
 pub mod isa;
 pub mod operands;
 pub mod regs;
 pub mod settings;
 pub mod type_inference;
 pub mod types;
 pub mod typevar;
-pub mod xform;
 
 /// A macro that converts boolean settings into predicates to look more natural.
 #[macro_export]
 macro_rules! predicate {
     ($a:ident && $($b:tt)*) => {
         PredicateNode::And(Box::new($a.into()), Box::new(predicate!($($b)*)))
     };
     ($a:ident) => {
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/operands.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/operands.rs
@@ -129,17 +129,17 @@ pub struct OperandKind {
 
     doc: Option<String>,
 
     pub default_member: Option<&'static str>,
 
     /// The camel-cased name of an operand kind is also the Rust type used to represent it.
     pub rust_type: String,
 
-    pub fields: OperandKindFields,
+    fields: OperandKindFields,
 }
 
 impl OperandKind {
     pub fn imm_key(&self) -> Option<String> {
         match self.fields {
             OperandKindFields::ImmEnum(_)
             | OperandKindFields::ImmValue
             | OperandKindFields::EntityRef => Some(self.name.to_string()),
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/type_inference.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/type_inference.rs
@@ -1,658 +1,5 @@
-use crate::cdsl::ast::{Def, DefIndex, DefPool, Var, VarIndex, VarPool};
-use crate::cdsl::typevar::{DerivedFunc, TypeSet, TypeVar};
-
-use std::collections::{HashMap, HashSet};
-use std::iter::FromIterator;
-
-#[derive(Hash, PartialEq, Eq)]
-pub enum Constraint {
-    /// Constraint specifying that a type var tv1 must be wider than or equal to type var tv2 at
-    /// runtime. This requires that:
-    /// 1) They have the same number of lanes
-    /// 2) In a lane tv1 has at least as many bits as tv2.
-    WiderOrEq(TypeVar, TypeVar),
-
-    /// Constraint specifying that two derived type vars must have the same runtime type.
-    Eq(TypeVar, TypeVar),
-
-    /// Constraint specifying that a type var must belong to some typeset.
-    InTypeset(TypeVar, TypeSet),
-}
-
-impl Constraint {
-    fn translate_with<F: Fn(&TypeVar) -> TypeVar>(&self, func: F) -> Constraint {
-        match self {
-            Constraint::WiderOrEq(lhs, rhs) => {
-                let lhs = func(&lhs);
-                let rhs = func(&rhs);
-                Constraint::WiderOrEq(lhs, rhs)
-            }
-            Constraint::Eq(lhs, rhs) => {
-                let lhs = func(&lhs);
-                let rhs = func(&rhs);
-                Constraint::Eq(lhs, rhs)
-            }
-            Constraint::InTypeset(tv, ts) => {
-                let tv = func(&tv);
-                Constraint::InTypeset(tv, ts.clone())
-            }
-        }
-    }
-
-    /// Creates a new constraint by replacing type vars by their hashmap equivalent.
-    fn translate_with_map(
-        &self,
-        original_to_own_typevar: &HashMap<&TypeVar, TypeVar>,
-    ) -> Constraint {
-        self.translate_with(|tv| substitute(original_to_own_typevar, tv))
-    }
-
-    /// Creates a new constraint by replacing type vars by their canonical equivalent.
-    fn translate_with_env(&self, type_env: &TypeEnvironment) -> Constraint {
-        self.translate_with(|tv| type_env.get_equivalent(tv))
-    }
-
-    fn is_trivial(&self) -> bool {
-        match self {
-            Constraint::WiderOrEq(lhs, rhs) => {
-                // Trivially true.
-                if lhs == rhs {
-                    return true;
-                }
-
-                let ts1 = lhs.get_typeset();
-                let ts2 = rhs.get_typeset();
-
-                // Trivially true.
-                if ts1.is_wider_or_equal(&ts2) {
-                    return true;
-                }
-
-                // Trivially false.
-                if ts1.is_narrower(&ts2) {
-                    return true;
-                }
-
-                // Trivially false.
-                if (&ts1.lanes & &ts2.lanes).len() == 0 {
-                    return true;
-                }
-
-                self.is_concrete()
-            }
-            Constraint::Eq(lhs, rhs) => lhs == rhs || self.is_concrete(),
-            Constraint::InTypeset(_, _) => {
-                // The way InTypeset are made, they would always be trivial if we were applying the
-                // same logic as the Python code did, so ignore this.
-                self.is_concrete()
-            }
-        }
-    }
-
-    /// Returns true iff all the referenced type vars are singletons.
-    fn is_concrete(&self) -> bool {
-        match self {
-            Constraint::WiderOrEq(lhs, rhs) => {
-                lhs.singleton_type().is_some() && rhs.singleton_type().is_some()
-            }
-            Constraint::Eq(lhs, rhs) => {
-                lhs.singleton_type().is_some() && rhs.singleton_type().is_some()
-            }
-            Constraint::InTypeset(tv, _) => tv.singleton_type().is_some(),
-        }
-    }
-
-    fn typevar_args(&self) -> Vec<&TypeVar> {
-        match self {
-            Constraint::WiderOrEq(lhs, rhs) => vec![lhs, rhs],
-            Constraint::Eq(lhs, rhs) => vec![lhs, rhs],
-            Constraint::InTypeset(tv, _) => vec![tv],
-        }
-    }
-}
-
-#[derive(Clone, Copy)]
-enum TypeEnvRank {
-    Singleton = 5,
-    Input = 4,
-    Intermediate = 3,
-    Output = 2,
-    Temp = 1,
-    Internal = 0,
-}
-
-/// Class encapsulating the necessary bookkeeping for type inference.
-pub struct TypeEnvironment {
-    vars: HashSet<VarIndex>,
-    ranks: HashMap<TypeVar, TypeEnvRank>,
-    equivalency_map: HashMap<TypeVar, TypeVar>,
-    pub constraints: Vec<Constraint>,
-}
-
-impl TypeEnvironment {
-    fn new() -> Self {
-        TypeEnvironment {
-            vars: HashSet::new(),
-            ranks: HashMap::new(),
-            equivalency_map: HashMap::new(),
-            constraints: Vec::new(),
-        }
-    }
-
-    fn register(&mut self, var_index: VarIndex, var: &mut Var) {
-        self.vars.insert(var_index);
-        let rank = if var.is_input() {
-            TypeEnvRank::Input
-        } else if var.is_intermediate() {
-            TypeEnvRank::Intermediate
-        } else if var.is_output() {
-            TypeEnvRank::Output
-        } else {
-            assert!(var.is_temp());
-            TypeEnvRank::Temp
-        };
-        self.ranks.insert(var.get_or_create_typevar(), rank);
-    }
-
-    fn add_constraint(&mut self, constraint: Constraint) {
-        if self
-            .constraints
-            .iter()
-            .find(|&item| item == &constraint)
-            .is_some()
-        {
-            return;
-        }
-
-        // Check extra conditions for InTypeset constraints.
-        if let Constraint::InTypeset(tv, _) = &constraint {
-            assert!(tv.base.is_none());
-            assert!(tv.name.starts_with("typeof_"));
-        }
-
-        self.constraints.push(constraint);
-    }
-
-    /// Returns the canonical representative of the equivalency class of the given argument, or
-    /// duplicates it if it's not there yet.
-    pub fn get_equivalent(&self, tv: &TypeVar) -> TypeVar {
-        let mut tv = tv;
-        while let Some(found) = self.equivalency_map.get(tv) {
-            tv = found;
-        }
-        match &tv.base {
-            Some(parent) => self
-                .get_equivalent(&parent.type_var)
-                .derived(parent.derived_func),
-            None => tv.clone(),
-        }
-    }
-
-    /// Get the rank of tv in the partial order:
-    /// - TVs directly associated with a Var get their rank from the Var (see register()).
-    /// - Internally generated non-derived TVs implicitly get the lowest rank (0).
-    /// - Derived variables get their rank from their free typevar.
-    /// - Singletons have the highest rank.
-    /// - TVs associated with vars in a source pattern have a higher rank than TVs associated with
-    /// temporary vars.
-    fn rank(&self, tv: &TypeVar) -> u8 {
-        let actual_tv = match tv.base {
-            Some(_) => tv.free_typevar(),
-            None => Some(tv.clone()),
-        };
-
-        let rank = match actual_tv {
-            Some(actual_tv) => match self.ranks.get(&actual_tv) {
-                Some(rank) => Some(*rank),
-                None => {
-                    assert!(
-                        !actual_tv.name.starts_with("typeof_"),
-                        format!("variable {} should be explicitly ranked", actual_tv.name)
-                    );
-                    None
-                }
-            },
-            None => None,
-        };
-
-        let rank = match rank {
-            Some(rank) => rank,
-            None => {
-                if tv.singleton_type().is_some() {
-                    TypeEnvRank::Singleton
-                } else {
-                    TypeEnvRank::Internal
-                }
-            }
-        };
-
-        rank as u8
-    }
-
-    /// Record the fact that the free tv1 is part of the same equivalence class as tv2. The
-    /// canonical representative of the merged class is tv2's canonical representative.
-    fn record_equivalent(&mut self, tv1: TypeVar, tv2: TypeVar) {
-        assert!(tv1.base.is_none());
-        assert!(self.get_equivalent(&tv1) == tv1);
-        if let Some(tv2_base) = &tv2.base {
-            // Ensure there are no cycles.
-            assert!(self.get_equivalent(&tv2_base.type_var) != tv1);
-        }
-        self.equivalency_map.insert(tv1, tv2);
-    }
-
-    /// Get the free typevars in the current type environment.
-    pub fn free_typevars(&self, var_pool: &mut VarPool) -> Vec<TypeVar> {
-        let mut typevars = Vec::new();
-        typevars.extend(self.equivalency_map.keys().cloned());
-        typevars.extend(
-            self.vars
-                .iter()
-                .map(|&var_index| var_pool.get_mut(var_index).get_or_create_typevar()),
-        );
-
-        let set: HashSet<TypeVar> = HashSet::from_iter(
-            typevars
-                .iter()
-                .map(|tv| self.get_equivalent(tv).free_typevar())
-                .filter(|opt_tv| {
-                    // Filter out singleton types.
-                    return opt_tv.is_some();
-                })
-                .map(|tv| tv.unwrap()),
-        );
-        Vec::from_iter(set)
-    }
-
-    /// Normalize by collapsing any roots that don't correspond to a concrete type var AND have a
-    /// single type var derived from them or equivalent to them.
-    ///
-    /// e.g. if we have a root of the tree that looks like:
-    ///
-    ///   typeof_a   typeof_b
-    ///          \\  /
-    ///       typeof_x
-    ///           |
-    ///         half_width(1)
-    ///           |
-    ///           1
-    ///
-    /// we want to collapse the linear path between 1 and typeof_x. The resulting graph is:
-    ///
-    ///   typeof_a   typeof_b
-    ///          \\  /
-    ///       typeof_x
-    fn normalize(&mut self, var_pool: &mut VarPool) {
-        let source_tvs: HashSet<TypeVar> = HashSet::from_iter(
-            self.vars
-                .iter()
-                .map(|&var_index| var_pool.get_mut(var_index).get_or_create_typevar()),
-        );
-
-        let mut children: HashMap<TypeVar, HashSet<TypeVar>> = HashMap::new();
-
-        // Insert all the parents found by the derivation relationship.
-        for type_var in self.equivalency_map.values() {
-            if type_var.base.is_none() {
-                continue;
-            }
-
-            let parent_tv = type_var.free_typevar();
-            if parent_tv.is_none() {
-                // Ignore this type variable, it's a singleton.
-                continue;
-            }
-            let parent_tv = parent_tv.unwrap();
-
-            children
-                .entry(parent_tv)
-                .or_insert(HashSet::new())
-                .insert(type_var.clone());
-        }
-
-        // Insert all the explicit equivalency links.
-        for (equivalent_tv, canon_tv) in self.equivalency_map.iter() {
-            children
-                .entry(canon_tv.clone())
-                .or_insert(HashSet::new())
-                .insert(equivalent_tv.clone());
-        }
+use crate::cdsl::typevar::TypeVar;
 
-        // Remove links that are straight paths up to typevar of variables.
-        for free_root in self.free_typevars(var_pool) {
-            let mut root = &free_root;
-            while !source_tvs.contains(&root)
-                && children.contains_key(&root)
-                && children.get(&root).unwrap().len() == 1
-            {
-                let child = children.get(&root).unwrap().iter().next().unwrap();
-                assert_eq!(self.equivalency_map[child], root.clone());
-                self.equivalency_map.remove(child);
-                root = child;
-            }
-        }
-    }
-
-    /// Extract a clean type environment from self, that only mentions type vars associated with
-    /// real variables.
-    fn extract(self, var_pool: &mut VarPool) -> TypeEnvironment {
-        let vars_tv: HashSet<TypeVar> = HashSet::from_iter(
-            self.vars
-                .iter()
-                .map(|&var_index| var_pool.get_mut(var_index).get_or_create_typevar()),
-        );
-
-        let mut new_equivalency_map: HashMap<TypeVar, TypeVar> = HashMap::new();
-        for tv in &vars_tv {
-            let canon_tv = self.get_equivalent(tv);
-            if *tv != canon_tv {
-                new_equivalency_map.insert(tv.clone(), canon_tv.clone());
-            }
-
-            // Sanity check: the translated type map should only refer to real variables.
-            assert!(vars_tv.contains(tv));
-            let canon_free_tv = canon_tv.free_typevar();
-            assert!(canon_free_tv.is_none() || vars_tv.contains(&canon_free_tv.unwrap()));
-        }
-
-        let mut new_constraints: HashSet<Constraint> = HashSet::new();
-        for constraint in &self.constraints {
-            let constraint = constraint.translate_with_env(&self);
-            if constraint.is_trivial() || new_constraints.contains(&constraint) {
-                continue;
-            }
-
-            // Sanity check: translated constraints should refer only to real variables.
-            for arg in constraint.typevar_args() {
-                assert!(vars_tv.contains(arg));
-                let arg_free_tv = arg.free_typevar();
-                assert!(arg_free_tv.is_none() || vars_tv.contains(&arg_free_tv.unwrap()));
-            }
-
-            new_constraints.insert(constraint);
-        }
-
-        TypeEnvironment {
-            vars: self.vars,
-            ranks: self.ranks,
-            equivalency_map: new_equivalency_map,
-            constraints: Vec::from_iter(new_constraints),
-        }
-    }
-}
-
-/// Replaces an external type variable according to the following rules:
-/// - if a local copy is present in the map, return it.
-/// - or if it's derived, create a local derived one that recursively substitutes the parent.
-/// - or return itself.
-fn substitute(map: &HashMap<&TypeVar, TypeVar>, external_type_var: &TypeVar) -> TypeVar {
-    match map.get(&external_type_var) {
-        Some(own_type_var) => own_type_var.clone(),
-        None => match &external_type_var.base {
-            Some(parent) => {
-                let parent_substitute = substitute(map, &parent.type_var);
-                TypeVar::derived(&parent_substitute, parent.derived_func)
-            }
-            None => external_type_var.clone(),
-        },
-    }
-}
-
-/// Normalize a (potentially derived) typevar using the following rules:
-///
-/// - vector and width derived functions commute
-///     {HALF,DOUBLE}VECTOR({HALF,DOUBLE}WIDTH(base)) ->
-///     {HALF,DOUBLE}WIDTH({HALF,DOUBLE}VECTOR(base))
-///
-/// - half/double pairs collapse
-///     {HALF,DOUBLE}WIDTH({DOUBLE,HALF}WIDTH(base)) -> base
-///     {HALF,DOUBLE}VECTOR({DOUBLE,HALF}VECTOR(base)) -> base
-fn canonicalize_derivations(tv: TypeVar) -> TypeVar {
-    let base = match &tv.base {
-        Some(base) => base,
-        None => return tv,
-    };
-
-    let derived_func = base.derived_func;
-
-    if let Some(base_base) = &base.type_var.base {
-        let base_base_tv = &base_base.type_var;
-        match (derived_func, base_base.derived_func) {
-            (DerivedFunc::HalfWidth, DerivedFunc::DoubleWidth)
-            | (DerivedFunc::DoubleWidth, DerivedFunc::HalfWidth)
-            | (DerivedFunc::HalfVector, DerivedFunc::DoubleVector)
-            | (DerivedFunc::DoubleVector, DerivedFunc::HalfVector) => {
-                // Cancelling bijective transformations. This doesn't hide any overflow issues
-                // since derived type sets are checked upon derivaion, and base typesets are only
-                // allowed to shrink.
-                return canonicalize_derivations(base_base_tv.clone());
-            }
-            (DerivedFunc::HalfWidth, DerivedFunc::HalfVector)
-            | (DerivedFunc::HalfWidth, DerivedFunc::DoubleVector)
-            | (DerivedFunc::DoubleWidth, DerivedFunc::DoubleVector)
-            | (DerivedFunc::DoubleWidth, DerivedFunc::HalfVector) => {
-                // Arbitrarily put WIDTH derivations before VECTOR derivations, since they commute.
-                return canonicalize_derivations(
-                    base_base_tv
-                        .derived(derived_func)
-                        .derived(base_base.derived_func),
-                );
-            }
-            _ => {}
-        };
-    }
-
-    canonicalize_derivations(base.type_var.clone()).derived(derived_func)
-}
-
-/// Given typevars tv1 and tv2 (which could be derived from one another), constrain their typesets
-/// to be the same. When one is derived from the other, repeat the constrain process until
-/// a fixed point is reached.
-fn constrain_fixpoint(tv1: &TypeVar, tv2: &TypeVar) {
-    loop {
-        let old_tv1_ts = tv1.get_typeset().clone();
-        tv2.constrain_types(tv1.clone());
-        if tv1.get_typeset() == old_tv1_ts {
-            break;
-        }
-    }
-
-    let old_tv2_ts = tv2.get_typeset().clone();
-    tv1.constrain_types(tv2.clone());
-    // The above loop should ensure that all reference cycles have been handled.
-    assert!(old_tv2_ts == tv2.get_typeset());
+pub enum Constraint {
+    WiderOrEq(TypeVar, TypeVar),
 }
-
-/// Unify tv1 and tv2 in the given type environment. tv1 must have a rank greater or equal to tv2's
-/// one, modulo commutations.
-fn unify(tv1: &TypeVar, tv2: &TypeVar, type_env: &mut TypeEnvironment) -> Result<(), String> {
-    let tv1 = canonicalize_derivations(type_env.get_equivalent(tv1));
-    let tv2 = canonicalize_derivations(type_env.get_equivalent(tv2));
-
-    if tv1 == tv2 {
-        // Already unified.
-        return Ok(());
-    }
-
-    if type_env.rank(&tv2) < type_env.rank(&tv1) {
-        // Make sure tv1 always has the smallest rank, since real variables have the higher rank
-        // and we want them to be the canonical representatives of their equivalency classes.
-        return unify(&tv2, &tv1, type_env);
-    }
-
-    constrain_fixpoint(&tv1, &tv2);
-
-    if tv1.get_typeset().size() == 0 || tv2.get_typeset().size() == 0 {
-        return Err(format!(
-            "Error: empty type created when unifying {} and {}",
-            tv1.name, tv2.name
-        ));
-    }
-
-    let base = match &tv1.base {
-        Some(base) => base,
-        None => {
-            type_env.record_equivalent(tv1, tv2);
-            return Ok(());
-        }
-    };
-
-    if let Some(inverse) = base.derived_func.inverse() {
-        return unify(&base.type_var, &tv2.derived(inverse), type_env);
-    }
-
-    type_env.add_constraint(Constraint::Eq(tv1, tv2));
-    Ok(())
-}
-
-/// Perform type inference on one Def in the current type environment and return an updated type
-/// environment or error.
-///
-/// At a high level this works by creating fresh copies of each formal type var in the Def's
-/// instruction's signature, and unifying the formal typevar with the corresponding actual typevar.
-fn infer_definition(
-    def: &Def,
-    var_pool: &mut VarPool,
-    type_env: TypeEnvironment,
-    last_type_index: &mut usize,
-) -> Result<TypeEnvironment, String> {
-    let apply = &def.apply;
-    let inst = &apply.inst;
-
-    let mut type_env = type_env;
-    let free_formal_tvs = inst.all_typevars();
-
-    let mut original_to_own_typevar: HashMap<&TypeVar, TypeVar> = HashMap::new();
-    for &tv in &free_formal_tvs {
-        assert!(original_to_own_typevar
-            .insert(
-                tv,
-                TypeVar::copy_from(tv, format!("own_{}", last_type_index))
-            )
-            .is_none());
-        *last_type_index += 1;
-    }
-
-    // Update the mapping with any explicity bound type vars:
-    for (i, value_type) in apply.value_types.iter().enumerate() {
-        let singleton = TypeVar::new_singleton(value_type.clone());
-        assert!(original_to_own_typevar
-            .insert(free_formal_tvs[i], singleton)
-            .is_some());
-    }
-
-    // Get fresh copies for each typevar in the signature (both free and derived).
-    let mut formal_tvs = Vec::new();
-    formal_tvs.extend(inst.value_results.iter().map(|&i| {
-        substitute(
-            &original_to_own_typevar,
-            inst.operands_out[i].type_var().unwrap(),
-        )
-    }));
-    formal_tvs.extend(inst.value_opnums.iter().map(|&i| {
-        substitute(
-            &original_to_own_typevar,
-            inst.operands_in[i].type_var().unwrap(),
-        )
-    }));
-
-    // Get the list of actual vars.
-    let mut actual_vars = Vec::new();
-    actual_vars.extend(inst.value_results.iter().map(|&i| def.defined_vars[i]));
-    actual_vars.extend(
-        inst.value_opnums
-            .iter()
-            .map(|&i| apply.args[i].unwrap_var()),
-    );
-
-    // Get the list of the actual TypeVars.
-    let mut actual_tvs = Vec::new();
-    for var_index in actual_vars {
-        let var = var_pool.get_mut(var_index);
-        type_env.register(var_index, var);
-        actual_tvs.push(var.get_or_create_typevar());
-    }
-
-    // Make sure we start unifying with the control type variable first, by putting it at the
-    // front of both vectors.
-    if let Some(poly) = &inst.polymorphic_info {
-        let own_ctrl_tv = &original_to_own_typevar[&poly.ctrl_typevar];
-        let ctrl_index = formal_tvs.iter().position(|tv| tv == own_ctrl_tv).unwrap();
-        if ctrl_index != 0 {
-            formal_tvs.swap(0, ctrl_index);
-            actual_tvs.swap(0, ctrl_index);
-        }
-    }
-
-    // Unify each actual type variable with the corresponding formal type variable.
-    for (actual_tv, formal_tv) in actual_tvs.iter().zip(&formal_tvs) {
-        if let Err(msg) = unify(actual_tv, formal_tv, &mut type_env) {
-            return Err(format!(
-                "fail ti on {} <: {}: {}",
-                actual_tv.name, formal_tv.name, msg
-            ));
-        }
-    }
-
-    // Add any instruction specific constraints.
-    for constraint in &inst.constraints {
-        type_env.add_constraint(constraint.translate_with_map(&original_to_own_typevar));
-    }
-
-    Ok(type_env)
-}
-
-/// Perform type inference on an transformation. Return an updated type environment or error.
-pub fn infer_transform(
-    src: DefIndex,
-    dst: &Vec<DefIndex>,
-    def_pool: &DefPool,
-    var_pool: &mut VarPool,
-) -> Result<TypeEnvironment, String> {
-    let mut type_env = TypeEnvironment::new();
-    let mut last_type_index = 0;
-
-    // Execute type inference on the source pattern.
-    type_env = infer_definition(def_pool.get(src), var_pool, type_env, &mut last_type_index)
-        .map_err(|err| format!("In src pattern: {}", err))?;
-
-    // Collect the type sets once after applying the source patterm; we'll compare the typesets
-    // after we've also considered the destination pattern, and will emit supplementary InTypeset
-    // checks if they don't match.
-    let src_typesets = type_env
-        .vars
-        .iter()
-        .map(|&var_index| {
-            let var = var_pool.get_mut(var_index);
-            let tv = type_env.get_equivalent(&var.get_or_create_typevar());
-            (var_index, tv.get_typeset().clone())
-        })
-        .collect::<Vec<_>>();
-
-    // Execute type inference on the destination pattern.
-    for (i, &def_index) in dst.iter().enumerate() {
-        let def = def_pool.get(def_index);
-        type_env = infer_definition(def, var_pool, type_env, &mut last_type_index)
-            .map_err(|err| format!("line {}: {}", i, err))?;
-    }
-
-    for (var_index, src_typeset) in src_typesets {
-        let var = var_pool.get(var_index);
-        if !var.has_free_typevar() {
-            continue;
-        }
-        let tv = type_env.get_equivalent(&var.get_typevar().unwrap());
-        let new_typeset = tv.get_typeset();
-        assert!(
-            new_typeset.is_subset(&src_typeset),
-            "type sets can only get narrower"
-        );
-        if new_typeset != src_typeset {
-            type_env.add_constraint(Constraint::InTypeset(tv.clone(), new_typeset.clone()));
-        }
-    }
-
-    type_env.normalize(var_pool);
-
-    Ok(type_env.extract(var_pool))
-}
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/typevar.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/typevar.rs
@@ -1,12 +1,9 @@
-use std::cell::RefCell;
-use std::collections::{BTreeSet, HashSet};
-use std::fmt;
-use std::hash;
+use std::collections::BTreeSet;
 use std::iter::FromIterator;
 use std::ops;
 use std::rc::Rc;
 
 use crate::cdsl::types::{BVType, LaneType, SpecialType, ValueType};
 
 const MAX_LANES: u16 = 256;
 const MAX_BITS: u16 = 64;
@@ -25,35 +22,35 @@ pub struct TypeVarContent {
     pub name: String,
 
     /// Documentation string.
     pub doc: String,
 
     /// Type set associated to the type variable.
     /// This field must remain private; use `get_typeset()` or `get_raw_typeset()` to get the
     /// information you want.
-    type_set: TypeSet,
+    type_set: Rc<TypeSet>,
 
     pub base: Option<TypeVarParent>,
 }
 
 #[derive(Clone, Debug)]
 pub struct TypeVar {
-    content: Rc<RefCell<TypeVarContent>>,
+    content: Rc<TypeVarContent>,
 }
 
 impl TypeVar {
     pub fn new(name: impl Into<String>, doc: impl Into<String>, type_set: TypeSet) -> Self {
         Self {
-            content: Rc::new(RefCell::new(TypeVarContent {
+            content: Rc::new(TypeVarContent {
                 name: name.into(),
                 doc: doc.into(),
-                type_set,
+                type_set: Rc::new(type_set),
                 base: None,
-            })),
+            }),
         }
     }
 
     pub fn new_singleton(value_type: ValueType) -> Self {
         let (name, doc) = (value_type.to_string(), value_type.doc());
         let mut builder = TypeSetBuilder::new();
 
         let (scalar_type, num_lanes) = match value_type {
@@ -84,75 +81,58 @@ impl TypeVar {
             LaneType::BoolType(bool_type) => {
                 let bits = bool_type as RangeBound;
                 builder.bools(bits..bits)
             }
         };
         TypeVar::new(name, doc, builder.finish())
     }
 
-    /// Get a fresh copy of self, named after `name`. Can only be called on non-derived typevars.
-    pub fn copy_from(other: &TypeVar, name: String) -> TypeVar {
-        assert!(
-            other.base.is_none(),
-            "copy_from() can only be called on non-derived type variables"
-        );
-        TypeVar {
-            content: Rc::new(RefCell::new(TypeVarContent {
-                name,
-                doc: "".into(),
-                type_set: other.type_set.clone(),
-                base: None,
-            })),
-        }
-    }
-
-    /// Returns the typeset for this TV. If the TV is derived, computes it recursively from the
-    /// derived function and the base's typeset.
-    /// Note this can't be done non-lazily in the constructor, because the TypeSet of the base may
-    /// change over time.
-    pub fn get_typeset(&self) -> TypeSet {
-        match &self.base {
-            Some(base) => base.type_var.get_typeset().image(base.derived_func),
-            None => self.type_set.clone(),
+    /// Returns this typevar's type set, maybe computing it from the parent.
+    fn get_typeset(&self) -> Rc<TypeSet> {
+        // TODO Can this be done in a non-lazy way in derived() and we can remove this function and
+        // the one below?
+        match &self.content.base {
+            Some(base) => Rc::new(base.type_var.get_typeset().image(base.derived_func)),
+            None => self.content.type_set.clone(),
         }
     }
 
     /// Returns this typevar's type set, assuming this type var has no parent.
     pub fn get_raw_typeset(&self) -> &TypeSet {
-        assert_eq!(self.type_set, self.get_typeset());
-        &self.type_set
+        assert_eq!(self.content.type_set, self.get_typeset());
+        &*self.content.type_set
     }
 
     /// If the associated typeset has a single type return it. Otherwise return None.
     pub fn singleton_type(&self) -> Option<ValueType> {
         let type_set = self.get_typeset();
         if type_set.size() == 1 {
             Some(type_set.get_singleton())
         } else {
             None
         }
     }
 
     /// Get the free type variable controlling this one.
     pub fn free_typevar(&self) -> Option<TypeVar> {
-        match &self.base {
+        match &self.content.base {
             Some(base) => base.type_var.free_typevar(),
             None => {
                 match self.singleton_type() {
                     // A singleton type isn't a proper free variable.
                     Some(_) => None,
                     None => Some(self.clone()),
                 }
             }
         }
     }
 
     /// Create a type variable that is a function of another.
-    pub fn derived(&self, derived_func: DerivedFunc) -> TypeVar {
+    fn derived(&self, derived_func: DerivedFunc) -> TypeVar {
         let ts = self.get_typeset();
 
         // Safety checks to avoid over/underflows.
         assert!(ts.specials.len() == 0, "can't derive from special types");
         match derived_func {
             DerivedFunc::HalfWidth => {
                 assert!(
                     ts.ints.len() == 0 || *ts.ints.iter().min().unwrap() > 8,
@@ -194,25 +174,25 @@ impl TypeVar {
                 );
             }
             DerivedFunc::LaneOf | DerivedFunc::ToBitVec | DerivedFunc::AsBool => {
                 /* no particular assertions */
             }
         }
 
         return TypeVar {
-            content: Rc::new(RefCell::new(TypeVarContent {
+            content: Rc::new(TypeVarContent {
                 name: format!("{}({})", derived_func.name(), self.name),
                 doc: "".into(),
                 type_set: ts,
                 base: Some(TypeVarParent {
                     type_var: self.clone(),
                     derived_func,
                 }),
-            })),
+            }),
         };
     }
 
     pub fn lane_of(&self) -> TypeVar {
         return self.derived(DerivedFunc::LaneOf);
     }
     pub fn as_bool(&self) -> TypeVar {
         return self.derived(DerivedFunc::AsBool);
@@ -227,115 +207,47 @@ impl TypeVar {
         return self.derived(DerivedFunc::HalfVector);
     }
     pub fn double_vector(&self) -> TypeVar {
         return self.derived(DerivedFunc::DoubleVector);
     }
     pub fn to_bitvec(&self) -> TypeVar {
         return self.derived(DerivedFunc::ToBitVec);
     }
-
-    /// Constrain the range of types this variable can assume to a subset of those in the typeset
-    /// ts.
-    /// May mutate itself if it's not derived, or its parent if it is.
-    pub fn constrain_types_by_ts(&self, type_set: TypeSet) {
-        match &self.base {
-            Some(base) => {
-                base.type_var
-                    .constrain_types_by_ts(type_set.preimage(base.derived_func));
-            }
-            None => {
-                self.content
-                    .borrow_mut()
-                    .type_set
-                    .inplace_intersect_with(&type_set);
-            }
-        }
-    }
-
-    /// Constrain the range of types this variable can assume to a subset of those `other` can
-    /// assume.
-    /// May mutate itself if it's not derived, or its parent if it is.
-    pub fn constrain_types(&self, other: TypeVar) {
-        if self == &other {
-            return;
-        }
-        self.constrain_types_by_ts(other.get_typeset());
-    }
-
-    /// Get a Rust expression that computes the type of this type variable.
-    pub fn to_rust_code(&self) -> String {
-        match &self.base {
-            Some(base) => format!(
-                "{}.{}()",
-                base.type_var.to_rust_code(),
-                base.derived_func.name()
-            ),
-            None => {
-                if let Some(singleton) = self.singleton_type() {
-                    singleton.rust_name()
-                } else {
-                    self.name.clone()
-                }
-            }
-        }
-    }
 }
 
 impl Into<TypeVar> for &TypeVar {
     fn into(self) -> TypeVar {
         self.clone()
     }
 }
 impl Into<TypeVar> for ValueType {
     fn into(self) -> TypeVar {
         TypeVar::new_singleton(self)
     }
 }
 
-// Hash TypeVars by pointers.
-// There might be a better way to do this, but since TypeVar's content (namely TypeSet) can be
-// mutated, it makes sense to use pointer equality/hashing here.
-impl hash::Hash for TypeVar {
-    fn hash<H: hash::Hasher>(&self, h: &mut H) {
-        match &self.base {
-            Some(base) => {
-                base.type_var.hash(h);
-                base.derived_func.hash(h);
-            }
-            None => {
-                (&**self as *const TypeVarContent).hash(h);
-            }
-        }
-    }
-}
-
 impl PartialEq for TypeVar {
     fn eq(&self, other: &TypeVar) -> bool {
-        match (&self.base, &other.base) {
-            (Some(base1), Some(base2)) => {
-                base1.type_var.eq(&base2.type_var) && base1.derived_func == base2.derived_func
-            }
+        match (&self.content.base, &other.content.base) {
+            (Some(base1), Some(base2)) => base1.type_var.eq(&base2.type_var),
             (None, None) => Rc::ptr_eq(&self.content, &other.content),
             _ => false,
         }
     }
 }
 
-// Allow TypeVar as map keys, based on pointer equality (see also above PartialEq impl).
-impl Eq for TypeVar {}
-
 impl ops::Deref for TypeVar {
     type Target = TypeVarContent;
     fn deref(&self) -> &Self::Target {
-        unsafe { self.content.as_ptr().as_ref().unwrap() }
+        &*self.content
     }
 }
 
-#[derive(Clone, Copy, Debug, Hash, PartialEq)]
+#[derive(Clone, Copy, Debug)]
 pub enum DerivedFunc {
     LaneOf,
     AsBool,
     HalfWidth,
     DoubleWidth,
     HalfVector,
     DoubleVector,
     ToBitVec,
@@ -348,30 +260,19 @@ impl DerivedFunc {
             DerivedFunc::AsBool => "as_bool",
             DerivedFunc::HalfWidth => "half_width",
             DerivedFunc::DoubleWidth => "double_width",
             DerivedFunc::HalfVector => "half_vector",
             DerivedFunc::DoubleVector => "double_vector",
             DerivedFunc::ToBitVec => "to_bitvec",
         }
     }
-
-    /// Returns the inverse function of this one, if it is a bijection.
-    pub fn inverse(&self) -> Option<DerivedFunc> {
-        match self {
-            DerivedFunc::HalfWidth => Some(DerivedFunc::DoubleWidth),
-            DerivedFunc::DoubleWidth => Some(DerivedFunc::HalfWidth),
-            DerivedFunc::HalfVector => Some(DerivedFunc::DoubleVector),
-            DerivedFunc::DoubleVector => Some(DerivedFunc::HalfVector),
-            _ => None,
-        }
-    }
 }
 
-#[derive(Debug, Hash)]
+#[derive(Debug)]
 pub struct TypeVarParent {
     pub type_var: TypeVar,
     pub derived_func: DerivedFunc,
 }
 
 /// A set of types.
 ///
 /// We don't allow arbitrary subsets of types, but use a parametrized approach
@@ -395,17 +296,17 @@ type Range = ops::Range<RangeBound>;
 type NumSet = BTreeSet<RangeBound>;
 
 macro_rules! num_set {
     ($($expr:expr),*) => {
         NumSet::from_iter(vec![$($expr),*])
     };
 }
 
-#[derive(Clone, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeSet {
     pub lanes: NumSet,
     pub ints: NumSet,
     pub floats: NumSet,
     pub bools: NumSet,
     pub bitvecs: NumSet,
     pub specials: Vec<SpecialType>,
 }
@@ -425,17 +326,17 @@ impl TypeSet {
             floats,
             bools,
             bitvecs,
             specials,
         }
     }
 
     /// Return the number of concrete types represented by this typeset.
-    pub fn size(&self) -> usize {
+    fn size(&self) -> usize {
         self.lanes.len()
             * (self.ints.len() + self.floats.len() + self.bools.len() + self.bitvecs.len())
             + self.specials.len()
     }
 
     /// Return the image of self across the derived function func.
     fn image(&self, derived_func: DerivedFunc) -> TypeSet {
         match derived_func {
@@ -580,185 +481,16 @@ impl TypeSet {
     }
 
     /// Return the singleton type represented by self. Can only call on typesets containing 1 type.
     fn get_singleton(&self) -> ValueType {
         let mut types = self.concrete_types();
         assert_eq!(types.len(), 1);
         return types.remove(0);
     }
-
-    /// Return the inverse image of self across the derived function func.
-    fn preimage(&self, func: DerivedFunc) -> TypeSet {
-        if self.size() == 0 {
-            // The inverse of the empty set is itself.
-            return self.clone();
-        }
-
-        match func {
-            DerivedFunc::LaneOf => {
-                let mut copy = self.clone();
-                copy.bitvecs = NumSet::new();
-                copy.lanes =
-                    NumSet::from_iter((0..MAX_LANES.trailing_zeros() + 1).map(|i| u16::pow(2, i)));
-                copy
-            }
-            DerivedFunc::AsBool => {
-                let mut copy = self.clone();
-                copy.bitvecs = NumSet::new();
-                if self.bools.contains(&1) {
-                    copy.ints = NumSet::from_iter(vec![8, 16, 32, 64]);
-                    copy.floats = NumSet::from_iter(vec![32, 64]);
-                } else {
-                    copy.ints = &self.bools - &NumSet::from_iter(vec![1]);
-                    copy.floats = &self.bools & &NumSet::from_iter(vec![32, 64]);
-                    // If b1 is not in our typeset, than lanes=1 cannot be in the pre-image, as
-                    // as_bool() of scalars is always b1.
-                    copy.lanes = &self.lanes - &NumSet::from_iter(vec![1]);
-                }
-                copy
-            }
-            DerivedFunc::HalfWidth => self.double_width(),
-            DerivedFunc::DoubleWidth => self.half_width(),
-            DerivedFunc::HalfVector => self.double_vector(),
-            DerivedFunc::DoubleVector => self.half_vector(),
-            DerivedFunc::ToBitVec => {
-                let all_lanes = range_to_set(Some(1..MAX_LANES));
-                let all_ints = range_to_set(Some(8..MAX_BITS));
-                let all_floats = range_to_set(Some(32..64));
-                let all_bools = range_to_set(Some(1..MAX_BITS));
-
-                let mut lanes = range_to_set(Some(1..MAX_LANES));
-                let mut ints = range_to_set(Some(8..MAX_BITS));
-                let mut floats = range_to_set(Some(32..64));
-                let mut bools = range_to_set(Some(1..MAX_BITS));
-
-                for &l in &all_lanes {
-                    for &i in &all_ints {
-                        if self.bitvecs.contains(&(i * l)) {
-                            lanes.insert(l);
-                            ints.insert(i);
-                        }
-                    }
-                    for &f in &all_floats {
-                        if self.bitvecs.contains(&(f * l)) {
-                            lanes.insert(l);
-                            floats.insert(f);
-                        }
-                    }
-                    for &b in &all_bools {
-                        if self.bitvecs.contains(&(b * l)) {
-                            lanes.insert(l);
-                            bools.insert(b);
-                        }
-                    }
-                }
-
-                let bitvecs = NumSet::new();
-                let specials = Vec::new();
-                TypeSet::new(lanes, ints, floats, bools, bitvecs, specials)
-            }
-        }
-    }
-
-    pub fn inplace_intersect_with(&mut self, other: &TypeSet) {
-        self.lanes = &self.lanes & &other.lanes;
-        self.ints = &self.ints & &other.ints;
-        self.floats = &self.floats & &other.floats;
-        self.bools = &self.bools & &other.bools;
-        self.bitvecs = &self.bitvecs & &other.bitvecs;
-
-        let mut new_specials = Vec::new();
-        for spec in &self.specials {
-            if let Some(spec) = other.specials.iter().find(|&other_spec| other_spec == spec) {
-                new_specials.push(*spec);
-            }
-        }
-        self.specials = new_specials;
-    }
-
-    pub fn is_subset(&self, other: &TypeSet) -> bool {
-        self.lanes.is_subset(&other.lanes)
-            && self.ints.is_subset(&other.ints)
-            && self.floats.is_subset(&other.floats)
-            && self.bools.is_subset(&other.bools)
-            && self.bitvecs.is_subset(&other.bitvecs)
-            && {
-                let specials: HashSet<SpecialType> = HashSet::from_iter(self.specials.clone());
-                let other_specials = HashSet::from_iter(other.specials.clone());
-                specials.is_subset(&other_specials)
-            }
-    }
-
-    pub fn is_wider_or_equal(&self, other: &TypeSet) -> bool {
-        set_wider_or_equal(&self.ints, &other.ints)
-            && set_wider_or_equal(&self.floats, &other.floats)
-            && set_wider_or_equal(&self.bools, &other.bools)
-    }
-
-    pub fn is_narrower(&self, other: &TypeSet) -> bool {
-        set_narrower(&self.ints, &other.ints)
-            && set_narrower(&self.floats, &other.floats)
-            && set_narrower(&self.bools, &other.bools)
-    }
-}
-
-fn set_wider_or_equal(s1: &NumSet, s2: &NumSet) -> bool {
-    s1.len() > 0 && s2.len() > 0 && s1.iter().min() >= s2.iter().max()
-}
-
-fn set_narrower(s1: &NumSet, s2: &NumSet) -> bool {
-    s1.len() > 0 && s2.len() > 0 && s1.iter().min() < s2.iter().max()
-}
-
-impl fmt::Debug for TypeSet {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        write!(fmt, "TypeSet(")?;
-
-        let mut subsets = Vec::new();
-        if !self.lanes.is_empty() {
-            subsets.push(format!(
-                "lanes={{{}}}",
-                Vec::from_iter(self.lanes.iter().map(|x| x.to_string())).join(", ")
-            ));
-        }
-        if !self.ints.is_empty() {
-            subsets.push(format!(
-                "ints={{{}}}",
-                Vec::from_iter(self.ints.iter().map(|x| x.to_string())).join(", ")
-            ));
-        }
-        if !self.floats.is_empty() {
-            subsets.push(format!(
-                "floats={{{}}}",
-                Vec::from_iter(self.floats.iter().map(|x| x.to_string())).join(", ")
-            ));
-        }
-        if !self.bools.is_empty() {
-            subsets.push(format!(
-                "bools={{{}}}",
-                Vec::from_iter(self.bools.iter().map(|x| x.to_string())).join(", ")
-            ));
-        }
-        if !self.bitvecs.is_empty() {
-            subsets.push(format!(
-                "bitvecs={{{}}}",
-                Vec::from_iter(self.bitvecs.iter().map(|x| x.to_string())).join(", ")
-            ));
-        }
-        if !self.specials.is_empty() {
-            subsets.push(format!(
-                "specials={{{}}}",
-                Vec::from_iter(self.specials.iter().map(|x| x.to_string())).join(", ")
-            ));
-        }
-
-        write!(fmt, "{})", subsets.join(", "))?;
-        Ok(())
-    }
 }
 
 pub struct TypeSetBuilder {
     ints: Interval,
     floats: Interval,
     bools: Interval,
     bitvecs: Interval,
     includes_scalars: bool,
@@ -826,28 +558,16 @@ impl TypeSetBuilder {
             range_to_set(self.simd_lanes.to_range(min_lanes..MAX_LANES, Some(1))),
             range_to_set(self.ints.to_range(8..MAX_BITS, None)),
             range_to_set(self.floats.to_range(32..64, None)),
             bools,
             range_to_set(self.bitvecs.to_range(1..MAX_BITVEC, None)),
             self.specials,
         )
     }
-
-    pub fn all() -> TypeSet {
-        TypeSetBuilder::new()
-            .ints(Interval::All)
-            .floats(Interval::All)
-            .bools(Interval::All)
-            .simd_lanes(Interval::All)
-            .bitvecs(Interval::All)
-            .specials(ValueType::all_special_types().collect())
-            .includes_scalars(true)
-            .finish()
-    }
 }
 
 #[derive(PartialEq)]
 pub enum Interval {
     None,
     All,
     Range(Range),
 }
@@ -1081,146 +801,16 @@ fn test_forward_images() {
     );
     assert_eq!(
         TypeSetBuilder::new().bools(32..64).finish().double_width(),
         TypeSetBuilder::new().bools(64..64).finish()
     );
 }
 
 #[test]
-fn test_backward_images() {
-    let empty_set = TypeSetBuilder::new().finish();
-
-    // LaneOf.
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(1..1)
-            .ints(8..8)
-            .floats(32..32)
-            .finish()
-            .preimage(DerivedFunc::LaneOf),
-        TypeSetBuilder::new()
-            .simd_lanes(Interval::All)
-            .ints(8..8)
-            .floats(32..32)
-            .finish()
-    );
-    assert_eq!(empty_set.preimage(DerivedFunc::LaneOf), empty_set);
-
-    // AsBool.
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(1..4)
-            .bools(1..64)
-            .finish()
-            .preimage(DerivedFunc::AsBool),
-        TypeSetBuilder::new()
-            .simd_lanes(1..4)
-            .ints(Interval::All)
-            .bools(Interval::All)
-            .floats(Interval::All)
-            .finish()
-    );
-
-    // Double vector.
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(1..1)
-            .ints(8..8)
-            .finish()
-            .preimage(DerivedFunc::DoubleVector)
-            .size(),
-        0
-    );
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(1..16)
-            .ints(8..16)
-            .floats(32..32)
-            .finish()
-            .preimage(DerivedFunc::DoubleVector),
-        TypeSetBuilder::new()
-            .simd_lanes(1..8)
-            .ints(8..16)
-            .floats(32..32)
-            .finish(),
-    );
-
-    // Half vector.
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(256..256)
-            .ints(8..8)
-            .finish()
-            .preimage(DerivedFunc::HalfVector)
-            .size(),
-        0
-    );
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(64..128)
-            .bools(1..32)
-            .finish()
-            .preimage(DerivedFunc::HalfVector),
-        TypeSetBuilder::new()
-            .simd_lanes(128..256)
-            .bools(1..32)
-            .finish(),
-    );
-
-    // Half width.
-    assert_eq!(
-        TypeSetBuilder::new()
-            .ints(64..64)
-            .floats(64..64)
-            .bools(64..64)
-            .finish()
-            .preimage(DerivedFunc::HalfWidth)
-            .size(),
-        0
-    );
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(64..256)
-            .bools(1..64)
-            .finish()
-            .preimage(DerivedFunc::HalfWidth),
-        TypeSetBuilder::new()
-            .simd_lanes(64..256)
-            .bools(16..64)
-            .finish(),
-    );
-
-    // Double width.
-    assert_eq!(
-        TypeSetBuilder::new()
-            .ints(8..8)
-            .floats(32..32)
-            .bools(1..8)
-            .finish()
-            .preimage(DerivedFunc::DoubleWidth)
-            .size(),
-        0
-    );
-    assert_eq!(
-        TypeSetBuilder::new()
-            .simd_lanes(1..16)
-            .ints(8..16)
-            .floats(32..64)
-            .finish()
-            .preimage(DerivedFunc::DoubleWidth),
-        TypeSetBuilder::new()
-            .simd_lanes(1..16)
-            .ints(8..8)
-            .floats(32..32)
-            .finish()
-    );
-}
-
-#[test]
 #[should_panic]
 fn test_typeset_singleton_panic_nonsingleton_types() {
     TypeSetBuilder::new()
         .ints(8..8)
         .floats(32..32)
         .finish()
         .get_singleton();
 }
deleted file mode 100644
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/xform.rs
+++ /dev/null
@@ -1,416 +0,0 @@
-use crate::cdsl::ast::{
-    Apply, DefIndex, DefPool, DummyDef, DummyExpr, Expr, PatternPosition, VarIndex, VarPool,
-};
-use crate::cdsl::inst::Instruction;
-use crate::cdsl::type_inference::{infer_transform, TypeEnvironment};
-use crate::cdsl::typevar::TypeVar;
-
-use cranelift_entity::{entity_impl, PrimaryMap};
-
-use std::collections::{HashMap, HashSet};
-use std::iter::FromIterator;
-
-/// An instruction transformation consists of a source and destination pattern.
-///
-/// Patterns are expressed in *register transfer language* as tuples of Def or Expr nodes. A
-/// pattern may optionally have a sequence of TypeConstraints, that additionally limit the set of
-/// cases when it applies.
-///
-/// The source pattern can contain only a single instruction.
-pub struct Transform {
-    pub src: DefIndex,
-    pub dst: Vec<DefIndex>,
-    pub var_pool: VarPool,
-    pub def_pool: DefPool,
-    pub type_env: TypeEnvironment,
-}
-
-type SymbolTable = HashMap<&'static str, VarIndex>;
-
-impl Transform {
-    fn new(src: DummyDef, dst: Vec<DummyDef>) -> Self {
-        let mut var_pool = VarPool::new();
-        let mut def_pool = DefPool::new();
-
-        let mut input_vars: Vec<VarIndex> = Vec::new();
-        let mut defined_vars: Vec<VarIndex> = Vec::new();
-
-        // Maps variable names to our own Var copies.
-        let mut symbol_table: SymbolTable = SymbolTable::new();
-
-        // Rewrite variables in src and dst using our own copies.
-        let src = rewrite_def_list(
-            PatternPosition::Source,
-            vec![src],
-            &mut symbol_table,
-            &mut input_vars,
-            &mut defined_vars,
-            &mut var_pool,
-            &mut def_pool,
-        )[0];
-
-        let num_src_inputs = input_vars.len();
-
-        let dst = rewrite_def_list(
-            PatternPosition::Destination,
-            dst,
-            &mut symbol_table,
-            &mut input_vars,
-            &mut defined_vars,
-            &mut var_pool,
-            &mut def_pool,
-        );
-
-        // Sanity checks.
-        for &var_index in &input_vars {
-            assert!(
-                var_pool.get(var_index).is_input(),
-                format!("'{:?}' used as both input and def", var_pool.get(var_index))
-            );
-        }
-        assert!(
-            input_vars.len() == num_src_inputs,
-            format!(
-                "extra input vars in dst pattern: {:?}",
-                input_vars
-                    .iter()
-                    .map(|&i| var_pool.get(i))
-                    .skip(num_src_inputs)
-                    .collect::<Vec<_>>()
-            )
-        );
-
-        // Perform type inference and cleanup.
-        let type_env = infer_transform(src, &dst, &def_pool, &mut var_pool).unwrap();
-
-        // Sanity check: the set of inferred free type variables should be a subset of the type
-        // variables corresponding to Vars appearing in the source pattern.
-        {
-            let free_typevars: HashSet<TypeVar> =
-                HashSet::from_iter(type_env.free_typevars(&mut var_pool));
-            let src_tvs = HashSet::from_iter(
-                input_vars
-                    .clone()
-                    .iter()
-                    .chain(
-                        defined_vars
-                            .iter()
-                            .filter(|&&var_index| !var_pool.get(var_index).is_temp()),
-                    )
-                    .map(|&var_index| var_pool.get(var_index).get_typevar())
-                    .filter(|maybe_var| maybe_var.is_some())
-                    .map(|var| var.unwrap()),
-            );
-            if !free_typevars.is_subset(&src_tvs) {
-                let missing_tvs = (&free_typevars - &src_tvs)
-                    .iter()
-                    .map(|tv| tv.name.clone())
-                    .collect::<Vec<_>>()
-                    .join(", ");
-                panic!("Some free vars don't appear in src: {}", missing_tvs);
-            }
-        }
-
-        for &var_index in input_vars.iter().chain(defined_vars.iter()) {
-            let var = var_pool.get_mut(var_index);
-            let canon_tv = type_env.get_equivalent(&var.get_or_create_typevar());
-            var.set_typevar(canon_tv);
-        }
-
-        Self {
-            src,
-            dst,
-            var_pool,
-            def_pool,
-            type_env,
-        }
-    }
-
-    fn verify_legalize(&self) {
-        let def = self.def_pool.get(self.src);
-        for &var_index in def.defined_vars.iter() {
-            let defined_var = self.var_pool.get(var_index);
-            assert!(
-                defined_var.is_output(),
-                format!("{:?} not defined in the destination pattern", defined_var)
-            );
-        }
-    }
-}
-
-/// Given a list of symbols defined in a Def, rewrite them to local symbols. Yield the new locals.
-fn rewrite_defined_vars(
-    position: PatternPosition,
-    dummy_def: &DummyDef,
-    def_index: DefIndex,
-    symbol_table: &mut SymbolTable,
-    defined_vars: &mut Vec<VarIndex>,
-    var_pool: &mut VarPool,
-) -> Vec<VarIndex> {
-    let mut new_defined_vars = Vec::new();
-    for var in &dummy_def.defined_vars {
-        let own_var = match symbol_table.get(var.name) {
-            Some(&existing_var) => existing_var,
-            None => {
-                // Materialize the variable.
-                let new_var = var_pool.create(var.name);
-                symbol_table.insert(var.name, new_var);
-                defined_vars.push(new_var);
-                new_var
-            }
-        };
-        var_pool.get_mut(own_var).set_def(position, def_index);
-        new_defined_vars.push(own_var);
-    }
-    new_defined_vars
-}
-
-/// Find all uses of variables in `expr` and replace them with our own local symbols.
-fn rewrite_expr(
-    position: PatternPosition,
-    dummy_expr: DummyExpr,
-    symbol_table: &mut SymbolTable,
-    input_vars: &mut Vec<VarIndex>,
-    var_pool: &mut VarPool,
-) -> Apply {
-    let (apply_target, dummy_args) = if let DummyExpr::Apply(apply_target, dummy_args) = dummy_expr
-    {
-        (apply_target, dummy_args)
-    } else {
-        panic!("we only rewrite apply expressions");
-    };
-
-    assert_eq!(
-        apply_target.inst().operands_in.len(),
-        dummy_args.len(),
-        "number of arguments in instruction is incorrect"
-    );
-
-    let mut args = Vec::new();
-    for (i, arg) in dummy_args.into_iter().enumerate() {
-        match arg {
-            DummyExpr::Var(var) => {
-                let own_var = match symbol_table.get(var.name) {
-                    Some(&own_var) => {
-                        let var = var_pool.get(own_var);
-                        assert!(
-                            var.is_input() || var.get_def(position).is_some(),
-                            format!("{:?} used as both input and def", var)
-                        );
-                        own_var
-                    }
-                    None => {
-                        // First time we're using this variable.
-                        let own_var = var_pool.create(var.name);
-                        symbol_table.insert(var.name, own_var);
-                        input_vars.push(own_var);
-                        own_var
-                    }
-                };
-                args.push(Expr::Var(own_var));
-            }
-            DummyExpr::Literal(literal) => {
-                assert!(!apply_target.inst().operands_in[i].is_value());
-                args.push(Expr::Literal(literal));
-            }
-            DummyExpr::Apply(..) => {
-                panic!("Recursive apply is not allowed.");
-            }
-        }
-    }
-
-    Apply::new(apply_target, args)
-}
-
-fn rewrite_def_list(
-    position: PatternPosition,
-    dummy_defs: Vec<DummyDef>,
-    symbol_table: &mut SymbolTable,
-    input_vars: &mut Vec<VarIndex>,
-    defined_vars: &mut Vec<VarIndex>,
-    var_pool: &mut VarPool,
-    def_pool: &mut DefPool,
-) -> Vec<DefIndex> {
-    let mut new_defs = Vec::new();
-    for dummy_def in dummy_defs {
-        let def_index = def_pool.next_index();
-
-        let new_defined_vars = rewrite_defined_vars(
-            position,
-            &dummy_def,
-            def_index,
-            symbol_table,
-            defined_vars,
-            var_pool,
-        );
-        let new_apply = rewrite_expr(position, dummy_def.expr, symbol_table, input_vars, var_pool);
-
-        assert!(
-            def_pool.next_index() == def_index,
-            "shouldn't have created new defs in the meanwhile"
-        );
-        assert_eq!(
-            new_apply.inst.value_results.len(),
-            new_defined_vars.len(),
-            "number of Var results in instruction is incorrect"
-        );
-
-        new_defs.push(def_pool.create(new_apply, new_defined_vars));
-    }
-    new_defs
-}
-
-/// A group of related transformations.
-pub struct TransformGroup {
-    pub name: &'static str,
-    pub doc: &'static str,
-    pub chain_with: Option<TransformGroupIndex>,
-    pub isa_name: Option<&'static str>,
-    pub id: TransformGroupIndex,
-
-    /// Maps Instruction camel_case names to custom legalization functions names.
-    pub custom_legalizes: HashMap<String, &'static str>,
-    pub transforms: Vec<Transform>,
-}
-
-impl TransformGroup {
-    pub fn rust_name(&self) -> String {
-        match self.isa_name {
-            Some(_) => {
-                // This is a function in the same module as the LEGALIZE_ACTIONS table referring to
-                // it.
-                self.name.to_string()
-            }
-            None => format!("crate::legalizer::{}", self.name),
-        }
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct TransformGroupIndex(u32);
-entity_impl!(TransformGroupIndex);
-
-pub struct TransformGroupBuilder {
-    name: &'static str,
-    doc: &'static str,
-    chain_with: Option<TransformGroupIndex>,
-    isa_name: Option<&'static str>,
-    pub custom_legalizes: HashMap<String, &'static str>,
-    pub transforms: Vec<Transform>,
-}
-
-impl TransformGroupBuilder {
-    pub fn new(name: &'static str, doc: &'static str) -> Self {
-        Self {
-            name,
-            doc,
-            chain_with: None,
-            isa_name: None,
-            custom_legalizes: HashMap::new(),
-            transforms: Vec::new(),
-        }
-    }
-
-    pub fn chain_with(mut self, next_id: TransformGroupIndex) -> Self {
-        assert!(self.chain_with.is_none());
-        self.chain_with = Some(next_id);
-        self
-    }
-
-    pub fn isa(mut self, isa_name: &'static str) -> Self {
-        assert!(self.isa_name.is_none());
-        self.isa_name = Some(isa_name);
-        self
-    }
-
-    /// Add a custom legalization action for `inst`.
-    ///
-    /// The `func_name` parameter is the fully qualified name of a Rust function which takes the
-    /// same arguments as the `isa::Legalize` actions.
-    ///
-    /// The custom function will be called to legalize `inst` and any return value is ignored.
-    pub fn custom_legalize(&mut self, inst: &Instruction, func_name: &'static str) {
-        assert!(
-            self.custom_legalizes
-                .insert(inst.camel_name.clone(), func_name)
-                .is_none(),
-            format!(
-                "custom legalization action for {} inserted twice",
-                inst.name
-            )
-        );
-    }
-
-    /// Add a legalization pattern to this group.
-    pub fn legalize(&mut self, src: DummyDef, dst: Vec<DummyDef>) {
-        let transform = Transform::new(src, dst);
-        transform.verify_legalize();
-        self.transforms.push(transform);
-    }
-
-    pub fn finish_and_add_to(self, owner: &mut TransformGroups) -> TransformGroupIndex {
-        let next_id = owner.next_key();
-        owner.add(TransformGroup {
-            name: self.name,
-            doc: self.doc,
-            isa_name: self.isa_name,
-            id: next_id,
-            chain_with: self.chain_with,
-            custom_legalizes: self.custom_legalizes,
-            transforms: self.transforms,
-        })
-    }
-}
-
-pub struct TransformGroups {
-    groups: PrimaryMap<TransformGroupIndex, TransformGroup>,
-}
-
-impl TransformGroups {
-    pub fn new() -> Self {
-        Self {
-            groups: PrimaryMap::new(),
-        }
-    }
-    pub fn add(&mut self, new_group: TransformGroup) -> TransformGroupIndex {
-        for group in self.groups.values() {
-            assert!(
-                group.name != new_group.name,
-                format!("trying to insert {} for the second time", new_group.name)
-            );
-        }
-        self.groups.push(new_group)
-    }
-    pub fn get(&self, id: TransformGroupIndex) -> &TransformGroup {
-        &self.groups[id]
-    }
-    pub fn get_mut(&mut self, id: TransformGroupIndex) -> &mut TransformGroup {
-        self.groups.get_mut(id).unwrap()
-    }
-    fn next_key(&self) -> TransformGroupIndex {
-        self.groups.next_key()
-    }
-    pub fn by_name(&self, name: &'static str) -> &TransformGroup {
-        for group in self.groups.values() {
-            if group.name == name {
-                return group;
-            }
-        }
-        panic!(format!("transform group with name {} not found", name));
-    }
-}
-
-#[test]
-#[should_panic]
-fn test_double_custom_legalization() {
-    use crate::cdsl::formats::{FormatRegistry, InstructionFormatBuilder};
-    use crate::cdsl::inst::InstructionBuilder;
-
-    let mut format = FormatRegistry::new();
-    format.insert(InstructionFormatBuilder::new("nullary"));
-    let dummy_inst = InstructionBuilder::new("dummy", "doc").finish(&format);
-
-    let mut transform_group = TransformGroupBuilder::new("test", "doc");
-    transform_group.custom_legalize(&dummy_inst, "custom 1");
-    transform_group.custom_legalize(&dummy_inst, "custom 2");
-}
--- a/third_party/rust/cranelift-codegen-meta/src/gen_inst.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/gen_inst.rs
@@ -660,17 +660,17 @@ fn typeset_to_string(ts: &TypeSet) -> St
     if ts.specials.len() > 0 {
         result += &format!(", specials=[{}]", iterable_to_string(&ts.specials));
     }
     result += ")";
     result
 }
 
 /// Generate the table of ValueTypeSets described by type_sets.
-pub fn gen_typesets_table(type_sets: &UniqueTable<TypeSet>, fmt: &mut Formatter) {
+fn gen_typesets_table(type_sets: &UniqueTable<TypeSet>, fmt: &mut Formatter) {
     if type_sets.len() == 0 {
         return;
     }
 
     fmt.comment("Table of value type sets.");
     assert!(type_sets.len() <= TYPESET_LIMIT, "Too many type sets!");
     fmtln!(
         fmt,
deleted file mode 100644
--- a/third_party/rust/cranelift-codegen-meta/src/gen_legalizer.rs
+++ /dev/null
@@ -1,578 +0,0 @@
-use crate::cdsl::ast::{Def, DefPool, VarPool};
-use crate::cdsl::formats::FormatRegistry;
-use crate::cdsl::isa::TargetIsa;
-use crate::cdsl::type_inference::Constraint;
-use crate::cdsl::typevar::{TypeSet, TypeVar};
-use crate::cdsl::xform::{Transform, TransformGroup, TransformGroups};
-
-use crate::error;
-use crate::gen_inst::gen_typesets_table;
-use crate::srcgen::Formatter;
-use crate::unique_table::UniqueTable;
-
-use std::collections::{HashMap, HashSet};
-use std::iter::FromIterator;
-
-/// Given a `Def` node, emit code that extracts all the instruction fields from
-/// `pos.func.dfg[iref]`.
-///
-/// Create local variables named after the `Var` instances in `node`.
-///
-/// Also create a local variable named `predicate` with the value of the evaluated instruction
-/// predicate, or `true` if the node has no predicate.
-fn unwrap_inst(
-    transform: &Transform,
-    format_registry: &FormatRegistry,
-    fmt: &mut Formatter,
-) -> bool {
-    let var_pool = &transform.var_pool;
-    let def_pool = &transform.def_pool;
-
-    let def = def_pool.get(transform.src);
-    let apply = &def.apply;
-    let inst = &apply.inst;
-    let iform = format_registry.get(inst.format);
-
-    fmt.comment(format!(
-        "Unwrap {}",
-        def.to_comment_string(&transform.var_pool)
-    ));
-
-    // Extract the Var arguments.
-    let arg_names = apply
-        .args
-        .iter()
-        .map(|arg| match arg.maybe_var() {
-            Some(var_index) => var_pool.get(var_index).name,
-            None => "_",
-        })
-        .collect::<Vec<_>>()
-        .join(", ");
-
-    fmtln!(
-        fmt,
-        "let ({}, predicate) = if let crate::ir::InstructionData::{} {{",
-        arg_names,
-        iform.name
-    );
-    fmt.indent(|fmt| {
-        // Fields are encoded directly.
-        for field in &iform.imm_fields {
-            fmtln!(fmt, "{},", field.member);
-        }
-
-        if iform.num_value_operands == 1 {
-            fmt.line("arg,");
-        } else if iform.has_value_list || iform.num_value_operands > 1 {
-            fmt.line("ref args,");
-        }
-
-        fmt.line("..");
-        fmt.outdented_line("} = pos.func.dfg[inst] {");
-        fmt.line("let func = &pos.func;");
-
-        if iform.has_value_list {
-            fmt.line("let args = args.as_slice(&func.dfg.value_lists);");
-        } else if iform.num_value_operands == 1 {
-            fmt.line("let args = [arg];")
-        }
-
-        // Generate the values for the tuple.
-        fmt.line("(");
-        fmt.indent(|fmt| {
-            for (op_num, op) in inst.operands_in.iter().enumerate() {
-                if op.is_immediate() {
-                    let n = inst.imm_opnums.iter().position(|&i| i == op_num).unwrap();
-                    fmtln!(fmt, "{},", iform.imm_fields[n].member);
-                } else if op.is_value() {
-                    let n = inst.value_opnums.iter().position(|&i| i == op_num).unwrap();
-                    fmtln!(fmt, "func.dfg.resolve_aliases(args[{}]),", n);
-                }
-            }
-
-            // Evaluate the instruction predicate if any.
-            fmt.multi_line(
-                &apply
-                    .inst_predicate_with_ctrl_typevar(format_registry, var_pool)
-                    .rust_predicate(),
-            );
-        });
-        fmt.line(")");
-
-        fmt.outdented_line("} else {");
-        fmt.line(r#"unreachable!("bad instruction format")"#);
-    });
-    fmtln!(fmt, "};");
-
-    for &op_num in &inst.value_opnums {
-        let arg = &apply.args[op_num];
-        if let Some(var_index) = arg.maybe_var() {
-            let var = var_pool.get(var_index);
-            if var.has_free_typevar() {
-                fmtln!(
-                    fmt,
-                    "let typeof_{} = pos.func.dfg.value_type({});",
-                    var.name,
-                    var.name
-                );
-            }
-        }
-    }
-
-    // If the definition creates results, detach the values and place them in locals.
-    let mut replace_inst = false;
-    if def.defined_vars.len() > 0 {
-        if def.defined_vars
-            == def_pool
-                .get(var_pool.get(def.defined_vars[0]).dst_def.unwrap())
-                .defined_vars
-        {
-            // Special case: The instruction replacing node defines the exact same values.
-            fmt.comment(format!(
-                "Results handled by {}.",
-                def_pool
-                    .get(var_pool.get(def.defined_vars[0]).dst_def.unwrap())
-                    .to_comment_string(var_pool)
-            ));
-            replace_inst = true;
-        } else {
-            // Boring case: Detach the result values, capture them in locals.
-            for &var_index in &def.defined_vars {
-                fmtln!(fmt, "let {};", var_pool.get(var_index).name);
-            }
-
-            fmt.line("{");
-            fmt.indent(|fmt| {
-                fmt.line("let r = pos.func.dfg.inst_results(inst);");
-                for i in 0..def.defined_vars.len() {
-                    let var = var_pool.get(def.defined_vars[i]);
-                    fmtln!(fmt, "{} = r[{}];", var.name, i);
-                }
-            });
-            fmt.line("}");
-
-            for &var_index in &def.defined_vars {
-                let var = var_pool.get(var_index);
-                if var.has_free_typevar() {
-                    fmtln!(
-                        fmt,
-                        "let typeof_{} = pos.func.dfg.value_type({});",
-                        var.name,
-                        var.name
-                    );
-                }
-            }
-        }
-    }
-    replace_inst
-}
-
-fn build_derived_expr(tv: &TypeVar) -> String {
-    let base = match &tv.base {
-        Some(base) => base,
-        None => {
-            assert!(tv.name.starts_with("typeof_"));
-            return format!("Some({})", tv.name);
-        }
-    };
-    let base_expr = build_derived_expr(&base.type_var);
-    format!(
-        "{}.map(|t: crate::ir::Type| t.{}())",
-        base_expr,
-        base.derived_func.name()
-    )
-}
-
-/// Emit rust code for the given check.
-///
-/// The emitted code is a statement redefining the `predicate` variable like this:
-///     let predicate = predicate && ...
-fn emit_runtime_typecheck<'a, 'b>(
-    constraint: &'a Constraint,
-    type_sets: &mut UniqueTable<'a, TypeSet>,
-    fmt: &mut Formatter,
-) {
-    match constraint {
-        Constraint::InTypeset(tv, ts) => {
-            let ts_index = type_sets.add(&ts);
-            fmt.comment(format!(
-                "{} must belong to {:?}",
-                tv.name,
-                type_sets.get(ts_index)
-            ));
-            fmtln!(
-                fmt,
-                "let predicate = predicate && TYPE_SETS[{}].contains({});",
-                ts_index,
-                tv.name
-            );
-        }
-        Constraint::Eq(tv1, tv2) => {
-            fmtln!(
-                fmt,
-                "let predicate = predicate && match ({}, {}) {{",
-                build_derived_expr(tv1),
-                build_derived_expr(tv2)
-            );
-            fmt.indent(|fmt| {
-                fmt.line("(Some(a), Some(b)) => a == b,");
-                fmt.comment("On overflow, constraint doesn\'t apply");
-                fmt.line("_ => false,");
-            });
-            fmtln!(fmt, "};");
-        }
-        Constraint::WiderOrEq(tv1, tv2) => {
-            fmtln!(
-                fmt,
-                "let predicate = predicate && match ({}, {}) {{",
-                build_derived_expr(tv1),
-                build_derived_expr(tv2)
-            );
-            fmt.indent(|fmt| {
-                fmt.line("(Some(a), Some(b)) => a.wider_or_equal(b),");
-                fmt.comment("On overflow, constraint doesn\'t apply");
-                fmt.line("_ => false,");
-            });
-            fmtln!(fmt, "};");
-        }
-    }
-}
-
-/// Determine if `node` represents one of the value splitting instructions: `isplit` or `vsplit.
-/// These instructions are lowered specially by the `legalize::split` module.
-fn is_value_split(def: &Def) -> bool {
-    let name = def.apply.inst.name;
-    name == "isplit" || name == "vsplit"
-}
-
-fn emit_dst_inst(def: &Def, def_pool: &DefPool, var_pool: &VarPool, fmt: &mut Formatter) {
-    let defined_vars = {
-        let vars = def
-            .defined_vars
-            .iter()
-            .map(|&var_index| var_pool.get(var_index).name)
-            .collect::<Vec<_>>();
-        if vars.len() == 1 {
-            vars[0].to_string()
-        } else {
-            format!("({})", vars.join(", "))
-        }
-    };
-
-    if is_value_split(def) {
-        // Split instructions are not emitted with the builder, but by calling special functions in
-        // the `legalizer::split` module. These functions will eliminate concat-split patterns.
-        fmt.line("let curpos = pos.position();");
-        fmt.line("let srcloc = pos.srcloc();");
-        fmtln!(
-            fmt,
-            "let {} = split::{}(pos.func, cfg, curpos, srcloc, {});",
-            defined_vars,
-            def.apply.inst.snake_name(),
-            def.apply.args[0].to_rust_code(var_pool)
-        );
-        return;
-    }
-
-    if def.defined_vars.is_empty() {
-        // This node doesn't define any values, so just insert the new instruction.
-        fmtln!(
-            fmt,
-            "pos.ins().{};",
-            def.apply.rust_builder(&def.defined_vars, var_pool)
-        );
-        return;
-    }
-
-    if let Some(src_def0) = var_pool.get(def.defined_vars[0]).src_def {
-        if def.defined_vars == def_pool.get(src_def0).defined_vars {
-            // The replacement instruction defines the exact same values as the source pattern.
-            // Unwrapping would have left the results intact.  Replace the whole instruction.
-            fmtln!(
-                fmt,
-                "let {} = pos.func.dfg.replace(inst).{};",
-                defined_vars,
-                def.apply.rust_builder(&def.defined_vars, var_pool)
-            );
-
-            // We need to bump the cursor so following instructions are inserted *after* the
-            // replaced instruction.
-            fmt.line("if pos.current_inst() == Some(inst) {");
-            fmt.indent(|fmt| {
-                fmt.line("pos.next_inst();");
-            });
-            fmt.line("}");
-            return;
-        }
-    }
-
-    // Insert a new instruction.
-    let mut builder = format!("let {} = pos.ins()", defined_vars);
-
-    if def.defined_vars.len() == 1 && var_pool.get(def.defined_vars[0]).is_output() {
-        // Reuse the single source result value.
-        builder = format!(
-            "{}.with_result({})",
-            builder,
-            var_pool.get(def.defined_vars[0]).to_rust_code()
-        );
-    } else if def
-        .defined_vars
-        .iter()
-        .any(|&var_index| var_pool.get(var_index).is_output())
-    {
-        // There are more than one output values that can be reused.
-        let array = def
-            .defined_vars
-            .iter()
-            .map(|&var_index| {
-                let var = var_pool.get(var_index);
-                if var.is_output() {
-                    format!("Some({})", var.name)
-                } else {
-                    "None".into()
-                }
-            })
-            .collect::<Vec<_>>()
-            .join(", ");
-        builder = format!("{}.with_results([{}])", builder, array);
-    }
-
-    fmtln!(
-        fmt,
-        "{}.{};",
-        builder,
-        def.apply.rust_builder(&def.defined_vars, var_pool)
-    );
-}
-
-/// Emit code for `transform`, assuming that the opcode of transform's root instruction
-/// has already been matched.
-///
-/// `inst: Inst` is the variable to be replaced. It is pointed to by `pos: Cursor`.
-/// `dfg: DataFlowGraph` is available and mutable.
-fn gen_transform<'a>(
-    transform: &'a Transform,
-    format_registry: &FormatRegistry,
-    type_sets: &mut UniqueTable<'a, TypeSet>,
-    fmt: &mut Formatter,
-) {
-    // Unwrap the source instruction, create local variables for the input variables.
-    let replace_inst = unwrap_inst(&transform, format_registry, fmt);
-
-    // Emit any runtime checks; these will rebind `predicate` emitted by unwrap_inst().
-    for constraint in &transform.type_env.constraints {
-        emit_runtime_typecheck(constraint, type_sets, fmt);
-    }
-
-    // Guard the actual expansion by `predicate`.
-    fmt.line("if predicate {");
-    fmt.indent(|fmt| {
-        // If we're going to delete `inst`, we need to detach its results first so they can be
-        // reattached during pattern expansion.
-        if !replace_inst {
-            fmt.line("pos.func.dfg.clear_results(inst);");
-        }
-
-        // Emit the destination pattern.
-        for &def_index in &transform.dst {
-            emit_dst_inst(
-                transform.def_pool.get(def_index),
-                &transform.def_pool,
-                &transform.var_pool,
-                fmt,
-            );
-        }
-
-        // Delete the original instruction if we didn't have an opportunity to replace it.
-        if !replace_inst {
-            fmt.line("let removed = pos.remove_inst();");
-            fmt.line("debug_assert_eq!(removed, inst);");
-        }
-        fmt.line("return true;");
-    });
-    fmt.line("}");
-}
-
-fn gen_transform_group<'a>(
-    group: &'a TransformGroup,
-    format_registry: &FormatRegistry,
-    transform_groups: &TransformGroups,
-    type_sets: &mut UniqueTable<'a, TypeSet>,
-    fmt: &mut Formatter,
-) {
-    fmt.doc_comment(group.doc);
-    fmt.line("#[allow(unused_variables,unused_assignments,non_snake_case)]");
-
-    // Function arguments.
-    fmtln!(fmt, "pub fn {}(", group.name);
-    fmt.indent(|fmt| {
-        fmt.line("inst: crate::ir::Inst,");
-        fmt.line("func: &mut crate::ir::Function,");
-        fmt.line("cfg: &mut crate::flowgraph::ControlFlowGraph,");
-        fmt.line("isa: &crate::isa::TargetIsa,");
-    });
-    fmtln!(fmt, ") -> bool {");
-
-    // Function body.
-    fmt.indent(|fmt| {
-        fmt.line("use crate::ir::InstBuilder;");
-        fmt.line("use crate::cursor::{Cursor, FuncCursor};");
-        fmt.line("let mut pos = FuncCursor::new(func).at_inst(inst);");
-        fmt.line("pos.use_srcloc(inst);");
-
-        // Group the transforms by opcode so we can generate a big switch.
-        // Preserve ordering.
-        let mut inst_to_transforms = HashMap::new();
-        for transform in &group.transforms {
-            let def_index = transform.src;
-            let inst = &transform.def_pool.get(def_index).apply.inst;
-            inst_to_transforms
-                .entry(inst.camel_name.clone())
-                .or_insert(Vec::new())
-                .push(transform);
-        }
-
-        let mut sorted_inst_names = Vec::from_iter(inst_to_transforms.keys());
-        sorted_inst_names.sort();
-
-        fmt.line("{");
-        fmt.indent(|fmt| {
-            fmt.line("match pos.func.dfg[inst].opcode() {");
-            fmt.indent(|fmt| {
-                for camel_name in sorted_inst_names {
-                    fmtln!(fmt, "ir::Opcode::{} => {{", camel_name);
-                    fmt.indent(|fmt| {
-                        for transform in inst_to_transforms.get(camel_name).unwrap() {
-                            gen_transform(transform, format_registry, type_sets, fmt);
-                        }
-                    });
-                    fmtln!(fmt, "}");
-                    fmt.empty_line();
-                }
-
-                // Emit the custom transforms. The Rust compiler will complain about any overlap with
-                // the normal transforms.
-                for (inst_camel_name, func_name) in &group.custom_legalizes {
-                    fmtln!(fmt, "ir::Opcode::{} => {{", inst_camel_name);
-                    fmt.indent(|fmt| {
-                        fmtln!(fmt, "{}(inst, pos.func, cfg, isa);", func_name);
-                        fmt.line("return true;");
-                    });
-                    fmtln!(fmt, "}");
-                    fmt.empty_line();
-                }
-
-                // We'll assume there are uncovered opcodes.
-                fmt.line("_ => {},");
-            });
-            fmt.line("}");
-        });
-        fmt.line("}");
-
-        // If we fall through, nothing was expanded; call the chain if any.
-        match &group.chain_with {
-            Some(group_id) => fmtln!(
-                fmt,
-                "{}(inst, pos.func, cfg, isa)",
-                transform_groups.get(*group_id).rust_name()
-            ),
-            None => fmt.line("false"),
-        };
-    });
-    fmtln!(fmt, "}");
-    fmt.empty_line();
-}
-
-/// Generate legalization functions for `isa` and add any shared `TransformGroup`s
-/// encountered to `shared_groups`.
-///
-/// Generate `TYPE_SETS` and `LEGALIZE_ACTIONS` tables.
-fn gen_isa(
-    isa: &TargetIsa,
-    format_registry: &FormatRegistry,
-    transform_groups: &TransformGroups,
-    shared_group_names: &mut HashSet<&'static str>,
-    fmt: &mut Formatter,
-) {
-    let mut type_sets = UniqueTable::new();
-    for group_index in isa.transitive_transform_groups(transform_groups) {
-        let group = transform_groups.get(group_index);
-        match group.isa_name {
-            Some(isa_name) => {
-                assert!(
-                    isa_name == isa.name,
-                    "ISA-specific legalizations must be used by the same ISA"
-                );
-                gen_transform_group(
-                    group,
-                    format_registry,
-                    transform_groups,
-                    &mut type_sets,
-                    fmt,
-                );
-            }
-            None => {
-                shared_group_names.insert(group.name);
-            }
-        }
-    }
-
-    gen_typesets_table(&type_sets, fmt);
-
-    let direct_groups = isa.direct_transform_groups();
-    fmtln!(
-        fmt,
-        "pub static LEGALIZE_ACTIONS: [isa::Legalize; {}] = [",
-        direct_groups.len()
-    );
-    fmt.indent(|fmt| {
-        for group_index in direct_groups {
-            fmtln!(fmt, "{},", transform_groups.get(group_index).rust_name());
-        }
-    });
-    fmtln!(fmt, "];");
-}
-
-/// Generate the legalizer files.
-pub fn generate(
-    isas: &Vec<TargetIsa>,
-    format_registry: &FormatRegistry,
-    transform_groups: &TransformGroups,
-    filename_prefix: &str,
-    out_dir: &str,
-) -> Result<(), error::Error> {
-    let mut shared_group_names = HashSet::new();
-
-    for isa in isas {
-        let mut fmt = Formatter::new();
-        gen_isa(
-            isa,
-            format_registry,
-            transform_groups,
-            &mut shared_group_names,
-            &mut fmt,
-        );
-        fmt.update_file(format!("{}-{}.rs", filename_prefix, isa.name), out_dir)?;
-    }
-
-    // Generate shared legalize groups.
-    let mut fmt = Formatter::new();
-    let mut type_sets = UniqueTable::new();
-    let mut sorted_shared_group_names = Vec::from_iter(shared_group_names);
-    sorted_shared_group_names.sort();
-    for group_name in &sorted_shared_group_names {
-        let group = transform_groups.by_name(group_name);
-        gen_transform_group(
-            group,
-            format_registry,
-            transform_groups,
-            &mut type_sets,
-            &mut fmt,
-        );
-    }
-    gen_typesets_table(&type_sets, &mut fmt);
-    fmt.update_file(format!("{}r.rs", filename_prefix), out_dir)?;
-
-    Ok(())
-}
--- a/third_party/rust/cranelift-codegen-meta/src/isa/arm32/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/arm32/mod.rs
@@ -1,14 +1,12 @@
-use crate::cdsl::cpu_modes::CpuMode;
 use crate::cdsl::inst::InstructionGroup;
 use crate::cdsl::isa::TargetIsa;
 use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
 use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
-
 use crate::shared::Definitions as SharedDefinitions;
 
 fn define_settings(_shared: &SettingGroup) -> SettingGroup {
     let setting = SettingGroupBuilder::new("arm32");
     setting.finish()
 }
 
 fn define_regs() -> IsaRegs {
@@ -49,21 +47,10 @@ fn define_regs() -> IsaRegs {
 }
 
 pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
     let settings = define_settings(&shared_defs.settings);
     let regs = define_regs();
 
     let inst_group = InstructionGroup::new("arm32", "arm32 specific instruction set");
 
-    // CPU modes for 32-bit ARM and Thumb2.
-    let mut a32 = CpuMode::new("A32");
-    let mut t32 = CpuMode::new("T32");
-
-    // TODO refine these.
-    let narrow = shared_defs.transform_groups.by_name("narrow");
-    a32.legalize_default(narrow);
-    t32.legalize_default(narrow);
-
-    let cpu_modes = vec![a32, t32];
-
-    TargetIsa::new("arm32", inst_group, settings, regs, cpu_modes)
+    TargetIsa::new("arm32", inst_group, settings, regs)
 }
--- a/third_party/rust/cranelift-codegen-meta/src/isa/arm64/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/arm64/mod.rs
@@ -1,14 +1,12 @@
-use crate::cdsl::cpu_modes::CpuMode;
 use crate::cdsl::inst::InstructionGroup;
 use crate::cdsl::isa::TargetIsa;
 use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
 use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
-
 use crate::shared::Definitions as SharedDefinitions;
 
 fn define_settings(_shared: &SettingGroup) -> SettingGroup {
     let setting = SettingGroupBuilder::new("arm64");
     setting.finish()
 }
 
 fn define_registers() -> IsaRegs {
@@ -45,18 +43,10 @@ fn define_registers() -> IsaRegs {
 }
 
 pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
     let settings = define_settings(&shared_defs.settings);
     let regs = define_registers();
 
     let inst_group = InstructionGroup::new("arm64", "arm64 specific instruction set");
 
-    let mut a64 = CpuMode::new("A64");
-
-    // TODO refine these.
-    let narrow = shared_defs.transform_groups.by_name("narrow");
-    a64.legalize_default(narrow);
-
-    let cpu_modes = vec![a64];
-
-    TargetIsa::new("arm64", inst_group, settings, regs, cpu_modes)
+    TargetIsa::new("arm64", inst_group, settings, regs)
 }
--- a/third_party/rust/cranelift-codegen-meta/src/isa/riscv/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/riscv/mod.rs
@@ -1,16 +1,12 @@
-use crate::cdsl::cpu_modes::CpuMode;
 use crate::cdsl::inst::InstructionGroup;
 use crate::cdsl::isa::TargetIsa;
 use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
 use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
-
-use crate::shared::types::Float::{F32, F64};
-use crate::shared::types::Int::{I32, I64};
 use crate::shared::Definitions as SharedDefinitions;
 
 fn define_settings(shared: &SettingGroup) -> SettingGroup {
     let mut setting = SettingGroupBuilder::new("riscv");
 
     let supports_m = setting.add_bool(
         "supports_m",
         "CPU supports the 'M' extension (mul/div)",
@@ -83,31 +79,10 @@ fn define_registers() -> IsaRegs {
 }
 
 pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
     let settings = define_settings(&shared_defs.settings);
     let regs = define_registers();
 
     let inst_group = InstructionGroup::new("riscv", "riscv specific instruction set");
 
-    // CPU modes for 32-bit and 64-bit operation.
-    let mut rv_32 = CpuMode::new("RV32");
-    let mut rv_64 = CpuMode::new("RV64");
-
-    let expand = shared_defs.transform_groups.by_name("expand");
-    let narrow = shared_defs.transform_groups.by_name("narrow");
-    rv_32.legalize_monomorphic(expand);
-    rv_32.legalize_default(narrow);
-    rv_32.legalize_type(I32, expand);
-    rv_32.legalize_type(F32, expand);
-    rv_32.legalize_type(F64, expand);
-
-    rv_64.legalize_monomorphic(expand);
-    rv_64.legalize_default(narrow);
-    rv_64.legalize_type(I32, expand);
-    rv_64.legalize_type(I64, expand);
-    rv_64.legalize_type(F32, expand);
-    rv_64.legalize_type(F64, expand);
-
-    let cpu_modes = vec![rv_32, rv_64];
-
-    TargetIsa::new("riscv", inst_group, settings, regs, cpu_modes)
+    TargetIsa::new("riscv", inst_group, settings, regs)
 }
deleted file mode 100644
--- a/third_party/rust/cranelift-codegen-meta/src/isa/x86/legalize.rs
+++ /dev/null
@@ -1,293 +0,0 @@
-use crate::cdsl::ast::{bind, var, ExprBuilder, Literal};
-use crate::cdsl::inst::InstructionGroup;
-use crate::cdsl::xform::TransformGroupBuilder;
-
-use crate::shared::types::Int::{I32, I64};
-use crate::shared::Definitions as SharedDefinitions;
-
-pub fn define(shared: &mut SharedDefinitions, x86_instructions: &InstructionGroup) {
-    let mut group = TransformGroupBuilder::new(
-        "x86_expand",
-        r#"
-    Legalize instructions by expansion.
-
-    Use x86-specific instructions if needed."#,
-    )
-    .isa("x86")
-    .chain_with(shared.transform_groups.by_name("expand_flags").id);
-
-    // List of instructions.
-    let insts = &shared.instructions;
-    let band = insts.by_name("band");
-    let bor = insts.by_name("bor");
-    let clz = insts.by_name("clz");
-    let ctz = insts.by_name("ctz");
-    let fcmp = insts.by_name("fcmp");
-    let fcvt_from_uint = insts.by_name("fcvt_from_uint");
-    let fcvt_to_sint = insts.by_name("fcvt_to_sint");
-    let fcvt_to_uint = insts.by_name("fcvt_to_uint");
-    let fcvt_to_sint_sat = insts.by_name("fcvt_to_sint_sat");
-    let fcvt_to_uint_sat = insts.by_name("fcvt_to_uint_sat");
-    let fmax = insts.by_name("fmax");
-    let fmin = insts.by_name("fmin");
-    let iadd = insts.by_name("iadd");
-    let iconst = insts.by_name("iconst");
-    let imul = insts.by_name("imul");
-    let isub = insts.by_name("isub");
-    let popcnt = insts.by_name("popcnt");
-    let sdiv = insts.by_name("sdiv");
-    let selectif = insts.by_name("selectif");
-    let smulhi = insts.by_name("smulhi");
-    let srem = insts.by_name("srem");
-    let udiv = insts.by_name("udiv");
-    let umulhi = insts.by_name("umulhi");
-    let ushr_imm = insts.by_name("ushr_imm");
-    let urem = insts.by_name("urem");
-
-    let x86_bsf = x86_instructions.by_name("x86_bsf");
-    let x86_bsr = x86_instructions.by_name("x86_bsr");
-    let x86_umulx = x86_instructions.by_name("x86_umulx");
-    let x86_smulx = x86_instructions.by_name("x86_smulx");
-
-    // List of immediates.
-    let floatcc = shared.operand_kinds.by_name("floatcc");
-    let imm64 = shared.operand_kinds.by_name("imm64");
-    let intcc = shared.operand_kinds.by_name("intcc");
-
-    // Division and remainder.
-    //
-    // The srem expansion requires custom code because srem INT_MIN, -1 is not
-    // allowed to trap. The other ops need to check avoid_div_traps.
-    group.custom_legalize(sdiv, "expand_sdivrem");
-    group.custom_legalize(srem, "expand_sdivrem");
-    group.custom_legalize(udiv, "expand_udivrem");
-    group.custom_legalize(urem, "expand_udivrem");
-
-    // Double length (widening) multiplication.
-    let a = var("a");
-    let x = var("x");
-    let y = var("y");
-    let a1 = var("a1");
-    let a2 = var("a2");
-    let res_lo = var("res_lo");
-    let res_hi = var("res_hi");
-
-    group.legalize(
-        def!(res_hi = umulhi(x, y)),
-        vec![def!((res_lo, res_hi) = x86_umulx(x, y))],
-    );
-
-    group.legalize(
-        def!(res_hi = smulhi(x, y)),
-        vec![def!((res_lo, res_hi) = x86_smulx(x, y))],
-    );
-
-    // Floating point condition codes.
-    //
-    // The 8 condition codes in `supported_floatccs` are directly supported by a
-    // `ucomiss` or `ucomisd` instruction. The remaining codes need legalization
-    // patterns.
-
-    let floatcc_eq = Literal::enumerator_for(floatcc, "eq");
-    let floatcc_ord = Literal::enumerator_for(floatcc, "ord");
-    let floatcc_ueq = Literal::enumerator_for(floatcc, "ueq");
-    let floatcc_ne = Literal::enumerator_for(floatcc, "ne");
-    let floatcc_uno = Literal::enumerator_for(floatcc, "uno");
-    let floatcc_one = Literal::enumerator_for(floatcc, "one");
-
-    // Equality needs an explicit `ord` test which checks the parity bit.
-    group.legalize(
-        def!(a = fcmp(floatcc_eq, x, y)),
-        vec![
-            def!(a1 = fcmp(floatcc_ord, x, y)),
-            def!(a2 = fcmp(floatcc_ueq, x, y)),
-            def!(a = band(a1, a2)),
-        ],
-    );
-    group.legalize(
-        def!(a = fcmp(floatcc_ne, x, y)),
-        vec![
-            def!(a1 = fcmp(floatcc_uno, x, y)),
-            def!(a2 = fcmp(floatcc_one, x, y)),
-            def!(a = bor(a1, a2)),
-        ],
-    );
-
-    let floatcc_lt = &Literal::enumerator_for(floatcc, "lt");
-    let floatcc_gt = &Literal::enumerator_for(floatcc, "gt");
-    let floatcc_le = &Literal::enumerator_for(floatcc, "le");
-    let floatcc_ge = &Literal::enumerator_for(floatcc, "ge");
-    let floatcc_ugt = &Literal::enumerator_for(floatcc, "ugt");
-    let floatcc_ult = &Literal::enumerator_for(floatcc, "ult");
-    let floatcc_uge = &Literal::enumerator_for(floatcc, "uge");
-    let floatcc_ule = &Literal::enumerator_for(floatcc, "ule");
-
-    // Inequalities that need to be reversed.
-    for &(cc, rev_cc) in &[
-        (floatcc_lt, floatcc_gt),
-        (floatcc_le, floatcc_ge),
-        (floatcc_ugt, floatcc_ult),
-        (floatcc_uge, floatcc_ule),
-    ] {
-        group.legalize(def!(a = fcmp(cc, x, y)), vec![def!(a = fcmp(rev_cc, y, x))]);
-    }
-
-    // We need to modify the CFG for min/max legalization.
-    group.custom_legalize(fmin, "expand_minmax");
-    group.custom_legalize(fmax, "expand_minmax");
-
-    // Conversions from unsigned need special handling.
-    group.custom_legalize(fcvt_from_uint, "expand_fcvt_from_uint");
-    // Conversions from float to int can trap and modify the control flow graph.
-    group.custom_legalize(fcvt_to_sint, "expand_fcvt_to_sint");
-    group.custom_legalize(fcvt_to_uint, "expand_fcvt_to_uint");
-    group.custom_legalize(fcvt_to_sint_sat, "expand_fcvt_to_sint_sat");
-    group.custom_legalize(fcvt_to_uint_sat, "expand_fcvt_to_uint_sat");
-
-    // Count leading and trailing zeroes, for baseline x86_64
-    let c_minus_one = var("c_minus_one");
-    let c_thirty_one = var("c_thirty_one");
-    let c_thirty_two = var("c_thirty_two");
-    let c_sixty_three = var("c_sixty_three");
-    let c_sixty_four = var("c_sixty_four");
-    let index1 = var("index1");
-    let r2flags = var("r2flags");
-    let index2 = var("index2");
-
-    let intcc_eq = Literal::enumerator_for(intcc, "eq");
-    let imm64_minus_one = Literal::constant(imm64, -1);
-    let imm64_63 = Literal::constant(imm64, 63);
-    group.legalize(
-        def!(a = clz.I64(x)),
-        vec![
-            def!(c_minus_one = iconst(imm64_minus_one)),
-            def!(c_sixty_three = iconst(imm64_63)),
-            def!((index1, r2flags) = x86_bsr(x)),
-            def!(index2 = selectif(intcc_eq, r2flags, c_minus_one, index1)),
-            def!(a = isub(c_sixty_three, index2)),
-        ],
-    );
-
-    let imm64_31 = Literal::constant(imm64, 31);
-    group.legalize(
-        def!(a = clz.I32(x)),
-        vec![
-            def!(c_minus_one = iconst(imm64_minus_one)),
-            def!(c_thirty_one = iconst(imm64_31)),
-            def!((index1, r2flags) = x86_bsr(x)),
-            def!(index2 = selectif(intcc_eq, r2flags, c_minus_one, index1)),
-            def!(a = isub(c_thirty_one, index2)),
-        ],
-    );
-
-    let imm64_64 = Literal::constant(imm64, 64);
-    group.legalize(
-        def!(a = ctz.I64(x)),
-        vec![
-            def!(c_sixty_four = iconst(imm64_64)),
-            def!((index1, r2flags) = x86_bsf(x)),
-            def!(a = selectif(intcc_eq, r2flags, c_sixty_four, index1)),
-        ],
-    );
-
-    let imm64_32 = Literal::constant(imm64, 32);
-    group.legalize(
-        def!(a = ctz.I32(x)),
-        vec![
-            def!(c_thirty_two = iconst(imm64_32)),
-            def!((index1, r2flags) = x86_bsf(x)),
-            def!(a = selectif(intcc_eq, r2flags, c_thirty_two, index1)),
-        ],
-    );
-
-    // Population count for baseline x86_64
-    let qv1 = var("qv1");
-    let qv3 = var("qv3");
-    let qv4 = var("qv4");
-    let qv5 = var("qv5");
-    let qv6 = var("qv6");
-    let qv7 = var("qv7");
-    let qv8 = var("qv8");
-    let qv9 = var("qv9");
-    let qv10 = var("qv10");
-    let qv11 = var("qv11");
-    let qv12 = var("qv12");
-    let qv13 = var("qv13");
-    let qv14 = var("qv14");
-    let qv15 = var("qv15");
-    let qv16 = var("qv16");
-    let qc77 = var("qc77");
-    #[allow(non_snake_case)]
-    let qc0F = var("qc0F");
-    let qc01 = var("qc01");
-
-    let imm64_1 = Literal::constant(imm64, 1);
-    let imm64_4 = Literal::constant(imm64, 4);
-    group.legalize(
-        def!(qv16 = popcnt.I64(qv1)),
-        vec![
-            def!(qv3 = ushr_imm(qv1, imm64_1)),
-            def!(qc77 = iconst(Literal::constant(imm64, 0x7777777777777777))),
-            def!(qv4 = band(qv3, qc77)),
-            def!(qv5 = isub(qv1, qv4)),
-            def!(qv6 = ushr_imm(qv4, imm64_1)),
-            def!(qv7 = band(qv6, qc77)),
-            def!(qv8 = isub(qv5, qv7)),
-            def!(qv9 = ushr_imm(qv7, imm64_1)),
-            def!(qv10 = band(qv9, qc77)),
-            def!(qv11 = isub(qv8, qv10)),
-            def!(qv12 = ushr_imm(qv11, imm64_4)),
-            def!(qv13 = iadd(qv11, qv12)),
-            def!(qc0F = iconst(Literal::constant(imm64, 0x0F0F0F0F0F0F0F0F))),
-            def!(qv14 = band(qv13, qc0F)),
-            def!(qc01 = iconst(Literal::constant(imm64, 0x0101010101010101))),
-            def!(qv15 = imul(qv14, qc01)),
-            def!(qv16 = ushr_imm(qv15, Literal::constant(imm64, 56))),
-        ],
-    );
-
-    let lv1 = var("lv1");
-    let lv3 = var("lv3");
-    let lv4 = var("lv4");
-    let lv5 = var("lv5");
-    let lv6 = var("lv6");
-    let lv7 = var("lv7");
-    let lv8 = var("lv8");
-    let lv9 = var("lv9");
-    let lv10 = var("lv10");
-    let lv11 = var("lv11");
-    let lv12 = var("lv12");
-    let lv13 = var("lv13");
-    let lv14 = var("lv14");
-    let lv15 = var("lv15");
-    let lv16 = var("lv16");
-    let lc77 = var("lc77");
-    #[allow(non_snake_case)]
-    let lc0F = var("lc0F");
-    let lc01 = var("lc01");
-
-    group.legalize(
-        def!(lv16 = popcnt.I32(lv1)),
-        vec![
-            def!(lv3 = ushr_imm(lv1, imm64_1)),
-            def!(lc77 = iconst(Literal::constant(imm64, 0x77777777))),
-            def!(lv4 = band(lv3, lc77)),
-            def!(lv5 = isub(lv1, lv4)),
-            def!(lv6 = ushr_imm(lv4, imm64_1)),
-            def!(lv7 = band(lv6, lc77)),
-            def!(lv8 = isub(lv5, lv7)),
-            def!(lv9 = ushr_imm(lv7, imm64_1)),
-            def!(lv10 = band(lv9, lc77)),
-            def!(lv11 = isub(lv8, lv10)),
-            def!(lv12 = ushr_imm(lv11, imm64_4)),
-            def!(lv13 = iadd(lv11, lv12)),
-            def!(lc0F = iconst(Literal::constant(imm64, 0x0F0F0F0F))),
-            def!(lv14 = band(lv13, lc0F)),
-            def!(lc01 = iconst(Literal::constant(imm64, 0x01010101))),
-            def!(lv15 = imul(lv14, lc01)),
-            def!(lv16 = ushr_imm(lv15, Literal::constant(imm64, 24))),
-        ],
-    );
-
-    group.finish_and_add_to(&mut shared.transform_groups);
-}
--- a/third_party/rust/cranelift-codegen-meta/src/isa/x86/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/x86/mod.rs
@@ -1,21 +1,16 @@
-use crate::cdsl::cpu_modes::CpuMode;
+mod instructions;
+
 use crate::cdsl::isa::TargetIsa;
 use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder};
 use crate::cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
 
-use crate::shared::types::Bool::B1;
-use crate::shared::types::Float::{F32, F64};
-use crate::shared::types::Int::{I16, I32, I64, I8};
 use crate::shared::Definitions as SharedDefinitions;
 
-mod instructions;
-mod legalize;
-
 fn define_settings(_shared: &SettingGroup) -> SettingGroup {
     let mut settings = SettingGroupBuilder::new("x86");
 
     // CPUID.01H:ECX
     let has_sse3 = settings.add_bool("has_sse3", "SSE3: CPUID.01H:ECX.SSE3[bit 0]", false);
     let has_ssse3 = settings.add_bool("has_ssse3", "SSSE3: CPUID.01H:ECX.SSSE3[bit 9]", false);
     let has_sse41 = settings.add_bool("has_sse41", "SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]", false);
     let has_sse42 = settings.add_bool("has_sse42", "SSE4.2: CPUID.01H:ECX.SSE4_2[bit 20]", false);
@@ -118,42 +113,11 @@ fn define_registers() -> IsaRegs {
     regs.finish()
 }
 
 pub fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa {
     let settings = define_settings(&shared_defs.settings);
     let regs = define_registers();
 
     let inst_group = instructions::define(&shared_defs.format_registry);
-    legalize::define(shared_defs, &inst_group);
 
-    // CPU modes for 32-bit and 64-bit operations.
-    let mut x86_64 = CpuMode::new("I64");
-    let mut x86_32 = CpuMode::new("I32");
-
-    let expand_flags = shared_defs.transform_groups.by_name("expand_flags");
-    let narrow = shared_defs.transform_groups.by_name("narrow");
-    let widen = shared_defs.transform_groups.by_name("widen");
-    let x86_expand = shared_defs.transform_groups.by_name("x86_expand");
-
-    x86_32.legalize_monomorphic(expand_flags);
-    x86_32.legalize_default(narrow);
-    x86_32.legalize_type(B1, expand_flags);
-    x86_32.legalize_type(I8, widen);
-    x86_32.legalize_type(I16, widen);
-    x86_32.legalize_type(I32, x86_expand);
-    x86_32.legalize_type(F32, x86_expand);
-    x86_32.legalize_type(F64, x86_expand);
-
-    x86_64.legalize_monomorphic(expand_flags);
-    x86_64.legalize_default(narrow);
-    x86_64.legalize_type(B1, expand_flags);
-    x86_64.legalize_type(I8, widen);
-    x86_64.legalize_type(I16, widen);
-    x86_64.legalize_type(I32, x86_expand);
-    x86_64.legalize_type(I64, x86_expand);
-    x86_64.legalize_type(F32, x86_expand);
-    x86_64.legalize_type(F64, x86_expand);
-
-    let cpu_modes = vec![x86_64, x86_32];
-
-    TargetIsa::new("x86", inst_group, settings, regs, cpu_modes)
+    TargetIsa::new("x86", inst_group, settings, regs)
 }
--- a/third_party/rust/cranelift-codegen-meta/src/lib.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/lib.rs
@@ -1,17 +1,16 @@
 #[macro_use]
 mod cdsl;
 mod srcgen;
 
 pub mod error;
 pub mod isa;
 
 mod gen_inst;
-mod gen_legalizer;
 mod gen_registers;
 mod gen_settings;
 mod gen_types;
 
 mod constant_hash;
 mod shared;
 mod unique_table;
 
@@ -41,24 +40,16 @@ pub fn generate(isas: &Vec<isa::Isa>, ou
     gen_inst::generate(
         all_inst_groups,
         &shared_defs.format_registry,
         "opcodes.rs",
         "inst_builder.rs",
         &out_dir,
     )?;
 
-    gen_legalizer::generate(
-        &isas,
-        &shared_defs.format_registry,
-        &shared_defs.transform_groups,
-        "new_legalize",
-        &out_dir,
-    )?;
-
     for isa in isas {
         gen_registers::generate(&isa, &format!("registers-{}.rs", isa.name), &out_dir)?;
         gen_settings::generate(
             &isa.settings,
             gen_settings::ParentGroup::Shared,
             &format!("new_settings-{}", isa.name),
             &out_dir,
         )?;
--- a/third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/shared/immediates.rs
@@ -66,20 +66,20 @@ pub fn define() -> Vec<OperandKind> {
     kinds.push(boolean);
 
     // A condition code for comparing integer values.
     // This enumerated operand kind is used for the `icmp` instruction and corresponds to the
     // condcodes::IntCC` Rust type.
     let mut intcc_values = HashMap::new();
     intcc_values.insert("eq", "Equal");
     intcc_values.insert("ne", "NotEqual");
-    intcc_values.insert("sge", "SignedGreaterThanOrEqual");
-    intcc_values.insert("sgt", "SignedGreaterThan");
-    intcc_values.insert("sle", "SignedLessThanOrEqual");
-    intcc_values.insert("slt", "SignedLessThan");
+    intcc_values.insert("sge", "UnsignedGreaterThanOrEqual");
+    intcc_values.insert("sgt", "UnsignedGreaterThan");
+    intcc_values.insert("sle", "UnsignedLessThanOrEqual");
+    intcc_values.insert("slt", "UnsignedLessThan");
     intcc_values.insert("uge", "UnsignedGreaterThanOrEqual");
     intcc_values.insert("ugt", "UnsignedGreaterThan");
     intcc_values.insert("ule", "UnsignedLessThanOrEqual");
     intcc_values.insert("ult", "UnsignedLessThan");
     let intcc = Builder::new_enum("intcc", intcc_values)
         .doc("An integer comparison condition code.")
         .default_member("cond")
         .rust_type("ir::condcodes::IntCC")
deleted file mode 100644
--- a/third_party/rust/cranelift-codegen-meta/src/shared/legalize.rs
+++ /dev/null
@@ -1,785 +0,0 @@
-use crate::cdsl::ast::{bind, var, ExprBuilder, Literal};
-use crate::cdsl::inst::{Instruction, InstructionGroup};
-use crate::cdsl::xform::{TransformGroupBuilder, TransformGroups};
-
-use crate::shared::OperandKinds;
-
-use crate::shared::types::Float::{F32, F64};
-use crate::shared::types::Int::{I16, I32, I64, I8};
-
-pub fn define(insts: &InstructionGroup, immediates: &OperandKinds) -> TransformGroups {
-    let mut narrow = TransformGroupBuilder::new(
-        "narrow",
-        r#"
-        Legalize instructions by narrowing.
-
-        The transformations in the 'narrow' group work by expressing
-        instructions in terms of smaller types. Operations on vector types are
-        expressed in terms of vector types with fewer lanes, and integer
-        operations are expressed in terms of smaller integer types.
-    "#,
-    );
-
-    let mut widen = TransformGroupBuilder::new(
-        "widen",
-        r#"
-        Legalize instructions by widening.
-
-        The transformations in the 'widen' group work by expressing
-        instructions in terms of larger types.
-    "#,
-    );
-
-    let mut expand = TransformGroupBuilder::new(
-        "expand",
-        r#"
-        Legalize instructions by expansion.
-
-        Rewrite instructions in terms of other instructions, generally
-        operating on the same types as the original instructions.
-    "#,
-    );
-
-    // List of instructions.
-    let band = insts.by_name("band");
-    let band_imm = insts.by_name("band_imm");
-    let band_not = insts.by_name("band_not");
-    let bint = insts.by_name("bint");
-    let bitrev = insts.by_name("bitrev");
-    let bnot = insts.by_name("bnot");
-    let bor = insts.by_name("bor");
-    let bor_imm = insts.by_name("bor_imm");
-    let bor_not = insts.by_name("bor_not");
-    let br_icmp = insts.by_name("br_icmp");
-    let br_table = insts.by_name("br_table");
-    let bxor = insts.by_name("bxor");
-    let bxor_imm = insts.by_name("bxor_imm");
-    let bxor_not = insts.by_name("bxor_not");
-    let cls = insts.by_name("cls");
-    let clz = insts.by_name("clz");
-    let ctz = insts.by_name("ctz");
-    let fabs = insts.by_name("fabs");
-    let f32const = insts.by_name("f32const");
-    let f64const = insts.by_name("f64const");
-    let fcopysign = insts.by_name("fcopysign");
-    let fneg = insts.by_name("fneg");
-    let iadd = insts.by_name("iadd");
-    let iadd_carry = insts.by_name("iadd_carry");
-    let iadd_cin = insts.by_name("iadd_cin");
-    let iadd_cout = insts.by_name("iadd_cout");
-    let iadd_imm = insts.by_name("iadd_imm");
-    let icmp = insts.by_name("icmp");
-    let icmp_imm = insts.by_name("icmp_imm");
-    let iconcat = insts.by_name("iconcat");
-    let iconst = insts.by_name("iconst");
-    let ifcmp = insts.by_name("ifcmp");
-    let ifcmp_imm = insts.by_name("ifcmp_imm");
-    let imul = insts.by_name("imul");
-    let imul_imm = insts.by_name("imul_imm");
-    let ireduce = insts.by_name("ireduce");
-    let irsub_imm = insts.by_name("irsub_imm");
-    let ishl = insts.by_name("ishl");
-    let ishl_imm = insts.by_name("ishl_imm");
-    let isplit = insts.by_name("isplit");
-    let istore8 = insts.by_name("istore8");
-    let istore16 = insts.by_name("istore16");
-    let isub = insts.by_name("isub");
-    let isub_bin = insts.by_name("isub_bin");
-    let isub_borrow = insts.by_name("isub_borrow");
-    let isub_bout = insts.by_name("isub_bout");
-    let load = insts.by_name("load");
-    let popcnt = insts.by_name("popcnt");
-    let rotl = insts.by_name("rotl");
-    let rotl_imm = insts.by_name("rotl_imm");
-    let rotr = insts.by_name("rotr");
-    let rotr_imm = insts.by_name("rotr_imm");
-    let sdiv = insts.by_name("sdiv");
-    let sdiv_imm = insts.by_name("sdiv_imm");
-    let select = insts.by_name("select");
-    let sextend = insts.by_name("sextend");
-    let sshr = insts.by_name("sshr");
-    let sshr_imm = insts.by_name("sshr_imm");
-    let srem = insts.by_name("srem");
-    let srem_imm = insts.by_name("srem_imm");
-    let store = insts.by_name("store");
-    let udiv = insts.by_name("udiv");
-    let udiv_imm = insts.by_name("udiv_imm");
-    let uextend = insts.by_name("uextend");
-    let uload8 = insts.by_name("uload8");
-    let uload16 = insts.by_name("uload16");
-    let ushr = insts.by_name("ushr");
-    let ushr_imm = insts.by_name("ushr_imm");
-    let urem = insts.by_name("urem");
-    let urem_imm = insts.by_name("urem_imm");
-    let trapif = insts.by_name("trapif");
-    let trapnz = insts.by_name("trapnz");
-    let trapz = insts.by_name("trapz");
-
-    // Custom expansions for memory objects.
-    expand.custom_legalize(insts.by_name("global_value"), "expand_global_value");
-    expand.custom_legalize(insts.by_name("heap_addr"), "expand_heap_addr");
-    expand.custom_legalize(insts.by_name("table_addr"), "expand_table_addr");
-
-    // Custom expansions for calls.
-    expand.custom_legalize(insts.by_name("call"), "expand_call");
-
-    // Custom expansions that need to change the CFG.
-    // TODO: Add sufficient XForm syntax that we don't need to hand-code these.
-    expand.custom_legalize(trapz, "expand_cond_trap");
-    expand.custom_legalize(trapnz, "expand_cond_trap");
-    expand.custom_legalize(br_table, "expand_br_table");
-    expand.custom_legalize(select, "expand_select");
-
-    // Custom expansions for floating point constants.
-    // These expansions require bit-casting or creating constant pool entries.
-    expand.custom_legalize(f32const, "expand_fconst");
-    expand.custom_legalize(f64const, "expand_fconst");
-
-    // Custom expansions for stack memory accesses.
-    expand.custom_legalize(insts.by_name("stack_load"), "expand_stack_load");
-    expand.custom_legalize(insts.by_name("stack_store"), "expand_stack_store");
-
-    // List of immediates.
-    let imm64 = immediates.by_name("imm64");
-    let ieee32 = immediates.by_name("ieee32");
-    let ieee64 = immediates.by_name("ieee64");
-    let intcc = immediates.by_name("intcc");
-
-    // List of variables to reuse in patterns.
-    let x = var("x");
-    let y = var("y");
-    let z = var("z");
-    let a = var("a");
-    let a1 = var("a1");
-    let a2 = var("a2");
-    let a3 = var("a3");
-    let a4 = var("a4");
-    let b = var("b");
-    let b1 = var("b1");
-    let b2 = var("b2");
-    let b3 = var("b3");
-    let b4 = var("b4");
-    let b_in = var("b_in");
-    let b_int = var("b_int");
-    let c = var("c");
-    let c1 = var("c1");
-    let c2 = var("c2");
-    let c3 = var("c3");
-    let c4 = var("c4");
-    let c_in = var("c_in");
-    let c_int = var("c_int");
-    let d = var("d");
-    let d1 = var("d1");
-    let d2 = var("d2");
-    let d3 = var("d3");
-    let d4 = var("d4");
-    let e = var("e");
-    let e1 = var("e1");
-    let e2 = var("e2");
-    let e3 = var("e3");
-    let e4 = var("e4");
-    let f = var("f");
-    let f1 = var("f1");
-    let f2 = var("f2");
-    let xl = var("xl");
-    let xh = var("xh");
-    let yl = var("yl");
-    let yh = var("yh");
-    let al = var("al");
-    let ah = var("ah");
-    let cc = var("cc");
-    let ptr = var("ptr");
-    let flags = var("flags");
-    let offset = var("off");
-
-    narrow.legalize(
-        def!(a = iadd(x, y)),
-        vec![
-            def!((xl, xh) = isplit(x)),
-            def!((yl, yh) = isplit(y)),
-            def!((al, c) = iadd_cout(xl, yl)),
-            def!(ah = iadd_cin(xh, yh, c)),
-            def!(a = iconcat(al, ah)),
-        ],
-    );
-
-    narrow.legalize(
-        def!(a = isub(x, y)),
-        vec![
-            def!((xl, xh) = isplit(x)),
-            def!((yl, yh) = isplit(y)),
-            def!((al, b) = isub_bout(xl, yl)),
-            def!(ah = isub_bin(xh, yh, b)),
-            def!(a = iconcat(al, ah)),
-        ],
-    );
-
-    for &bin_op in &[band, bor, bxor] {
-        narrow.legalize(
-            def!(a = bin_op(x, y)),
-            vec![
-                def!((xl, xh) = isplit(x)),
-                def!((yl, yh) = isplit(y)),
-                def!(al = bin_op(xl, yl)),
-                def!(ah = bin_op(xh, yh)),
-                def!(a = iconcat(al, ah)),
-            ],
-        );
-    }
-
-    narrow.legalize(
-        def!(a = select(c, x, y)),
-        vec![
-            def!((xl, xh) = isplit(x)),
-            def!((yl, yh) = isplit(y)),
-            def!(al = select(c, xl, yl)),
-            def!(ah = select(c, xh, yh)),
-            def!(a = iconcat(al, ah)),
-        ],
-    );
-
-    // Widen instructions with one input operand.
-    for &op in &[bnot, popcnt] {
-        for &int_ty in &[I8, I16] {
-            widen.legalize(
-                def!(a = op.int_ty(b)),
-                vec![
-                    def!(x = uextend.I32(b)),
-                    def!(z = op.I32(x)),
-                    def!(a = ireduce.int_ty(z)),
-                ],
-            );
-        }
-    }
-
-    // Widen instructions with two input operands.
-    let mut widen_two_arg = |signed: bool, op: &Instruction| {
-        for &int_ty in &[I8, I16] {
-            let sign_ext_op = if signed { sextend } else { uextend };
-            widen.legalize(
-                def!(a = op.int_ty(b, c)),
-                vec![
-                    def!(x = sign_ext_op.I32(b)),
-                    def!(y = sign_ext_op.I32(c)),
-                    def!(z = op.I32(x, y)),
-                    def!(a = ireduce.int_ty(z)),
-                ],
-            );
-        }
-    };
-
-    for bin_op in &[
-        iadd, isub, imul, udiv, urem, band, bor, bxor, band_not, bor_not, bxor_not,
-    ] {
-        widen_two_arg(false, bin_op);
-    }
-    for bin_op in &[sdiv, srem] {
-        widen_two_arg(true, bin_op);
-    }
-
-    // Widen instructions using immediate operands.
-    let mut widen_imm = |signed: bool, op: &Instruction| {
-        for &int_ty in &[I8, I16] {
-            let sign_ext_op = if signed { sextend } else { uextend };
-            widen.legalize(
-                def!(a = op.int_ty(b, c)),
-                vec![
-                    def!(x = sign_ext_op.I32(b)),
-                    def!(z = op.I32(x, c)),
-                    def!(a = ireduce.int_ty(z)),
-                ],
-            );
-        }
-    };
-
-    for bin_op in &[
-        iadd_imm, imul_imm, udiv_imm, urem_imm, band_imm, bor_imm, bxor_imm, irsub_imm,
-    ] {
-        widen_imm(false, bin_op);
-    }
-    for bin_op in &[sdiv_imm, srem_imm] {
-        widen_imm(true, bin_op);
-    }
-
-    for &(int_ty, num) in &[(I8, 24), (I16, 16)] {
-        let imm = Literal::constant(imm64, -num);
-
-        widen.legalize(
-            def!(a = clz.int_ty(b)),
-            vec![
-                def!(c = uextend.I32(b)),
-                def!(d = clz.I32(c)),
-                def!(e = iadd_imm(d, imm)),
-                def!(a = ireduce.int_ty(e)),
-            ],
-        );
-
-        widen.legalize(
-            def!(a = cls.int_ty(b)),
-            vec![
-                def!(c = sextend.I32(b)),
-                def!(d = cls.I32(c)),
-                def!(e = iadd_imm(d, imm)),
-                def!(a = ireduce.int_ty(e)),
-            ],
-        );
-    }
-
-    for &(int_ty, num) in &[(I8, 1 << 8), (I16, 1 << 16)] {
-        let num = Literal::constant(imm64, num);
-        widen.legalize(
-            def!(a = ctz.int_ty(b)),
-            vec![
-                def!(c = uextend.I32(b)),
-                // When `b` is zero, returns the size of x in bits.
-                def!(d = bor_imm(c, num)),
-                def!(e = ctz.I32(d)),
-                def!(a = ireduce.int_ty(e)),
-            ],
-        );
-    }
-
-    // iconst
-    for &int_ty in &[I8, I16] {
-        widen.legalize(
-            def!(a = iconst.int_ty(b)),
-            vec![def!(c = iconst.I32(b)), def!(a = ireduce.int_ty(c))],
-        );
-    }
-
-    for &extend_op in &[uextend, sextend] {
-        // The sign extension operators have two typevars: the result has one and controls the
-        // instruction, then the input has one.
-        let bound = bind(bind(extend_op, I16), I8);
-        widen.legalize(
-            def!(a = bound(b)),
-            vec![def!(c = extend_op.I32(b)), def!(a = ireduce(c))],
-        );
-    }
-
-    widen.legalize(
-        def!(store.I8(flags, a, ptr, offset)),
-        vec![
-            def!(b = uextend.I32(a)),
-            def!(istore8(flags, b, ptr, offset)),
-        ],
-    );
-
-    widen.legalize(
-        def!(store.I16(flags, a, ptr, offset)),
-        vec![
-            def!(b = uextend.I32(a)),
-            def!(istore16(flags, b, ptr, offset)),
-        ],
-    );
-
-    widen.legalize(
-        def!(a = load.I8(flags, ptr, offset)),
-        vec![
-            def!(b = uload8.I32(flags, ptr, offset)),
-            def!(a = ireduce(b)),
-        ],
-    );
-
-    widen.legalize(
-        def!(a = load.I16(flags, ptr, offset)),
-        vec![
-            def!(b = uload16.I32(flags, ptr, offset)),
-            def!(a = ireduce(b)),
-        ],
-    );
-
-    for &int_ty in &[I8, I16] {
-        widen.legalize(
-            def!(br_table.int_ty(x, y, z)),
-            vec![def!(b = uextend.I32(x)), def!(br_table(b, y, z))],
-        );
-    }
-
-    for &int_ty in &[I8, I16] {
-        widen.legalize(
-            def!(a = bint.int_ty(b)),
-            vec![def!(x = bint.I32(b)), def!(a = ireduce.int_ty(x))],
-        );
-    }
-
-    for &int_ty in &[I8, I16] {
-        for &op in &[ishl, ishl_imm, ushr, ushr_imm] {
-            widen.legalize(
-                def!(a = op.int_ty(b, c)),
-                vec![
-                    def!(x = uextend.I32(b)),
-                    def!(z = op.I32(x, c)),
-                    def!(a = ireduce.int_ty(z)),
-                ],
-            );
-        }
-
-        for &op in &[sshr, sshr_imm] {
-            widen.legalize(
-                def!(a = op.int_ty(b, c)),
-                vec![
-                    def!(x = sextend.I32(b)),
-                    def!(z = op.I32(x, c)),
-                    def!(a = ireduce.int_ty(z)),
-                ],
-            );
-        }
-
-        for cc in &["eq", "ne", "ugt", "ult", "uge", "ule"] {
-            let w_cc = Literal::enumerator_for(intcc, cc);
-            widen.legalize(
-                def!(a = icmp_imm.int_ty(w_cc, b, c)),
-                vec![def!(x = uextend.I32(b)), def!(a = icmp_imm(w_cc, x, c))],
-            );
-            widen.legalize(
-                def!(a = icmp.int_ty(w_cc, b, c)),
-                vec![
-                    def!(x = uextend.I32(b)),
-                    def!(y = uextend.I32(c)),
-                    def!(a = icmp.I32(w_cc, x, y)),
-                ],
-            );
-        }
-
-        for cc in &["sgt", "slt", "sge", "sle"] {
-            let w_cc = Literal::enumerator_for(intcc, cc);
-            widen.legalize(
-                def!(a = icmp_imm.int_ty(w_cc, b, c)),
-                vec![def!(x = sextend.I32(b)), def!(a = icmp_imm(w_cc, x, c))],
-            );
-
-            widen.legalize(
-                def!(a = icmp.int_ty(w_cc, b, c)),
-                vec![
-                    def!(x = sextend.I32(b)),
-                    def!(y = sextend.I32(c)),
-                    def!(a = icmp(w_cc, x, y)),
-                ],
-            );
-        }
-    }
-
-    // Expand integer operations with carry for RISC architectures that don't have
-    // the flags.
-    let intcc_ult = Literal::enumerator_for(intcc, "ult");
-    expand.legalize(
-        def!((a, c) = iadd_cout(x, y)),
-        vec![def!(a = iadd(x, y)), def!(c = icmp(intcc_ult, a, x))],
-    );
-
-    let intcc_ugt = Literal::enumerator_for(intcc, "ugt");
-    expand.legalize(
-        def!((a, b) = isub_bout(x, y)),
-        vec![def!(a = isub(x, y)), def!(b = icmp(intcc_ugt, a, x))],
-    );
-
-    expand.legalize(
-        def!(a = iadd_cin(x, y, c)),
-        vec![
-            def!(a1 = iadd(x, y)),
-            def!(c_int = bint(c)),
-            def!(a = iadd(a1, c_int)),
-        ],
-    );
-
-    expand.legalize(
-        def!(a = isub_bin(x, y, b)),
-        vec![
-            def!(a1 = isub(x, y)),
-            def!(b_int = bint(b)),
-            def!(a = isub(a1, b_int)),
-        ],
-    );
-
-    expand.legalize(
-        def!((a, c) = iadd_carry(x, y, c_in)),
-        vec![
-            def!((a1, c1) = iadd_cout(x, y)),
-            def!(c_int = bint(c_in)),
-            def!((a, c2) = iadd_cout(a1, c_int)),
-            def!(c = bor(c1, c2)),
-        ],
-    );
-
-    expand.legalize(
-        def!((a, b) = isub_borrow(x, y, b_in)),
-        vec![
-            def!((a1, b1) = isub_bout(x, y)),
-            def!(b_int = bint(b_in)),
-            def!((a, b2) = isub_bout(a1, b_int)),
-            def!(b = bor(b1, b2)),
-        ],
-    );
-
-    // Expansions for immediate operands that are out of range.
-    for &(inst_imm, inst) in &[
-        (iadd_imm, iadd),
-        (imul_imm, imul),
-        (sdiv_imm, sdiv),
-        (udiv_imm, udiv),
-        (srem_imm, srem),
-        (urem_imm, urem),
-        (band_imm, band),
-        (bor_imm, bor),
-        (bxor_imm, bxor),
-        (ifcmp_imm, ifcmp),
-    ] {
-        expand.legalize(
-            def!(a = inst_imm(x, y)),
-            vec![def!(a1 = iconst(y)), def!(a = inst(x, a1))],
-        );
-    }
-
-    expand.legalize(
-        def!(a = irsub_imm(y, x)),
-        vec![def!(a1 = iconst(x)), def!(a = isub(a1, y))],
-    );
-
-    // Rotates and shifts.
-    for &(inst_imm, inst) in &[
-        (rotl_imm, rotl),
-        (rotr_imm, rotr),
-        (ishl_imm, ishl),
-        (sshr_imm, sshr),
-        (ushr_imm, ushr),
-    ] {
-        expand.legalize(
-            def!(a = inst_imm(x, y)),
-            vec![def!(a1 = iconst.I32(y)), def!(a = inst(x, a1))],
-        );
-    }
-
-    expand.legalize(
-        def!(a = icmp_imm(cc, x, y)),
-        vec![def!(a1 = iconst(y)), def!(a = icmp(cc, x, a1))],
-    );
-
-    //# Expansions for *_not variants of bitwise ops.
-    for &(inst_not, inst) in &[(band_not, band), (bor_not, bor), (bxor_not, bxor)] {
-        expand.legalize(
-            def!(a = inst_not(x, y)),
-            vec![def!(a1 = bnot(y)), def!(a = inst(x, a1))],
-        );
-    }
-
-    //# Expand bnot using xor.
-    let minus_one = Literal::constant(imm64, -1);
-    expand.legalize(
-        def!(a = bnot(x)),
-        vec![def!(y = iconst(minus_one)), def!(a = bxor(x, y))],
-    );
-
-    //# Expand bitrev
-    //# Adapted from Stack Overflow.
-    //# https://stackoverflow.com/questions/746171/most-efficient-algorithm-for-bit-reversal-from-msb-lsb-to-lsb-msb-in-c
-    let imm64_1 = Literal::constant(imm64, 1);
-    let imm64_2 = Literal::constant(imm64, 2);
-    let imm64_4 = Literal::constant(imm64, 4);
-
-    widen.legalize(
-        def!(a = bitrev.I8(x)),
-        vec![
-            def!(a1 = band_imm(x, Literal::constant(imm64, 0xaa))),
-            def!(a2 = ushr_imm(a1, imm64_1)),
-            def!(a3 = band_imm(x, Literal::constant(imm64, 0x55))),
-            def!(a4 = ishl_imm(a3, imm64_1)),
-            def!(b = bor(a2, a4)),
-            def!(b1 = band_imm(b, Literal::constant(imm64, 0xcc))),
-            def!(b2 = ushr_imm(b1, imm64_2)),
-            def!(b3 = band_imm(b, Literal::constant(imm64, 0x33))),
-            def!(b4 = ishl_imm(b3, imm64_2)),
-            def!(c = bor(b2, b4)),
-            def!(c1 = band_imm(c, Literal::constant(imm64, 0xf0))),
-            def!(c2 = ushr_imm(c1, imm64_4)),
-            def!(c3 = band_imm(c, Literal::constant(imm64, 0x0f))),
-            def!(c4 = ishl_imm(c3, imm64_4)),
-            def!(a = bor(c2, c4)),
-        ],
-    );
-
-    let imm64_8 = Literal::constant(imm64, 8);
-
-    widen.legalize(
-        def!(a = bitrev.I16(x)),
-        vec![
-            def!(a1 = band_imm(x, Literal::constant(imm64, 0xaaaa))),
-            def!(a2 = ushr_imm(a1, imm64_1)),
-            def!(a3 = band_imm(x, Literal::constant(imm64, 0x5555))),
-            def!(a4 = ishl_imm(a3, imm64_1)),
-            def!(b = bor(a2, a4)),
-            def!(b1 = band_imm(b, Literal::constant(imm64, 0xcccc))),
-            def!(b2 = ushr_imm(b1, imm64_2)),
-            def!(b3 = band_imm(b, Literal::constant(imm64, 0x3333))),
-            def!(b4 = ishl_imm(b3, imm64_2)),
-            def!(c = bor(b2, b4)),
-            def!(c1 = band_imm(c, Literal::constant(imm64, 0xf0f0))),
-            def!(c2 = ushr_imm(c1, imm64_4)),
-            def!(c3 = band_imm(c, Literal::constant(imm64, 0x0f0f))),
-            def!(c4 = ishl_imm(c3, imm64_4)),
-            def!(d = bor(c2, c4)),
-            def!(d1 = band_imm(d, Literal::constant(imm64, 0xff00))),
-            def!(d2 = ushr_imm(d1, imm64_8)),
-            def!(d3 = band_imm(d, Literal::constant(imm64, 0x00ff))),
-            def!(d4 = ishl_imm(d3, imm64_8)),
-            def!(a = bor(d2, d4)),
-        ],
-    );
-
-    let imm64_16 = Literal::constant(imm64, 16);
-
-    expand.legalize(
-        def!(a = bitrev.I32(x)),
-        vec![
-            def!(a1 = band_imm(x, Literal::constant(imm64, 0xaaaaaaaa))),
-            def!(a2 = ushr_imm(a1, imm64_1)),
-            def!(a3 = band_imm(x, Literal::constant(imm64, 0x55555555))),
-            def!(a4 = ishl_imm(a3, imm64_1)),
-            def!(b = bor(a2, a4)),
-            def!(b1 = band_imm(b, Literal::constant(imm64, 0xcccccccc))),
-            def!(b2 = ushr_imm(b1, imm64_2)),
-            def!(b3 = band_imm(b, Literal::constant(imm64, 0x33333333))),
-            def!(b4 = ishl_imm(b3, imm64_2)),
-            def!(c = bor(b2, b4)),
-            def!(c1 = band_imm(c, Literal::constant(imm64, 0xf0f0f0f0))),
-            def!(c2 = ushr_imm(c1, imm64_4)),
-            def!(c3 = band_imm(c, Literal::constant(imm64, 0x0f0f0f0f))),
-            def!(c4 = ishl_imm(c3, imm64_4)),
-            def!(d = bor(c2, c4)),
-            def!(d1 = band_imm(d, Literal::constant(imm64, 0xff00ff00))),
-            def!(d2 = ushr_imm(d1, imm64_8)),
-            def!(d3 = band_imm(d, Literal::constant(imm64, 0x00ff00ff))),
-            def!(d4 = ishl_imm(d3, imm64_8)),
-            def!(e = bor(d2, d4)),
-            def!(e1 = ushr_imm(e, imm64_16)),
-            def!(e2 = ishl_imm(e, imm64_16)),
-            def!(a = bor(e1, e2)),
-        ],
-    );
-
-    #[allow(overflowing_literals)]
-    let imm64_0xaaaaaaaaaaaaaaaa = Literal::constant(imm64, 0xaaaaaaaaaaaaaaaa);
-    let imm64_0x5555555555555555 = Literal::constant(imm64, 0x5555555555555555);
-    #[allow(overflowing_literals)]
-    let imm64_0xcccccccccccccccc = Literal::constant(imm64, 0xcccccccccccccccc);
-    let imm64_0x3333333333333333 = Literal::constant(imm64, 0x3333333333333333);
-    #[allow(overflowing_literals)]
-    let imm64_0xf0f0f0f0f0f0f0f0 = Literal::constant(imm64, 0xf0f0f0f0f0f0f0f0);
-    let imm64_0x0f0f0f0f0f0f0f0f = Literal::constant(imm64, 0x0f0f0f0f0f0f0f0f);
-    #[allow(overflowing_literals)]
-    let imm64_0xff00ff00ff00ff00 = Literal::constant(imm64, 0xff00ff00ff00ff00);
-    let imm64_0x00ff00ff00ff00ff = Literal::constant(imm64, 0x00ff00ff00ff00ff);
-    #[allow(overflowing_literals)]
-    let imm64_0xffff0000ffff0000 = Literal::constant(imm64, 0xffff0000ffff0000);
-    let imm64_0x0000ffff0000ffff = Literal::constant(imm64, 0x0000ffff0000ffff);
-    let imm64_32 = Literal::constant(imm64, 32);
-
-    expand.legalize(
-        def!(a = bitrev.I64(x)),
-        vec![
-            def!(a1 = band_imm(x, imm64_0xaaaaaaaaaaaaaaaa)),
-            def!(a2 = ushr_imm(a1, imm64_1)),
-            def!(a3 = band_imm(x, imm64_0x5555555555555555)),
-            def!(a4 = ishl_imm(a3, imm64_1)),
-            def!(b = bor(a2, a4)),
-            def!(b1 = band_imm(b, imm64_0xcccccccccccccccc)),
-            def!(b2 = ushr_imm(b1, imm64_2)),
-            def!(b3 = band_imm(b, imm64_0x3333333333333333)),
-            def!(b4 = ishl_imm(b3, imm64_2)),
-            def!(c = bor(b2, b4)),
-            def!(c1 = band_imm(c, imm64_0xf0f0f0f0f0f0f0f0)),
-            def!(c2 = ushr_imm(c1, imm64_4)),
-            def!(c3 = band_imm(c, imm64_0x0f0f0f0f0f0f0f0f)),
-            def!(c4 = ishl_imm(c3, imm64_4)),
-            def!(d = bor(c2, c4)),
-            def!(d1 = band_imm(d, imm64_0xff00ff00ff00ff00)),
-            def!(d2 = ushr_imm(d1, imm64_8)),
-            def!(d3 = band_imm(d, imm64_0x00ff00ff00ff00ff)),
-            def!(d4 = ishl_imm(d3, imm64_8)),
-            def!(e = bor(d2, d4)),
-            def!(e1 = band_imm(e, imm64_0xffff0000ffff0000)),
-            def!(e2 = ushr_imm(e1, imm64_16)),
-            def!(e3 = band_imm(e, imm64_0x0000ffff0000ffff)),
-            def!(e4 = ishl_imm(e3, imm64_16)),
-            def!(f = bor(e2, e4)),
-            def!(f1 = ushr_imm(f, imm64_32)),
-            def!(f2 = ishl_imm(f, imm64_32)),
-            def!(a = bor(f1, f2)),
-        ],
-    );
-
-    // Floating-point sign manipulations.
-    for &(ty, const_inst, minus_zero) in &[
-        (F32, f32const, &Literal::bits(ieee32, 0x80000000)),
-        (F64, f64const, &Literal::bits(ieee64, 0x8000000000000000)),
-    ] {
-        expand.legalize(
-            def!(a = fabs.ty(x)),
-            vec![def!(b = const_inst(minus_zero)), def!(a = band_not(x, b))],
-        );
-
-        expand.legalize(
-            def!(a = fneg.ty(x)),
-            vec![def!(b = const_inst(minus_zero)), def!(a = bxor(x, b))],
-        );
-
-        expand.legalize(
-            def!(a = fcopysign.ty(x, y)),
-            vec![
-                def!(b = const_inst(minus_zero)),
-                def!(a1 = band_not(x, b)),
-                def!(a2 = band(y, b)),
-                def!(a = bor(a1, a2)),
-            ],
-        );
-    }
-
-    expand.custom_legalize(br_icmp, "expand_br_icmp");
-
-    let mut groups = TransformGroups::new();
-
-    narrow.finish_and_add_to(&mut groups);
-    let expand_id = expand.finish_and_add_to(&mut groups);
-
-    // Expansions using CPU flags.
-    let mut expand_flags = TransformGroupBuilder::new(
-        "expand_flags",
-        r#"
-        Instruction expansions for architectures with flags.
-
-        Expand some instructions using CPU flags, then fall back to the normal
-        expansions. Not all architectures support CPU flags, so these patterns
-        are kept separate.
-    "#,
-    )
-    .chain_with(expand_id);
-
-    let imm64_0 = Literal::constant(imm64, 0);
-    let intcc_ne = Literal::enumerator_for(intcc, "ne");
-    let intcc_eq = Literal::enumerator_for(intcc, "eq");
-
-    expand_flags.legalize(
-        def!(trapnz(x, c)),
-        vec![
-            def!(a = ifcmp_imm(x, imm64_0)),
-            def!(trapif(intcc_ne, a, c)),
-        ],
-    );
-
-    expand_flags.legalize(
-        def!(trapz(x, c)),
-        vec![
-            def!(a = ifcmp_imm(x, imm64_0)),
-            def!(trapif(intcc_eq, a, c)),
-        ],
-    );
-
-    expand_flags.finish_and_add_to(&mut groups);
-
-    // XXX The order of declarations unfortunately matters to be compatible with the Python code.
-    // When it's all migrated, we can put this next to the narrow/expand finish_and_add_to calls
-    // above.
-    widen.finish_and_add_to(&mut groups);
-
-    groups
-}
--- a/third_party/rust/cranelift-codegen-meta/src/shared/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/shared/mod.rs
@@ -1,30 +1,27 @@
 //! Shared definitions for the Cranelift intermediate language.
 
 pub mod entities;
 pub mod formats;
 pub mod immediates;
 pub mod instructions;
-pub mod legalize;
 pub mod settings;
 pub mod types;
 
 use crate::cdsl::formats::FormatRegistry;
 use crate::cdsl::inst::InstructionGroup;
 use crate::cdsl::operands::OperandKind;
 use crate::cdsl::settings::SettingGroup;
-use crate::cdsl::xform::TransformGroups;
 
 pub struct Definitions {
     pub settings: SettingGroup,
     pub instructions: InstructionGroup,
     pub operand_kinds: OperandKinds,
     pub format_registry: FormatRegistry,
-    pub transform_groups: TransformGroups,
 }
 
 pub struct OperandKinds(Vec<OperandKind>);
 
 impl OperandKinds {
     pub fn new() -> Self {
         Self(Vec::new())
     }
@@ -48,19 +45,15 @@ impl OperandKinds {
         self.0.push(operand_kind);
     }
 }
 
 pub fn define() -> Definitions {
     let immediates = OperandKinds(immediates::define());
     let entities = OperandKinds(entities::define());
     let format_registry = formats::define(&immediates, &entities);
-    let instructions = instructions::define(&format_registry, &immediates, &entities);
-    let transform_groups = legalize::define(&instructions, &immediates);
-
     Definitions {
         settings: settings::define(),
-        instructions,
+        instructions: instructions::define(&format_registry, &immediates, &entities),
         operand_kinds: immediates,
         format_registry,
-        transform_groups,
     }
 }
--- a/third_party/rust/cranelift-codegen-meta/src/srcgen.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/srcgen.rs
@@ -74,37 +74,37 @@ impl Formatter {
             String::new()
         } else {
             format!("{:-1$}", " ", self.indent * SHIFTWIDTH)
         }
     }
 
     /// Get a string containing whitespace outdented one level. Used for
     /// lines of code that are inside a single indented block.
-    fn get_outdent(&mut self) -> String {
+    fn _get_outdent(&mut self) -> String {
+        self.indent_push();
+        let s = self.get_indent();
         self.indent_pop();
-        let s = self.get_indent();
-        self.indent_push();
         s
     }
 
     /// Add an indented line.
     pub fn line(&mut self, contents: impl AsRef<str>) {
         let indented_line = format!("{}{}\n", self.get_indent(), contents.as_ref());
         self.lines.push(indented_line);
     }
 
     /// Pushes an empty line.
     pub fn empty_line(&mut self) {
         self.lines.push("\n".to_string());
     }
 
     /// Emit a line outdented one level.
-    pub fn outdented_line(&mut self, s: &str) {
-        let new_line = format!("{}{}\n", self.get_outdent(), s);
+    pub fn _outdented_line(&mut self, s: &str) {
+        let new_line = format!("{}{}", self._get_outdent(), s);
         self.lines.push(new_line);
     }
 
     /// Write `self.lines` to a file.
     pub fn update_file(
         &self,
         filename: impl AsRef<str>,
         directory: &str,
--- a/third_party/rust/cranelift-codegen-meta/src/unique_table.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/unique_table.rs
@@ -26,19 +26,16 @@ impl<'entries, T: Eq + Hash> UniqueTable
             }
             Some(&i) => i,
         }
     }
 
     pub fn len(&self) -> usize {
         self.table.len()
     }
-    pub fn get(&self, index: usize) -> &T {
-        self.table[index]
-    }
     pub fn iter(&self) -> slice::Iter<&'entries T> {
         self.table.iter()
     }
 }
 
 /// A table of sequences which tries to avoid common subsequences.
 pub struct UniqueSeqTable<T: PartialEq + Clone> {
     table: Vec<T>,
--- a/third_party/rust/cranelift-codegen/.cargo-checksum.json
+++ b/third_party/rust/cranelift-codegen/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"9e1e9d197a2fcdb9bfd3c32a7608ab772ed4301aa0b9f2e60b73c98f542ac760","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"7c0919d12ff966e0c400e7cfa0a555b2e50ede20c0dfb4f4401e35a828134ea9","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"f956b8ba863cd26f6867e13c1b2db3c202e9b07c48c1e43a9c2b41ad0deb8922","meta-python/base/formats.py":"f9fb41210bc1f99a78cb7a60ee9f01c603412c6b1db7e69abbcc0f573cf9fb40","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"4f92066dc9cfa651e395afc8956b1a082b4e8591c6f7310db89593ff55322e2b","meta-python/base/legalize.py":"8455a5c7428e98d23e432d7be28cc863804781013ac614ba57f6d231cd810d28","meta-python/base/predicates.py":"53a5a9a37021a9762f0faec9f9e3c5b713411d47dd9192423cfe0f7a61916809","meta-python/base/semantics.py":"b90cbca9a143676ac37496c83634a66a83360248e4505ff7bda12b0d454efd92","meta-python/base/settings.py":"97fca9ddaab347f50f1594c93283f8f474e53a7232eae65949f56a6a702c2bba","meta-python/base/types.py":"9616d6fe4cab050827ab02eeb9843eacebbb8f7555521f504b5ee2ddf7214fdb","meta-python/build.py":"a6617c8a4d20b76e0c8ea8c6cb2e95ada9ffd0c6cf0f93d841a5204e4678f218","meta-python/cdsl/__init__.py":"b534ec129a0e517f0d13313c2b4bb3a345d3e5b62693a31d8d42c80a219e39fa","meta-python/cdsl/ast.py":"8509f15eaaaf2fed2bec93eba19d313d37c2ddd70d1399a491a394206cbfabe4","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"50fe9329a56e6294a27306aad7be22c88a5b5ef42c3b030ec59218167157f62f","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"fe2dc6e78ff6d4bcb6b1d5448ded343ede0f03b96a965a11aef0f5bbe7bb8f56","meta-python/cdsl/registers.py":"939dafd1b8976a6cd456c9a5e4b374af81fafb9da979ea3a1f6d14e4645914a6","meta-python/cdsl/settings.py":"a859bd006e13b245ff906977512cd4822c3b22601ed17e87ce0618503172809f","meta-python/cdsl/test_ast.py":"947e934e2862445a158bf266dff58a8c88aae31fb34a7f823309ee58a15c5393","meta-python/cdsl/test_package.py":"ffa53d20e023ecb89137294bb13614f4de9b09e1bf05d9772131570bf78f7987","meta-python/cdsl/test_ti.py":"04656e2da99ec37875f91172bb2fa423da1ee27bf523a4d41af311ea22492d1b","meta-python/cdsl/test_typevar.py":"768bf3c35481950264ad6fd7059a532ac62b121ac439983bb4fe1ae76a1d1248","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"566e91f0bb3ebacd5abf9f5a663caee69706c2e829dee1ed735d229198689f76","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"bf200b711570b905f0fb30611ba64f131f98593060eedbe5575054cca4928593","meta-python/check.sh":"707cda14534882e8d4593f93c056390560394c9bc8a687e99f10a56d7b09cb92","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"53bbdd591c91f8e28da95e4da02c9299a01a32d8be6a0c7490b6b7c60a4fbebe","meta-python/gen_encoding.py":"471c5f4ecf24a2a173864c62a48920e5fbe1aacd2229b3eb4483637570bb26b2","meta-python/gen_legalizer.py":"758f5aa072be71041915b8b662a59fc2dab8b0359dd91533161a8f449051fb3b","meta-python/gen_settings.py":"f13e47335ae87b6381134b3d334f2fcbdfc03da92a8864dd1ff1c026408062a7","meta-python/isa/__init__.py":"e499c1206cd095a926fa0ca7eb9d0a50a802ed71c8eb7598e5d3a0f939c8ada5","meta-python/isa/arm32/__init__.py":"eecba73231aa398ded7304690bdba3450dc163afd4360f1b0ad02a28e2380363","meta-python/isa/arm32/defs.py":"01c41dbd7406c624e26229df6befa0992194bddcc7d11e8f6174abfe2b33bf61","meta-python/isa/arm32/registers.py":"c03ca6435828ad5f262049e42f1f71bcf74903831f85daa92c3f322a6c1050ea","meta-python/isa/arm32/settings.py":"afd5a04a9d029f578d6f62dc7c539191886cc9f9dea15d65fc66bf37a63b8814","meta-python/isa/arm64/__init__.py":"f6877253cf786d7ee972881e7d9b3c78c11e6b024e4e227487340dd01d0c44e4","meta-python/isa/arm64/defs.py":"797c5bb6d11fc7a44afe67476136dbd11c40f5e13a1c8f52f9f96be4441677b2","meta-python/isa/arm64/registers.py":"9bdd06edaa382be96042e1ac36d63137e73292292b61dcf4becb7d1428130317","meta-python/isa/arm64/settings.py":"f7b1f8733e775ea8005372ee35f1c2a627b3a69d722e837295599e4cf1f5eb43","meta-python/isa/riscv/__init__.py":"c11607c9eef0bc2707daa3edd4174e934c7a0dcc8ce90cee2c9292a85b1ac596","meta-python/isa/riscv/defs.py":"e73740055c4fb123c45453fc149a807e9720466de848022d5375049bdcfc311c","meta-python/isa/riscv/encodings.py":"ecaad5ea98273ade1cb10606354e893342c495bb48771df50121f789566d7be6","meta-python/isa/riscv/recipes.py":"3852e5b7aa6995fa721ba91744a0470343ce1834651e7b9cc97b5d69af7dfdc5","meta-python/isa/riscv/registers.py":"ef9aca3a6ec2b08ee8f5952186d232861b64a919b671b41911a365e7672b01bd","meta-python/isa/riscv/settings.py":"dfe29722d67be0620a70e08cfb802829a26f5fd339a9342a8ac2dd419daf8a85","meta-python/isa/x86/__init__.py":"ad579de68ea7bf5dc2bce0e3a6f09e7978b1697f1afec8a5ce5dc591136e590d","meta-python/isa/x86/defs.py":"b5eb7889b6f5e5b221ed3923d0137bbb1566c55b5961448cc39e4ea2f13cf4b7","meta-python/isa/x86/encodings.py":"028acd4ba348ba2dfa601217b8d4597748f87cdbfbaeece477150fc09bab50a6","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"c9d7910cd4311ee4307460ca55070404e212727814664f2a2096b9b702ff7178","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"d779a768475cf00c2a8d3ddb5cd0a70ce34662e0ebb52ee26a7e1a495ec41aa2","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"c9dd72fde0ab020d3328dde532d92b39e438e4147930e41df7613c27727e11eb","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"48ef80320f21682860bbf5f79f18739f1d10f0b1fe581ebb05541e90dc2f2f4f","meta-python/semantics/test_elaborate.py":"3a4c850a7385007422c7549661b211903cd1dd1606dad7a86262ae27e697bca6","meta-python/srcgen.py":"999557d683e808a2ca90688c489ec4aff65798f44ac321ecf7de34d307261913","meta-python/stubs/z3/__init__.pyi":"6aaeb80f783b29c4364dee21da45f6df041c0a4807189a15777ee5447f6515dc","meta-python/stubs/z3/z3core.pyi":"c01a41d468e07cc4f8b405c292ed7f8c82bc1077f8b82dfde1e474577ade3335","meta-python/stubs/z3/z3types.pyi":"30009c951af99b9028d47cd4cabae95ff9742b77b690bd8dd63f6b7dba580759","meta-python/test_constant_hash.py":"157cf4f8964e0f04c041ffd349e889ce565b144453436690578c5d03c3a60216","meta-python/test_gen_legalizer.py":"d7da85622f142d2d66d0b92660b6f04b1424788bac05e6fbe0e5822b54dec705","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"76ee030cf0780fe63ccbf855b1161f215e3e2991cb9abe71ca9aff25e5f1dbc2","src/binemit/memorysink.rs":"ad79459de45431b04f28a296074d3613e804538911fbfd451b68058218594574","src/binemit/mod.rs":"bfd83cb1e23e7b2f6926134e1e57548af240036128033f19e557f4d130133e87","src/binemit/relaxation.rs":"95442e08349762b11dce3d8f5d86adea97d3554a0353d7d519bbabfe18a87b01","src/binemit/shrink.rs":"45434d5fb17804f5199f5fa80fd96aedaeac1ca3824766236eb16b6b529155b4","src/bitset.rs":"d57a79058a31b094b4bbe9d34876a5543286df1e08b5ceadfd05a9efc5a3b1ce","src/cfg_printer.rs":"69b4f16132c886ef0b883c8b78b59d041ceec3c8b96dd8015e990ac06733ce91","src/constant_hash.rs":"330e8289789ee351d0abeaf4b5e859b8db8772306e0820d34864fc9905d53b38","src/context.rs":"5c5eeb2aa36eec4d311efb60f6135fbeb223382e17a6e4126a779dfaf73e9be7","src/cursor.rs":"dcce946ad85d8fc2f1c9cc885ae8a0440c37d9e512606fb8a518aaffcc6d6f8f","src/dbg.rs":"1898d94cff0975815eb348651702e95c8f2f63886501d3b7043ee75668480472","src/dce.rs":"d8ab7c0cac0416f9d75afdacc60ba02e532361ec927c3f8bd171b1a53ec8b31a","src/divconst_magic_numbers.rs":"192f7cb7a9a844f975dfdac49fa659e9c51c3e62ca7b8edfe2b55cec8c2dd61c","src/dominator_tree.rs":"7ee4114026011b11d49e48c5a9202970bafe3b22c2074f7c1390b98ebb2edb7a","src/flowgraph.rs":"bf520026c32c5454554d0b078b64a78bd44f3c0f4f198eddf71bcfd78cc963a3","src/fx.rs":"8a5d07487906d8316a179e826fcd817a92a4860686256a6fd9d78ba47c63f330","src/ir/builder.rs":"1a12c57f4168fa3c2fcf6be2f19d0d377eee40f24ae4390e6ba9d954f85a8a3e","src/ir/condcodes.rs":"5247c8d849e1372d2a22379c33a4a88226ec6187be18ca6f2c4e0f315d812aa8","src/ir/dfg.rs":"50a3a7c44b6a993f033a65682beaeae12d5ed78ff67d7ac5e205e645ef8e122f","src/ir/entities.rs":"8bae1166b59afd38953e7d9154ae141c979ab77153b9512f45db7b82a256fdf4","src/ir/extfunc.rs":"9806734eeb480724481128d8c1de78a3b1f80f1214c20f24131196a0df137872","src/ir/extname.rs":"ed2c0b52cdaecc7f0ba9a894ef9fffe139e09b520e43dcd6f0c887a3d41a31ac","src/ir/function.rs":"907c4658865559c27fe4ee2f4064d0c64add712f2a190185236dba3cb98d4c32","src/ir/globalvalue.rs":"1f6125788a9a5c118716f87fd72e85009d2e0a7f4c13b2a7904be8c7412ee4eb","src/ir/heap.rs":"a59d3e5901412b53c0b53a8cdf10765ff5921de9c410ae9acea226c89827df3c","src/ir/immediates.rs":"029a8aa905e6fd0f3334e17a28e73ac36684df2ca0829dcae0158ea8cf64ca8c","src/ir/instructions.rs":"2180de1d127ab5878c5743d8e096d551edb973e0ff1d373c4239c32e7981364c","src/ir/jumptable.rs":"7764abc9aa027a5a89d22059b360372bd9a19686887c5a7830f7637d6f188e1e","src/ir/layout.rs":"bb45eefde16ac9423f637dfcc2796ae7b955a97f38a55f23a19cc45da5decce1","src/ir/libcall.rs":"55fd77f6e32370812a271f4fd5d9817c03904733be79d49e17e2683fe516e30e","src/ir/memflags.rs":"dbcf3798ab66dc764b73fb7f139a621c54cc6bcc683f1f70a33ed7e8c3486bfd","src/ir/mod.rs":"ec1da8a8bd99a3dbbcea59e2c10aa60511488471930646ab293f47d428013224","src/ir/progpoint.rs":"49433f22bd6ff3a96ad0733ff612f3617b312e4492b6b663187141966f6aa701","src/ir/sourceloc.rs":"37ef5fd8cef1de99620797d7d5aba3630e737171853c8471495c685dafac19b6","src/ir/stackslot.rs":"2f54359339837bb1d0d817d3af21bb4b1b050c31703885dfaced29f6e41153c2","src/ir/table.rs":"dcc3b663a989b2b084402b08dc9a0e928dbd052e194a46a1886cc6f0cf1a5f2c","src/ir/trapcode.rs":"59e223193617b8c1043ddd3a907c6131f2987e8fe0965ebfd9f7c056c064b7c5","src/ir/types.rs":"1f644beba2c797f7bd89378d930c3eca1491ec5f82c4715945ac63a0a5754473","src/ir/valueloc.rs":"4c676c2d21d75611ef922a230ee82846afb565ce0f55bc71e33c70e1a1d92a07","src/isa/arm32/abi.rs":"74775c5f1eb95764e46815fa8b31891416a616fdd212972eb77aead43b3345a9","src/isa/arm32/binemit.rs":"52b2f4b3c6d8683ed6963c1f53907ac57b6aab7cc149464c9a12d6875aa3b5c6","src/isa/arm32/enc_tables.rs":"b5b7f2fdcaf1d1878a357c54ab757e94f0d06e5bd391ac5d876e96f5b30d6b7a","src/isa/arm32/mod.rs":"24492cfe9120a3ebb199b1d0a0b58425c58970bae32349b3cf2dd390ce51e62f","src/isa/arm32/registers.rs":"254b568a02480f46bb4967a24a438390231014258f0c159f0a41dbafe8e66d56","src/isa/arm32/settings.rs":"188f3cc445168b472b488e73b011e83edd31ac17e3841dacda07a55ccf923468","src/isa/arm64/abi.rs":"52353ed2e2133dacddaad70a876ecebb9c179c19b911ffa823b5b89d3ee7a17c","src/isa/arm64/binemit.rs":"4465cceb68d03ae4d0fdf188c9b86870fb57b3617d67f0bb7d476e5afb581e81","src/isa/arm64/enc_tables.rs":"8c829c544daeed9adc8458891614a0be6f149e775bd22651465f2c165d4a9e56","src/isa/arm64/mod.rs":"f9ca60e7407b69595cb4ef42103ed079e7bcb40546f11d944ddcfc6a04a7fd11","src/isa/arm64/registers.rs":"308cfcfd9ff2191d7656e7350bb36e41803664eb86ae490fb4b4d3549b25b6a2","src/isa/arm64/settings.rs":"0dff47e995e5d9740deb0116b59e91fbcb725a7fa1bdbd802bf83c13381b17f7","src/isa/call_conv.rs":"833ac811ff78ab8d3a5052165e76c51c6da7686020d95462c18074750fb790ed","src/isa/constraints.rs":"f2e2dee4308dabaab1071983d2edd9a9972a99c5c99edf919adbb4554b4eb067","src/isa/enc_tables.rs":"3497f3d701f21d6f952424abf31515fde9e67aea1cde26236c9ee8b033c61ae6","src/isa/encoding.rs":"7ea5b4400530172f96e263561682886ea6c67e706398d44a83933ef7f0ac98a5","src/isa/mod.rs":"40ab1c6d86f903a88bc7ef83b7cdcbee0eedbfdf7112fb7a6749c0c8cc9ee42c","src/isa/registers.rs":"4a91d4888df5eeed1802f34c43a42b82aaf1f9928a58329b0cbc9c3c57c75485","src/isa/riscv/abi.rs":"36557b91ad16a1344c80fbb16a62b46eac88500d76cb9ebcd4eae224dd67b2de","src/isa/riscv/binemit.rs":"0bd76b005b53b71bdb59057a20671fbcd8ab1c37d767bfd4ab0a92d05e192d9a","src/isa/riscv/enc_tables.rs":"ab73c80fef6b1256fbd3c0e1bdd8e43a20f7d132a32236f6bfc028e9003adfe0","src/isa/riscv/mod.rs":"377dfc7dc9940d284b21bf3d2433916dd9c3df79cce172a2a75ef572dcafe98f","src/isa/riscv/registers.rs":"666c2abe1a93db5f1573d1603db6c13c37f3fc877c0c93b64d1b971921bfa950","src/isa/riscv/settings.rs":"d018d23418ff3fb98571bcdeeddde3277bf213b4b8ac1e55b6573e128b3931ce","src/isa/stack.rs":"d023c57feb944c94c4dc8b7138dcbc9d37ff18ca23c23d83e9bab3c88299ffa0","src/isa/x86/abi.rs":"98092944de6b8a8171f1c7d24a63d23ee6dc77a5b4048be113582c5362ac0158","src/isa/x86/binemit.rs":"328f5803717e095abbda0d0a49a79b8f5250a6d16a739a5912ee0a71f276d9de","src/isa/x86/enc_tables.rs":"ac9b97299644473a483b22b55b0f6ee83c403e983a4debade53c2bbac95400fe","src/isa/x86/mod.rs":"15488d60a950aa4cb75afb63d42d4524e1fcea3b77c7c160e2cb862ec2236a92","src/isa/x86/registers.rs":"bed70bbe1f56f3ef03ea7cd1bea68eb911913cb4c8b93167e044dfc639f7f461","src/isa/x86/settings.rs":"cd8f8c5255663f6e247f0634088b16b53d785ee8c62cb5c0926b3d27597c12ff","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"435707e84b5e406843238d27f5cc4886f4ae37e2c4d25a749e189a378b3af632","src/legalizer/call.rs":"6a82a9daeba5f452a7db0c47dcc43829b119b0652961bc2aa336b809c3f34ef1","src/legalizer/globalvalue.rs":"896f59dc5b8c4a5aee45e3f59211066f214d3ab9142865d80ad6610633363ac9","src/legalizer/heap.rs":"4caf9b5f98556364f16164613872c29a457dcbf44b07cc49fc415abbcd61ec6c","src/legalizer/libcall.rs":"6e58da5e1c2419192a3393debc6e9714df9728e59e1740ff569e8a9c0daa40d5","src/legalizer/mod.rs":"7df6ed89a80c9dab7f6e3ddbedcb1c4bcc86c3c6e5bdc3e71e51d5322cb1ce52","src/legalizer/split.rs":"13fe4d2cecea166ecdc1ebb11f5254374ee170518f1a61de7ac0a921bc8fb25d","src/legalizer/table.rs":"d6e09f8340ca597fdb13f86021e5c53bd3161dc4258effc56c1f6d9be7b819ec","src/lib.rs":"12855b9aedb583859a89dd8f8a7e1ff6d6c9f68e938f60ff4d123aa3d98c2da5","src/licm.rs":"a4b482c995daf0ecf928a525747316760986a42234331554ae68fe9ef8c7145e","src/loop_analysis.rs":"58fc3cc0e700f05e3131ff1b16ff975d4f32a68c790f095d8445bd300356d3c0","src/nan_canonicalization.rs":"9619bb5554791bd1be75ecd98564d6c9f5b65132bc07c5c4d8c210cd79b66f82","src/partition_slice.rs":"bc13504e7658aab565918d965a0b67e941eb572e583870571bc6dbb2b9aad272","src/postopt.rs":"f3af3f27496de14e4e65b7efb0748ca11edff8fedd7b57d680b310de5156aa62","src/predicates.rs":"44bbc09ae0c7d5b54c05eb6061b062e92d1893edc7dda43ae2bccfedc6bb25e3","src/print_errors.rs":"0955151433563b4c305c78b9a8f192c5fe0556ac2528a5ede3b2fd4d143eb743","src/ref_slice.rs":"421a61323c11858a596d50220487f399e1bcedeff0e8d1b716dd4b3531eb01a5","src/regalloc/affinity.rs":"66ee6b9789ec207393c318b14177e1439a54f197b13ebefdb0c4ab77acf38c00","src/regalloc/coalescing.rs":"881c8be32eb4d4b34cf208d0dba3e18b8469bc19f19aa7120514c801562392d3","src/regalloc/coloring.rs":"72bef8b5e3425c805d62cf2329acd29510f1be0886ee73308b69938cf2de203f","src/regalloc/context.rs":"a7da41171ad73cd541977657f0af0d5308567fff140fa7eb7ee44e03c62d8c96","src/regalloc/diversion.rs":"d46d733f6d00a8f536d5c7c8b8fc6f348c3d0605dd0ee77e1d8359367ba53347","src/regalloc/live_value_tracker.rs":"28823003dc72e8a4702776a8ab5ffd878712700a272b64376b0de2022e0ee31a","src/regalloc/liveness.rs":"cc904b813a8a2fc819f0cd5ffacb5a4b82f29ae3ae6a34cccc01fc47c20d150f","src/regalloc/liverange.rs":"7a28454e5f70d570db439b966a01ead759b65eb65c5845f9c58bf2f230a5f2ab","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"c9d1098266c5b8b89eff84a55be3bc4838b70416c2446edf57f5257a6232d059","src/regalloc/register_set.rs":"bc58f93f22f0adbe43260fe20c6089be1fca64f5bcc4acff85dc0a5ec5b61937","src/regalloc/reload.rs":"4dd64aacc97fda5e950222df37df20bf2281cfbca93d1945f3a4f25e4b867aac","src/regalloc/solver.rs":"e2a6d2782d213676dec9781aeb5a37806e092d6daac3249a6cd4d4c92a9d117f","src/regalloc/spilling.rs":"f21ae054e6546b0cd774a94bb301517ba341b985223b6db36e6c9ba995eecfd8","src/regalloc/virtregs.rs":"e5c8da6860ba9495f9396621530347e1dd6fc5b2fae2eb23c171ea77429356f1","src/result.rs":"c10354d615f93caa446c3c8c49d6ba3af762816af470f9c4accf04315cce9753","src/scoped_hash_map.rs":"5afafb3a4039094c3a2aad1582354220d21f399aa50046e7f4a1259e1976597e","src/settings.rs":"23eb1461f7f02f4e26cca71ddc72ead7887bb1aec64b04eb6eb0397c402bf3c8","src/simple_gvn.rs":"c8feb380d4831badc59aa1e65efeafa6702711585817fe5f6b31de6b265fac24","src/simple_preopt.rs":"d2800d1345dc02e2ff5ef5c8b3d1bf9fcaee8f62e78df9f1681338ffc780d520","src/stack_layout.rs":"c5de271e296fc424f1a30017620bc88500369c8e553fef6e95beccb9c6640e7c","src/timing.rs":"a6808943eec68f5d3ff32132d40c07c142e6aa8073473561573a013978883e4f","src/topo_order.rs":"b01ed68a7300691f41ac434e58a5267b10a8b4a7056d65035e24aa8a6722122a","src/unreachable_code.rs":"40cc71a02887ee4065c76ce96dda0a363a8cc134ec784fe5ed1f276db76596ce","src/verifier/cssa.rs":"e3e1d77b763c0ba82d3b59ab5b4667fd3152d5a08be50b58b0c82f86376bb062","src/verifier/flags.rs":"f4ba0e0c13fd643bdbec6466219a25a33993a6e170debb48497a859d9f79d914","src/verifier/liveness.rs":"2631037bafa88659bc47d2174e261f5acb1702ca522722a597fa28e474994d79","src/verifier/locations.rs":"9623bbc2d2f86f36893eebe60330fd51b99c9f9c8e5162c61cc89ab221e75b5a","src/verifier/mod.rs":"0d4a46879a8c4b110b354ba35c667478a785e69b8a1c3b97c7f1aadc79433637","src/write.rs":"24b5caa5fa9145f8da78b9ef2342f52a05d04318b3b03f5b8bb1d486a3d46041"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"9e1e9d197a2fcdb9bfd3c32a7608ab772ed4301aa0b9f2e60b73c98f542ac760","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"7c0919d12ff966e0c400e7cfa0a555b2e50ede20c0dfb4f4401e35a828134ea9","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"f956b8ba863cd26f6867e13c1b2db3c202e9b07c48c1e43a9c2b41ad0deb8922","meta-python/base/formats.py":"f9fb41210bc1f99a78cb7a60ee9f01c603412c6b1db7e69abbcc0f573cf9fb40","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"4f92066dc9cfa651e395afc8956b1a082b4e8591c6f7310db89593ff55322e2b","meta-python/base/legalize.py":"8455a5c7428e98d23e432d7be28cc863804781013ac614ba57f6d231cd810d28","meta-python/base/predicates.py":"53a5a9a37021a9762f0faec9f9e3c5b713411d47dd9192423cfe0f7a61916809","meta-python/base/semantics.py":"b90cbca9a143676ac37496c83634a66a83360248e4505ff7bda12b0d454efd92","meta-python/base/settings.py":"97fca9ddaab347f50f1594c93283f8f474e53a7232eae65949f56a6a702c2bba","meta-python/base/types.py":"9616d6fe4cab050827ab02eeb9843eacebbb8f7555521f504b5ee2ddf7214fdb","meta-python/build.py":"a6617c8a4d20b76e0c8ea8c6cb2e95ada9ffd0c6cf0f93d841a5204e4678f218","meta-python/cdsl/__init__.py":"b534ec129a0e517f0d13313c2b4bb3a345d3e5b62693a31d8d42c80a219e39fa","meta-python/cdsl/ast.py":"832ac98dddea88f4f8a608ac6ac3fda009a15b52abacca30cf39e3787154521c","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"50fe9329a56e6294a27306aad7be22c88a5b5ef42c3b030ec59218167157f62f","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"fe2dc6e78ff6d4bcb6b1d5448ded343ede0f03b96a965a11aef0f5bbe7bb8f56","meta-python/cdsl/registers.py":"939dafd1b8976a6cd456c9a5e4b374af81fafb9da979ea3a1f6d14e4645914a6","meta-python/cdsl/settings.py":"a859bd006e13b245ff906977512cd4822c3b22601ed17e87ce0618503172809f","meta-python/cdsl/test_ast.py":"947e934e2862445a158bf266dff58a8c88aae31fb34a7f823309ee58a15c5393","meta-python/cdsl/test_package.py":"ffa53d20e023ecb89137294bb13614f4de9b09e1bf05d9772131570bf78f7987","meta-python/cdsl/test_ti.py":"04656e2da99ec37875f91172bb2fa423da1ee27bf523a4d41af311ea22492d1b","meta-python/cdsl/test_typevar.py":"768bf3c35481950264ad6fd7059a532ac62b121ac439983bb4fe1ae76a1d1248","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"566e91f0bb3ebacd5abf9f5a663caee69706c2e829dee1ed735d229198689f76","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"bf200b711570b905f0fb30611ba64f131f98593060eedbe5575054cca4928593","meta-python/check.sh":"707cda14534882e8d4593f93c056390560394c9bc8a687e99f10a56d7b09cb92","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"53bbdd591c91f8e28da95e4da02c9299a01a32d8be6a0c7490b6b7c60a4fbebe","meta-python/gen_encoding.py":"471c5f4ecf24a2a173864c62a48920e5fbe1aacd2229b3eb4483637570bb26b2","meta-python/gen_legalizer.py":"758f5aa072be71041915b8b662a59fc2dab8b0359dd91533161a8f449051fb3b","meta-python/gen_settings.py":"f13e47335ae87b6381134b3d334f2fcbdfc03da92a8864dd1ff1c026408062a7","meta-python/isa/__init__.py":"e499c1206cd095a926fa0ca7eb9d0a50a802ed71c8eb7598e5d3a0f939c8ada5","meta-python/isa/arm32/__init__.py":"eecba73231aa398ded7304690bdba3450dc163afd4360f1b0ad02a28e2380363","meta-python/isa/arm32/defs.py":"01c41dbd7406c624e26229df6befa0992194bddcc7d11e8f6174abfe2b33bf61","meta-python/isa/arm32/registers.py":"c03ca6435828ad5f262049e42f1f71bcf74903831f85daa92c3f322a6c1050ea","meta-python/isa/arm32/settings.py":"afd5a04a9d029f578d6f62dc7c539191886cc9f9dea15d65fc66bf37a63b8814","meta-python/isa/arm64/__init__.py":"f6877253cf786d7ee972881e7d9b3c78c11e6b024e4e227487340dd01d0c44e4","meta-python/isa/arm64/defs.py":"797c5bb6d11fc7a44afe67476136dbd11c40f5e13a1c8f52f9f96be4441677b2","meta-python/isa/arm64/registers.py":"9bdd06edaa382be96042e1ac36d63137e73292292b61dcf4becb7d1428130317","meta-python/isa/arm64/settings.py":"f7b1f8733e775ea8005372ee35f1c2a627b3a69d722e837295599e4cf1f5eb43","meta-python/isa/riscv/__init__.py":"c11607c9eef0bc2707daa3edd4174e934c7a0dcc8ce90cee2c9292a85b1ac596","meta-python/isa/riscv/defs.py":"e73740055c4fb123c45453fc149a807e9720466de848022d5375049bdcfc311c","meta-python/isa/riscv/encodings.py":"ecaad5ea98273ade1cb10606354e893342c495bb48771df50121f789566d7be6","meta-python/isa/riscv/recipes.py":"3852e5b7aa6995fa721ba91744a0470343ce1834651e7b9cc97b5d69af7dfdc5","meta-python/isa/riscv/registers.py":"ef9aca3a6ec2b08ee8f5952186d232861b64a919b671b41911a365e7672b01bd","meta-python/isa/riscv/settings.py":"dfe29722d67be0620a70e08cfb802829a26f5fd339a9342a8ac2dd419daf8a85","meta-python/isa/x86/__init__.py":"ad579de68ea7bf5dc2bce0e3a6f09e7978b1697f1afec8a5ce5dc591136e590d","meta-python/isa/x86/defs.py":"b5eb7889b6f5e5b221ed3923d0137bbb1566c55b5961448cc39e4ea2f13cf4b7","meta-python/isa/x86/encodings.py":"028acd4ba348ba2dfa601217b8d4597748f87cdbfbaeece477150fc09bab50a6","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"c9d7910cd4311ee4307460ca55070404e212727814664f2a2096b9b702ff7178","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"d779a768475cf00c2a8d3ddb5cd0a70ce34662e0ebb52ee26a7e1a495ec41aa2","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"c9dd72fde0ab020d3328dde532d92b39e438e4147930e41df7613c27727e11eb","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"48ef80320f21682860bbf5f79f18739f1d10f0b1fe581ebb05541e90dc2f2f4f","meta-python/semantics/test_elaborate.py":"3a4c850a7385007422c7549661b211903cd1dd1606dad7a86262ae27e697bca6","meta-python/srcgen.py":"999557d683e808a2ca90688c489ec4aff65798f44ac321ecf7de34d307261913","meta-python/stubs/z3/__init__.pyi":"6aaeb80f783b29c4364dee21da45f6df041c0a4807189a15777ee5447f6515dc","meta-python/stubs/z3/z3core.pyi":"c01a41d468e07cc4f8b405c292ed7f8c82bc1077f8b82dfde1e474577ade3335","meta-python/stubs/z3/z3types.pyi":"30009c951af99b9028d47cd4cabae95ff9742b77b690bd8dd63f6b7dba580759","meta-python/test_constant_hash.py":"157cf4f8964e0f04c041ffd349e889ce565b144453436690578c5d03c3a60216","meta-python/test_gen_legalizer.py":"d7da85622f142d2d66d0b92660b6f04b1424788bac05e6fbe0e5822b54dec705","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"76ee030cf0780fe63ccbf855b1161f215e3e2991cb9abe71ca9aff25e5f1dbc2","src/binemit/memorysink.rs":"ad79459de45431b04f28a296074d3613e804538911fbfd451b68058218594574","src/binemit/mod.rs":"bfd83cb1e23e7b2f6926134e1e57548af240036128033f19e557f4d130133e87","src/binemit/relaxation.rs":"95442e08349762b11dce3d8f5d86adea97d3554a0353d7d519bbabfe18a87b01","src/binemit/shrink.rs":"45434d5fb17804f5199f5fa80fd96aedaeac1ca3824766236eb16b6b529155b4","src/bitset.rs":"d57a79058a31b094b4bbe9d34876a5543286df1e08b5ceadfd05a9efc5a3b1ce","src/cfg_printer.rs":"69b4f16132c886ef0b883c8b78b59d041ceec3c8b96dd8015e990ac06733ce91","src/constant_hash.rs":"330e8289789ee351d0abeaf4b5e859b8db8772306e0820d34864fc9905d53b38","src/context.rs":"5c5eeb2aa36eec4d311efb60f6135fbeb223382e17a6e4126a779dfaf73e9be7","src/cursor.rs":"dcce946ad85d8fc2f1c9cc885ae8a0440c37d9e512606fb8a518aaffcc6d6f8f","src/dbg.rs":"1898d94cff0975815eb348651702e95c8f2f63886501d3b7043ee75668480472","src/dce.rs":"d8ab7c0cac0416f9d75afdacc60ba02e532361ec927c3f8bd171b1a53ec8b31a","src/divconst_magic_numbers.rs":"baccf8894bf8113b25fe3c35a16160544557d5a77290e08b27cc50f258973532","src/dominator_tree.rs":"7ee4114026011b11d49e48c5a9202970bafe3b22c2074f7c1390b98ebb2edb7a","src/flowgraph.rs":"bf520026c32c5454554d0b078b64a78bd44f3c0f4f198eddf71bcfd78cc963a3","src/fx.rs":"8a5d07487906d8316a179e826fcd817a92a4860686256a6fd9d78ba47c63f330","src/ir/builder.rs":"1a12c57f4168fa3c2fcf6be2f19d0d377eee40f24ae4390e6ba9d954f85a8a3e","src/ir/condcodes.rs":"5247c8d849e1372d2a22379c33a4a88226ec6187be18ca6f2c4e0f315d812aa8","src/ir/dfg.rs":"50a3a7c44b6a993f033a65682beaeae12d5ed78ff67d7ac5e205e645ef8e122f","src/ir/entities.rs":"8bae1166b59afd38953e7d9154ae141c979ab77153b9512f45db7b82a256fdf4","src/ir/extfunc.rs":"9806734eeb480724481128d8c1de78a3b1f80f1214c20f24131196a0df137872","src/ir/extname.rs":"ed2c0b52cdaecc7f0ba9a894ef9fffe139e09b520e43dcd6f0c887a3d41a31ac","src/ir/function.rs":"907c4658865559c27fe4ee2f4064d0c64add712f2a190185236dba3cb98d4c32","src/ir/globalvalue.rs":"1f6125788a9a5c118716f87fd72e85009d2e0a7f4c13b2a7904be8c7412ee4eb","src/ir/heap.rs":"a59d3e5901412b53c0b53a8cdf10765ff5921de9c410ae9acea226c89827df3c","src/ir/immediates.rs":"029a8aa905e6fd0f3334e17a28e73ac36684df2ca0829dcae0158ea8cf64ca8c","src/ir/instructions.rs":"2180de1d127ab5878c5743d8e096d551edb973e0ff1d373c4239c32e7981364c","src/ir/jumptable.rs":"7764abc9aa027a5a89d22059b360372bd9a19686887c5a7830f7637d6f188e1e","src/ir/layout.rs":"bb45eefde16ac9423f637dfcc2796ae7b955a97f38a55f23a19cc45da5decce1","src/ir/libcall.rs":"55fd77f6e32370812a271f4fd5d9817c03904733be79d49e17e2683fe516e30e","src/ir/memflags.rs":"dbcf3798ab66dc764b73fb7f139a621c54cc6bcc683f1f70a33ed7e8c3486bfd","src/ir/mod.rs":"ec1da8a8bd99a3dbbcea59e2c10aa60511488471930646ab293f47d428013224","src/ir/progpoint.rs":"49433f22bd6ff3a96ad0733ff612f3617b312e4492b6b663187141966f6aa701","src/ir/sourceloc.rs":"37ef5fd8cef1de99620797d7d5aba3630e737171853c8471495c685dafac19b6","src/ir/stackslot.rs":"2f54359339837bb1d0d817d3af21bb4b1b050c31703885dfaced29f6e41153c2","src/ir/table.rs":"dcc3b663a989b2b084402b08dc9a0e928dbd052e194a46a1886cc6f0cf1a5f2c","src/ir/trapcode.rs":"59e223193617b8c1043ddd3a907c6131f2987e8fe0965ebfd9f7c056c064b7c5","src/ir/types.rs":"1f644beba2c797f7bd89378d930c3eca1491ec5f82c4715945ac63a0a5754473","src/ir/valueloc.rs":"4c676c2d21d75611ef922a230ee82846afb565ce0f55bc71e33c70e1a1d92a07","src/isa/arm32/abi.rs":"74775c5f1eb95764e46815fa8b31891416a616fdd212972eb77aead43b3345a9","src/isa/arm32/binemit.rs":"52b2f4b3c6d8683ed6963c1f53907ac57b6aab7cc149464c9a12d6875aa3b5c6","src/isa/arm32/enc_tables.rs":"b5b7f2fdcaf1d1878a357c54ab757e94f0d06e5bd391ac5d876e96f5b30d6b7a","src/isa/arm32/mod.rs":"24492cfe9120a3ebb199b1d0a0b58425c58970bae32349b3cf2dd390ce51e62f","src/isa/arm32/registers.rs":"254b568a02480f46bb4967a24a438390231014258f0c159f0a41dbafe8e66d56","src/isa/arm32/settings.rs":"188f3cc445168b472b488e73b011e83edd31ac17e3841dacda07a55ccf923468","src/isa/arm64/abi.rs":"52353ed2e2133dacddaad70a876ecebb9c179c19b911ffa823b5b89d3ee7a17c","src/isa/arm64/binemit.rs":"4465cceb68d03ae4d0fdf188c9b86870fb57b3617d67f0bb7d476e5afb581e81","src/isa/arm64/enc_tables.rs":"8c829c544daeed9adc8458891614a0be6f149e775bd22651465f2c165d4a9e56","src/isa/arm64/mod.rs":"f9ca60e7407b69595cb4ef42103ed079e7bcb40546f11d944ddcfc6a04a7fd11","src/isa/arm64/registers.rs":"308cfcfd9ff2191d7656e7350bb36e41803664eb86ae490fb4b4d3549b25b6a2","src/isa/arm64/settings.rs":"0dff47e995e5d9740deb0116b59e91fbcb725a7fa1bdbd802bf83c13381b17f7","src/isa/call_conv.rs":"833ac811ff78ab8d3a5052165e76c51c6da7686020d95462c18074750fb790ed","src/isa/constraints.rs":"f2e2dee4308dabaab1071983d2edd9a9972a99c5c99edf919adbb4554b4eb067","src/isa/enc_tables.rs":"3497f3d701f21d6f952424abf31515fde9e67aea1cde26236c9ee8b033c61ae6","src/isa/encoding.rs":"7ea5b4400530172f96e263561682886ea6c67e706398d44a83933ef7f0ac98a5","src/isa/mod.rs":"40ab1c6d86f903a88bc7ef83b7cdcbee0eedbfdf7112fb7a6749c0c8cc9ee42c","src/isa/registers.rs":"4a91d4888df5eeed1802f34c43a42b82aaf1f9928a58329b0cbc9c3c57c75485","src/isa/riscv/abi.rs":"36557b91ad16a1344c80fbb16a62b46eac88500d76cb9ebcd4eae224dd67b2de","src/isa/riscv/binemit.rs":"0bd76b005b53b71bdb59057a20671fbcd8ab1c37d767bfd4ab0a92d05e192d9a","src/isa/riscv/enc_tables.rs":"ab73c80fef6b1256fbd3c0e1bdd8e43a20f7d132a32236f6bfc028e9003adfe0","src/isa/riscv/mod.rs":"377dfc7dc9940d284b21bf3d2433916dd9c3df79cce172a2a75ef572dcafe98f","src/isa/riscv/registers.rs":"666c2abe1a93db5f1573d1603db6c13c37f3fc877c0c93b64d1b971921bfa950","src/isa/riscv/settings.rs":"d018d23418ff3fb98571bcdeeddde3277bf213b4b8ac1e55b6573e128b3931ce","src/isa/stack.rs":"d023c57feb944c94c4dc8b7138dcbc9d37ff18ca23c23d83e9bab3c88299ffa0","src/isa/x86/abi.rs":"98092944de6b8a8171f1c7d24a63d23ee6dc77a5b4048be113582c5362ac0158","src/isa/x86/binemit.rs":"328f5803717e095abbda0d0a49a79b8f5250a6d16a739a5912ee0a71f276d9de","src/isa/x86/enc_tables.rs":"250ab677b2a316f9826495a0719f71f4b54b3c3c26d0bb42a76dd85b55a2f8e3","src/isa/x86/mod.rs":"15488d60a950aa4cb75afb63d42d4524e1fcea3b77c7c160e2cb862ec2236a92","src/isa/x86/registers.rs":"bed70bbe1f56f3ef03ea7cd1bea68eb911913cb4c8b93167e044dfc639f7f461","src/isa/x86/settings.rs":"cd8f8c5255663f6e247f0634088b16b53d785ee8c62cb5c0926b3d27597c12ff","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"435707e84b5e406843238d27f5cc4886f4ae37e2c4d25a749e189a378b3af632","src/legalizer/call.rs":"6a82a9daeba5f452a7db0c47dcc43829b119b0652961bc2aa336b809c3f34ef1","src/legalizer/globalvalue.rs":"896f59dc5b8c4a5aee45e3f59211066f214d3ab9142865d80ad6610633363ac9","src/legalizer/heap.rs":"4caf9b5f98556364f16164613872c29a457dcbf44b07cc49fc415abbcd61ec6c","src/legalizer/libcall.rs":"6e58da5e1c2419192a3393debc6e9714df9728e59e1740ff569e8a9c0daa40d5","src/legalizer/mod.rs":"7df6ed89a80c9dab7f6e3ddbedcb1c4bcc86c3c6e5bdc3e71e51d5322cb1ce52","src/legalizer/split.rs":"13fe4d2cecea166ecdc1ebb11f5254374ee170518f1a61de7ac0a921bc8fb25d","src/legalizer/table.rs":"d6e09f8340ca597fdb13f86021e5c53bd3161dc4258effc56c1f6d9be7b819ec","src/lib.rs":"12855b9aedb583859a89dd8f8a7e1ff6d6c9f68e938f60ff4d123aa3d98c2da5","src/licm.rs":"a4b482c995daf0ecf928a525747316760986a42234331554ae68fe9ef8c7145e","src/loop_analysis.rs":"58fc3cc0e700f05e3131ff1b16ff975d4f32a68c790f095d8445bd300356d3c0","src/nan_canonicalization.rs":"9619bb5554791bd1be75ecd98564d6c9f5b65132bc07c5c4d8c210cd79b66f82","src/partition_slice.rs":"bc13504e7658aab565918d965a0b67e941eb572e583870571bc6dbb2b9aad272","src/postopt.rs":"f3af3f27496de14e4e65b7efb0748ca11edff8fedd7b57d680b310de5156aa62","src/predicates.rs":"44bbc09ae0c7d5b54c05eb6061b062e92d1893edc7dda43ae2bccfedc6bb25e3","src/print_errors.rs":"0955151433563b4c305c78b9a8f192c5fe0556ac2528a5ede3b2fd4d143eb743","src/ref_slice.rs":"421a61323c11858a596d50220487f399e1bcedeff0e8d1b716dd4b3531eb01a5","src/regalloc/affinity.rs":"66ee6b9789ec207393c318b14177e1439a54f197b13ebefdb0c4ab77acf38c00","src/regalloc/coalescing.rs":"881c8be32eb4d4b34cf208d0dba3e18b8469bc19f19aa7120514c801562392d3","src/regalloc/coloring.rs":"72bef8b5e3425c805d62cf2329acd29510f1be0886ee73308b69938cf2de203f","src/regalloc/context.rs":"a7da41171ad73cd541977657f0af0d5308567fff140fa7eb7ee44e03c62d8c96","src/regalloc/diversion.rs":"d46d733f6d00a8f536d5c7c8b8fc6f348c3d0605dd0ee77e1d8359367ba53347","src/regalloc/live_value_tracker.rs":"28823003dc72e8a4702776a8ab5ffd878712700a272b64376b0de2022e0ee31a","src/regalloc/liveness.rs":"cc904b813a8a2fc819f0cd5ffacb5a4b82f29ae3ae6a34cccc01fc47c20d150f","src/regalloc/liverange.rs":"7a28454e5f70d570db439b966a01ead759b65eb65c5845f9c58bf2f230a5f2ab","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"c9d1098266c5b8b89eff84a55be3bc4838b70416c2446edf57f5257a6232d059","src/regalloc/register_set.rs":"bc58f93f22f0adbe43260fe20c6089be1fca64f5bcc4acff85dc0a5ec5b61937","src/regalloc/reload.rs":"4dd64aacc97fda5e950222df37df20bf2281cfbca93d1945f3a4f25e4b867aac","src/regalloc/solver.rs":"e2a6d2782d213676dec9781aeb5a37806e092d6daac3249a6cd4d4c92a9d117f","src/regalloc/spilling.rs":"f21ae054e6546b0cd774a94bb301517ba341b985223b6db36e6c9ba995eecfd8","src/regalloc/virtregs.rs":"e5c8da6860ba9495f9396621530347e1dd6fc5b2fae2eb23c171ea77429356f1","src/result.rs":"c10354d615f93caa446c3c8c49d6ba3af762816af470f9c4accf04315cce9753","src/scoped_hash_map.rs":"5afafb3a4039094c3a2aad1582354220d21f399aa50046e7f4a1259e1976597e","src/settings.rs":"23eb1461f7f02f4e26cca71ddc72ead7887bb1aec64b04eb6eb0397c402bf3c8","src/simple_gvn.rs":"c8feb380d4831badc59aa1e65efeafa6702711585817fe5f6b31de6b265fac24","src/simple_preopt.rs":"3e8958c7eddf0f0e207d1f6a10ce9d9595b554dcabd984fcea1d6a4716365358","src/stack_layout.rs":"c5de271e296fc424f1a30017620bc88500369c8e553fef6e95beccb9c6640e7c","src/timing.rs":"a6808943eec68f5d3ff32132d40c07c142e6aa8073473561573a013978883e4f","src/topo_order.rs":"b01ed68a7300691f41ac434e58a5267b10a8b4a7056d65035e24aa8a6722122a","src/unreachable_code.rs":"40cc71a02887ee4065c76ce96dda0a363a8cc134ec784fe5ed1f276db76596ce","src/verifier/cssa.rs":"e3e1d77b763c0ba82d3b59ab5b4667fd3152d5a08be50b58b0c82f86376bb062","src/verifier/flags.rs":"f4ba0e0c13fd643bdbec6466219a25a33993a6e170debb48497a859d9f79d914","src/verifier/liveness.rs":"2631037bafa88659bc47d2174e261f5acb1702ca522722a597fa28e474994d79","src/verifier/locations.rs":"9623bbc2d2f86f36893eebe60330fd51b99c9f9c8e5162c61cc89ab221e75b5a","src/verifier/mod.rs":"0d4a46879a8c4b110b354ba35c667478a785e69b8a1c3b97c7f1aadc79433637","src/write.rs":"24b5caa5fa9145f8da78b9ef2342f52a05d04318b3b03f5b8bb1d486a3d46041"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-codegen/meta-python/cdsl/ast.py
+++ b/third_party/rust/cranelift-codegen/meta-python/cdsl/ast.py
@@ -157,29 +157,29 @@ class Var(Atom):
     Intermediate values
         Values that are defined in the source pattern, but not in the
         destination pattern. These may have uses outside the source pattern, so
         the defining instruction can't be deleted immediately.
     Temporary values
         Values that are defined only in the destination pattern.
     """
 
-    def __init__(self, name):
-        # type: (str) -> None
+    def __init__(self, name, typevar=None):
+        # type: (str, TypeVar) -> None
         self.name = name
         # The `Def` defining this variable in a source pattern.
         self.src_def = None  # type: Def
         # The `Def` defining this variable in a destination pattern.
         self.dst_def = None  # type: Def
         # TypeVar representing the type of this variable.
-        self.typevar = None  # type: TypeVar
+        self.typevar = typevar  # type: TypeVar
         # The original 'typeof(x)' type variable that was created for this Var.
         # This one doesn't change. `self.typevar` above may be changed to
         # another typevar by type inference.
-        self.original_typevar = None  # type: TypeVar
+        self.original_typevar = self.typevar  # type: TypeVar
 
     def __str__(self):
         # type: () -> str
         return self.name
 
     def __repr__(self):
         # type: () -> str
         s = self.name
--- a/third_party/rust/cranelift-codegen/src/divconst_magic_numbers.rs
+++ b/third_party/rust/cranelift-codegen/src/divconst_magic_numbers.rs
@@ -50,17 +50,17 @@ pub fn magic_u32(d: u32) -> MU32 {
     let mut q2: u32 = 0x7FFFFFFFu32 / d;
     let mut r2: u32 = 0x7FFFFFFFu32 - q2 * d;
     loop {
         p = p + 1;
         if r1 >= nc - r1 {
             q1 = u32::wrapping_add(u32::wrapping_mul(2, q1), 1);
             r1 = u32::wrapping_sub(u32::wrapping_mul(2, r1), nc);
         } else {
-            q1 = u32::wrapping_mul(2, q1);
+            q1 = 2 * q1;
             r1 = 2 * r1;
         }
         if r2 + 1 >= d - r2 {
             if q2 >= 0x7FFFFFFFu32 {
                 do_add = true;
             }
             q2 = 2 * q2 + 1;
             r2 = u32::wrapping_sub(u32::wrapping_add(u32::wrapping_mul(2, r2), 1), d);
@@ -96,17 +96,17 @@ pub fn magic_u64(d: u64) -> MU64 {
     let mut q2: u64 = 0x7FFFFFFFFFFFFFFFu64 / d;
     let mut r2: u64 = 0x7FFFFFFFFFFFFFFFu64 - q2 * d;
     loop {
         p = p + 1;
         if r1 >= nc - r1 {
             q1 = u64::wrapping_add(u64::wrapping_mul(2, q1), 1);
             r1 = u64::wrapping_sub(u64::wrapping_mul(2, r1), nc);
         } else {
-            q1 = u64::wrapping_mul(2, q1);
+            q1 = 2 * q1;
             r1 = 2 * r1;
         }
         if r2 + 1 >= d - r2 {
             if q2 >= 0x7FFFFFFFFFFFFFFFu64 {
                 do_add = true;
             }
             q2 = 2 * q2 + 1;
             r2 = u64::wrapping_sub(u64::wrapping_add(u64::wrapping_mul(2, r2), 1), d);
@@ -517,134 +517,78 @@ mod tests {
             magic_s64(0x7fffffffffffffffi64),
             make_ms64(0x4000000000000001u64 as i64, 61)
         );
     }
 
     #[test]
     fn test_magic_generators_dont_panic() {
         // The point of this is to check that the magic number generators
-        // don't panic with integer wraparounds, especially at boundary cases
-        // for their arguments. The actual results are thrown away, although
-        // we force `total` to be used, so that rustc can't optimise the
-        // entire computation away.
-
+        // don't panic with integer wraparounds, especially at boundary
+        // cases for their arguments. The actual results are thrown away.
+        let mut total: u64 = 0;
         // Testing UP magic_u32
-        let mut total: u64 = 0;
         for x in 2..(200 * 1000u32) {
             let m = magic_u32(x);
             total = total ^ (m.mul_by as u64);
             total = total + (m.shift_by as u64);
-            total = total + (if m.do_add { 123 } else { 456 });
+            total = total - (if m.do_add { 123 } else { 456 });
         }
-        assert_eq!(total, 2481999609);
-
-        total = 0;
-        // Testing MIDPOINT magic_u32
-        for x in 0x8000_0000u32 - 10 * 1000u32..0x8000_0000u32 + 10 * 1000u32 {
-            let m = magic_u32(x);
-            total = total ^ (m.mul_by as u64);
-            total = total + (m.shift_by as u64);
-            total = total + (if m.do_add { 123 } else { 456 });
-        }
-        assert_eq!(total, 2399809723);
-
-        total = 0;
+        assert_eq!(total, 1747815691);
         // Testing DOWN magic_u32
         for x in 0..(200 * 1000u32) {
             let m = magic_u32(0xFFFF_FFFFu32 - x);
             total = total ^ (m.mul_by as u64);
             total = total + (m.shift_by as u64);
-            total = total + (if m.do_add { 123 } else { 456 });
+            total = total - (if m.do_add { 123 } else { 456 });
         }
-        assert_eq!(total, 271138267);
+        assert_eq!(total, 2210292772);
 
         // Testing UP magic_u64
-        total = 0;
         for x in 2..(200 * 1000u64) {
             let m = magic_u64(x);
             total = total ^ m.mul_by;
             total = total + (m.shift_by as u64);
-            total = total + (if m.do_add { 123 } else { 456 });
+            total = total - (if m.do_add { 123 } else { 456 });
         }
-        assert_eq!(total, 7430004086976261161);
-
-        total = 0;
-        // Testing MIDPOINT magic_u64
-        for x in 0x8000_0000_0000_0000u64 - 10 * 1000u64..0x8000_0000_0000_0000u64 + 10 * 1000u64 {
-            let m = magic_u64(x);
-            total = total ^ m.mul_by;
-            total = total + (m.shift_by as u64);
-            total = total + (if m.do_add { 123 } else { 456 });
-        }
-        assert_eq!(total, 10312117246769520603);
-
+        assert_eq!(total, 7430004084791260605);
         // Testing DOWN magic_u64
-        total = 0;
         for x in 0..(200 * 1000u64) {
             let m = magic_u64(0xFFFF_FFFF_FFFF_FFFFu64 - x);
             total = total ^ m.mul_by;
             total = total + (m.shift_by as u64);
-            total = total + (if m.do_add { 123 } else { 456 });
+            total = total - (if m.do_add { 123 } else { 456 });
         }
-        assert_eq!(total, 1126603594357269734);
+        assert_eq!(total, 7547519887519825919);
 
         // Testing UP magic_s32
-        total = 0;
         for x in 0..(200 * 1000i32) {
             let m = magic_s32(-0x8000_0000i32 + x);
             total = total ^ (m.mul_by as u64);
             total = total + (m.shift_by as u64);
         }
-        assert_eq!(total, 18446744069953376812);
-
-        total = 0;
-        // Testing MIDPOINT magic_s32
-        for x in 0..(200 * 1000i32) {
-            let x2 = -100 * 1000i32 + x;
-            if x2 != -1 && x2 != 0 && x2 != 1 {
-                let m = magic_s32(x2);
-                total = total ^ (m.mul_by as u64);
-                total = total + (m.shift_by as u64);
-            }
-        }
-        assert_eq!(total, 351839350);
-
+        assert_eq!(total, 10899224186731671235);
         // Testing DOWN magic_s32
-        total = 0;
         for x in 0..(200 * 1000i32) {
             let m = magic_s32(0x7FFF_FFFFi32 - x);
             total = total ^ (m.mul_by as u64);
             total = total + (m.shift_by as u64);
         }
-        assert_eq!(total, 18446744072916880714);
+        assert_eq!(total, 7547519887517897369);
 
         // Testing UP magic_s64
-        total = 0;
         for x in 0..(200 * 1000i64) {
             let m = magic_s64(-0x8000_0000_0000_0000i64 + x);
             total = total ^ (m.mul_by as u64);
             total = total + (m.shift_by as u64);
         }
-        assert_eq!(total, 17929885647724831014);
-
-        total = 0;
-        // Testing MIDPOINT magic_s64
-        for x in 0..(200 * 1000i64) {
-            let x2 = -100 * 1000i64 + x;
-            if x2 != -1 && x2 != 0 && x2 != 1 {
-                let m = magic_s64(x2);
-                total = total ^ (m.mul_by as u64);
-                total = total + (m.shift_by as u64);
-            }
-        }
-        assert_eq!(total, 18106042338125661964);
-
+        assert_eq!(total, 8029756891368555163);
         // Testing DOWN magic_s64
-        total = 0;
         for x in 0..(200 * 1000i64) {
             let m = magic_s64(0x7FFF_FFFF_FFFF_FFFFi64 - x);
             total = total ^ (m.mul_by as u64);
             total = total + (m.shift_by as u64);
         }
-        assert_eq!(total, 563301797155560970);
+        // Force `total` -- and hence, the entire computation -- to
+        // be used, so that rustc can't optimise it out.
+        assert_eq!(total, 7547519887532559585u64);
     }
 }
--- a/third_party/rust/cranelift-codegen/src/isa/x86/enc_tables.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/x86/enc_tables.rs
@@ -86,35 +86,16 @@ fn size_plus_maybe_sib_or_offset_for_in_
     sizing: &RecipeSizing,
     inst: Inst,
     divert: &RegDiversions,
     func: &Function,
 ) -> u8 {
     sizing.base_size + additional_size_if(1, inst, divert, func, needs_sib_byte_or_offset)
 }
 
-/// If the value's definition is a constant immediate, returns its unpacked value, or None
-/// otherwise.
-fn maybe_iconst_imm(pos: &FuncCursor, value: ir::Value) -> Option<i64> {
-    if let ir::ValueDef::Result(inst, _) = &pos.func.dfg.value_def(value) {
-        if let ir::InstructionData::UnaryImm {
-            opcode: ir::Opcode::Iconst,
-            imm,
-        } = &pos.func.dfg[*inst]
-        {
-            let value: i64 = (*imm).into();
-            Some(value)
-        } else {
-            None
-        }
-    } else {
-        None
-    }
-}
-
 /// Expand the `sdiv` and `srem` instructions using `x86_sdivmodx`.
 fn expand_sdivrem(
     inst: ir::Inst,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
     isa: &isa::TargetIsa,
 ) {
     let (x, y, is_srem) = match func.dfg[inst] {
@@ -123,74 +104,51 @@ fn expand_sdivrem(
             args,
         } => (args[0], args[1], false),
         ir::InstructionData::Binary {
             opcode: ir::Opcode::Srem,
             args,
         } => (args[0], args[1], true),
         _ => panic!("Need sdiv/srem: {}", func.dfg.display_inst(inst, None)),
     };
-
+    let avoid_div_traps = isa.flags().avoid_div_traps();
     let old_ebb = func.layout.pp_ebb(inst);
     let result = func.dfg.first_result(inst);
     let ty = func.dfg.value_type(result);
 
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
     pos.func.dfg.clear_results(inst);
 
-    let avoid_div_traps = isa.flags().avoid_div_traps();
-
     // If we can tolerate native division traps, sdiv doesn't need branching.
     if !avoid_div_traps && !is_srem {
         let xhi = pos.ins().sshr_imm(x, i64::from(ty.lane_bits()) - 1);
         pos.ins().with_result(result).x86_sdivmodx(x, xhi, y);
         pos.remove_inst();
         return;
     }
 
-    // Try to remove checks if the input value is an immediate other than 0 or -1. For these two
-    // immediates, we'd ideally replace conditional traps by traps, but this requires more
-    // manipulation of the dfg/cfg, which is out of scope here.
-    let (could_be_zero, could_be_minus_one) = if let Some(imm) = maybe_iconst_imm(&pos, y) {
-        (imm == 0, imm == -1)
-    } else {
-        (true, true)
-    };
-
-    // Put in an explicit division-by-zero trap if the environment requires it.
-    if avoid_div_traps && could_be_zero {
-        pos.ins().trapz(y, ir::TrapCode::IntegerDivisionByZero);
-    }
-
-    if !could_be_minus_one {
-        let xhi = pos.ins().sshr_imm(x, i64::from(ty.lane_bits()) - 1);
-        let reuse = if is_srem {
-            [None, Some(result)]
-        } else {
-            [Some(result), None]
-        };
-        pos.ins().with_results(reuse).x86_sdivmodx(x, xhi, y);
-        pos.remove_inst();
-        return;
-    }
-
     // EBB handling the -1 divisor case.
     let minus_one = pos.func.dfg.make_ebb();
 
     // Final EBB with one argument representing the final result value.
     let done = pos.func.dfg.make_ebb();
 
     // Move the `inst` result value onto the `done` EBB.
     pos.func.dfg.attach_ebb_param(done, result);
 
     // Start by checking for a -1 divisor which needs to be handled specially.
     let is_m1 = pos.ins().ifcmp_imm(y, -1);
     pos.ins().brif(IntCC::Equal, is_m1, minus_one, &[]);
 
+    // Put in an explicit division-by-zero trap if the environment requires it.
+    if avoid_div_traps {
+        pos.ins().trapz(y, ir::TrapCode::IntegerDivisionByZero);
+    }
+
     // Now it is safe to execute the `x86_sdivmodx` instruction which will still trap on division
     // by zero.
     let xhi = pos.ins().sshr_imm(x, i64::from(ty.lane_bits()) - 1);
     let (quot, rem) = pos.ins().x86_sdivmodx(x, xhi, y);
     let divres = if is_srem { rem } else { quot };
     pos.ins().jump(done, &[divres]);
 
     // Now deal with the -1 divisor case.
@@ -243,27 +201,17 @@ fn expand_udivrem(
     let ty = func.dfg.value_type(result);
 
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
     pos.func.dfg.clear_results(inst);
 
     // Put in an explicit division-by-zero trap if the environment requires it.
     if avoid_div_traps {
-        let zero_check = if let Some(imm) = maybe_iconst_imm(&pos, y) {
-            // Ideally, we'd just replace the conditional trap with a trap when the immediate is
-            // zero, but this requires more manipulation of the dfg/cfg, which is out of scope
-            // here.
-            imm == 0
-        } else {
-            true
-        };
-        if zero_check {
-            pos.ins().trapz(y, ir::TrapCode::IntegerDivisionByZero);
-        }
+        pos.ins().trapz(y, ir::TrapCode::IntegerDivisionByZero);
     }
 
     // Now it is safe to execute the `x86_udivmodx` instruction.
     let xhi = pos.ins().iconst(ty, 0);
     let reuse = if is_urem {
         [None, Some(result)]
     } else {
         [Some(result), None]
--- a/third_party/rust/cranelift-codegen/src/simple_preopt.rs
+++ b/third_party/rust/cranelift-codegen/src/simple_preopt.rs
@@ -1,14 +1,16 @@
 //! A pre-legalization rewriting pass.
 //!
 //! This module provides early-stage optimizations. The optimizations found
 //! should be useful for already well-optimized code. More general purpose
 //! early-stage optimizations can be found in the preopt crate.
 
+#![allow(non_snake_case)]
+
 use crate::cursor::{Cursor, FuncCursor};
 use crate::divconst_magic_numbers::{magic_s32, magic_s64, magic_u32, magic_u64};
 use crate::divconst_magic_numbers::{MS32, MS64, MU32, MU64};
 use crate::flowgraph::ControlFlowGraph;
 use crate::ir::condcodes::{CondCode, IntCC};
 use crate::ir::dfg::ValueDef;
 use crate::ir::instructions::{Opcode, ValueList};
 use crate::ir::types::{I32, I64};
@@ -20,138 +22,132 @@ use crate::timing;
 //
 // Pattern-match helpers and transformation for div and rem by constants.
 
 // Simple math helpers
 
 /// if `x` is a power of two, or the negation thereof, return the power along
 /// with a boolean that indicates whether `x` is negative. Else return None.
 #[inline]
-fn i32_is_power_of_two(x: i32) -> Option<(bool, u32)> {
+fn isPowerOf2_S32(x: i32) -> Option<(bool, u32)> {
     // We have to special-case this because abs(x) isn't representable.
     if x == -0x8000_0000 {
         return Some((true, 31));
     }
     let abs_x = i32::wrapping_abs(x) as u32;
     if abs_x.is_power_of_two() {
         return Some((x < 0, abs_x.trailing_zeros()));
     }
     None
 }
 
-/// Same comments as for i32_is_power_of_two apply.
+/// Same comments as for isPowerOf2_S64 apply.
 #[inline]
-fn i64_is_power_of_two(x: i64) -> Option<(bool, u32)> {
+fn isPowerOf2_S64(x: i64) -> Option<(bool, u32)> {
     // We have to special-case this because abs(x) isn't representable.
     if x == -0x8000_0000_0000_0000 {
         return Some((true, 63));
     }
     let abs_x = i64::wrapping_abs(x) as u64;
     if abs_x.is_power_of_two() {
         return Some((x < 0, abs_x.trailing_zeros()));
     }
     None
 }
 
-/// Representation of an instruction that can be replaced by a single division/remainder operation
-/// between a left Value operand and a right immediate operand.
 #[derive(Debug)]
 enum DivRemByConstInfo {
-    DivU32(Value, u32),
-    DivU64(Value, u64),
+    DivU32(Value, u32), // In all cases, the arguments are:
+    DivU64(Value, u64), // left operand, right operand
     DivS32(Value, i32),
     DivS64(Value, i64),
     RemU32(Value, u32),
     RemU64(Value, u64),
     RemS32(Value, i32),
     RemS64(Value, i64),
 }
 
-/// Possibly create a DivRemByConstInfo from the given components, by figuring out which, if any,
-/// of the 8 cases apply, and also taking care to sanity-check the immediate.
+/// Possibly create a DivRemByConstInfo from the given components, by
+/// figuring out which, if any, of the 8 cases apply, and also taking care to
+/// sanity-check the immediate.
 fn package_up_divrem_info(
-    value: Value,
-    value_type: Type,
-    imm_i64: i64,
-    is_signed: bool,
-    is_rem: bool,
+    argL: Value,
+    argL_ty: Type,
+    argRs: i64,
+    isSigned: bool,
+    isRem: bool,
 ) -> Option<DivRemByConstInfo> {
-    let imm_u64 = imm_i64 as u64;
-
-    match (is_signed, value_type) {
-        (false, I32) => {
-            if imm_u64 < 0x1_0000_0000 {
-                if is_rem {
-                    Some(DivRemByConstInfo::RemU32(value, imm_u64 as u32))
-                } else {
-                    Some(DivRemByConstInfo::DivU32(value, imm_u64 as u32))
-                }
-            } else {
-                None
-            }
-        }
-
-        (false, I64) => {
-            // unsigned 64, no range constraint.
-            if is_rem {
-                Some(DivRemByConstInfo::RemU64(value, imm_u64))
-            } else {
-                Some(DivRemByConstInfo::DivU64(value, imm_u64))
-            }
-        }
-
-        (true, I32) => {
-            if imm_u64 <= 0x7fff_ffff || imm_u64 >= 0xffff_ffff_8000_0000 {
-                if is_rem {
-                    Some(DivRemByConstInfo::RemS32(value, imm_u64 as i32))
-                } else {
-                    Some(DivRemByConstInfo::DivS32(value, imm_u64 as i32))
-                }
-            } else {
-                None
-            }
-        }
-
-        (true, I64) => {
-            // signed 64, no range constraint.
-            if is_rem {
-                Some(DivRemByConstInfo::RemS64(value, imm_u64 as i64))
-            } else {
-                Some(DivRemByConstInfo::DivS64(value, imm_u64 as i64))
-            }
-        }
-
-        _ => None,
+    let argRu: u64 = argRs as u64;
+    if !isSigned && argL_ty == I32 && argRu < 0x1_0000_0000 {
+        let con = if isRem {
+            DivRemByConstInfo::RemU32
+        } else {
+            DivRemByConstInfo::DivU32
+        };
+        return Some(con(argL, argRu as u32));
+    }
+    if !isSigned && argL_ty == I64 {
+        // unsigned 64, no range constraint
+        let con = if isRem {
+            DivRemByConstInfo::RemU64
+        } else {
+            DivRemByConstInfo::DivU64
+        };
+        return Some(con(argL, argRu));
     }
+    if isSigned && argL_ty == I32 && (argRu <= 0x7fff_ffff || argRu >= 0xffff_ffff_8000_0000) {
+        let con = if isRem {
+            DivRemByConstInfo::RemS32
+        } else {
+            DivRemByConstInfo::DivS32
+        };
+        return Some(con(argL, argRu as i32));
+    }
+    if isSigned && argL_ty == I64 {
+        // signed 64, no range constraint
+        let con = if isRem {
+            DivRemByConstInfo::RemS64
+        } else {
+            DivRemByConstInfo::DivS64
+        };
+        return Some(con(argL, argRu as i64));
+    }
+    None
 }
 
-/// Examine `inst` to see if it is a div or rem by a constant, and if so return the operands,
-/// signedness, operation size and div-vs-rem-ness in a handy bundle.
+/// Examine `idata` to see if it is a div or rem by a constant, and if so
+/// return the operands, signedness, operation size and div-vs-rem-ness in a
+/// handy bundle.
 fn get_div_info(inst: Inst, dfg: &DataFlowGraph) -> Option<DivRemByConstInfo> {
-    if let InstructionData::BinaryImm { opcode, arg, imm } = dfg[inst] {
-        let (is_signed, is_rem) = match opcode {
+    let idata: &InstructionData = &dfg[inst];
+
+    if let InstructionData::BinaryImm { opcode, arg, imm } = *idata {
+        let (isSigned, isRem) = match opcode {
             Opcode::UdivImm => (false, false),
             Opcode::UremImm => (false, true),
             Opcode::SdivImm => (true, false),
             Opcode::SremImm => (true, true),
-            _ => return None,
+            _other => return None,
         };
-        return package_up_divrem_info(arg, dfg.value_type(arg), imm.into(), is_signed, is_rem);
+        // Pull the operation size (type) from the left arg
+        let argL_ty = dfg.value_type(arg);
+        return package_up_divrem_info(arg, argL_ty, imm.into(), isSigned, isRem);
     }
 
     None
 }
 
-/// Actually do the transformation given a bundle containing the relevant information.
-/// `divrem_info` describes a div or rem by a constant, that `pos` currently points at, and `inst`
-/// is the associated instruction.  `inst` is replaced by a sequence of other operations that
-/// calculate the same result. Note that there are various `divrem_info` cases where we cannot do
-/// any transformation, in which case `inst` is left unchanged.
+/// Actually do the transformation given a bundle containing the relevant
+/// information. `divrem_info` describes a div or rem by a constant, that
+/// `pos` currently points at, and `inst` is the associated instruction.
+/// `inst` is replaced by a sequence of other operations that calculate the
+/// same result. Note that there are various `divrem_info` cases where we
+/// cannot do any transformation, in which case `inst` is left unchanged.
 fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCursor, inst: Inst) {
-    let is_rem = match *divrem_info {
+    let isRem = match *divrem_info {
         DivRemByConstInfo::DivU32(_, _)
         | DivRemByConstInfo::DivU64(_, _)
         | DivRemByConstInfo::DivS32(_, _)
         | DivRemByConstInfo::DivS64(_, _) => false,
         DivRemByConstInfo::RemU32(_, _)
         | DivRemByConstInfo::RemU64(_, _)
         | DivRemByConstInfo::RemS32(_, _)
         | DivRemByConstInfo::RemS64(_, _) => true,
@@ -161,32 +157,32 @@ fn do_divrem_transformation(divrem_info:
         // -------------------- U32 --------------------
 
         // U32 div, rem by zero: ignore
         DivRemByConstInfo::DivU32(_n1, 0) | DivRemByConstInfo::RemU32(_n1, 0) => {}
 
         // U32 div by 1: identity
         // U32 rem by 1: zero
         DivRemByConstInfo::DivU32(n1, 1) | DivRemByConstInfo::RemU32(n1, 1) => {
-            if is_rem {
+            if isRem {
                 pos.func.dfg.replace(inst).iconst(I32, 0);
             } else {
                 pos.func.dfg.replace(inst).copy(n1);
             }
         }
 
         // U32 div, rem by a power-of-2
         DivRemByConstInfo::DivU32(n1, d) | DivRemByConstInfo::RemU32(n1, d)
             if d.is_power_of_two() =>
         {
             debug_assert!(d >= 2);
             // compute k where d == 2^k
             let k = d.trailing_zeros();
             debug_assert!(k >= 1 && k <= 31);
-            if is_rem {
+            if isRem {
                 let mask = (1u64 << k) - 1;
                 pos.func.dfg.replace(inst).band_imm(n1, mask as i64);
             } else {
                 pos.func.dfg.replace(inst).ushr_imm(n1, k as i64);
             }
         }
 
         // U32 div, rem by non-power-of-2
@@ -215,48 +211,48 @@ fn do_divrem_transformation(divrem_info:
                 if shift_by > 0 {
                     qf = pos.ins().ushr_imm(q1, shift_by as i64);
                 } else {
                     qf = q1;
                 }
             }
             // Now qf holds the final quotient. If necessary calculate the
             // remainder instead.
-            if is_rem {
+            if isRem {
                 let tt = pos.ins().imul_imm(qf, d as i64);
                 pos.func.dfg.replace(inst).isub(n1, tt);
             } else {
                 pos.func.dfg.replace(inst).copy(qf);
             }
         }
 
         // -------------------- U64 --------------------
 
         // U64 div, rem by zero: ignore
         DivRemByConstInfo::DivU64(_n1, 0) | DivRemByConstInfo::RemU64(_n1, 0) => {}
 
         // U64 div by 1: identity
         // U64 rem by 1: zero
         DivRemByConstInfo::DivU64(n1, 1) | DivRemByConstInfo::RemU64(n1, 1) => {
-            if is_rem {
+            if isRem {
                 pos.func.dfg.replace(inst).iconst(I64, 0);
             } else {
                 pos.func.dfg.replace(inst).copy(n1);
             }
         }
 
         // U64 div, rem by a power-of-2
         DivRemByConstInfo::DivU64(n1, d) | DivRemByConstInfo::RemU64(n1, d)
             if d.is_power_of_two() =>
         {
             debug_assert!(d >= 2);
             // compute k where d == 2^k
             let k = d.trailing_zeros();
             debug_assert!(k >= 1 && k <= 63);
-            if is_rem {
+            if isRem {
                 let mask = (1u64 << k) - 1;
                 pos.func.dfg.replace(inst).band_imm(n1, mask as i64);
             } else {
                 pos.func.dfg.replace(inst).ushr_imm(n1, k as i64);
             }
         }
 
         // U64 div, rem by non-power-of-2
@@ -285,17 +281,17 @@ fn do_divrem_transformation(divrem_info:
                 if shift_by > 0 {
                     qf = pos.ins().ushr_imm(q1, shift_by as i64);
                 } else {
                     qf = q1;
                 }
             }
             // Now qf holds the final quotient. If necessary calculate the
             // remainder instead.
-            if is_rem {
+            if isRem {
                 let tt = pos.ins().imul_imm(qf, d as i64);
                 pos.func.dfg.replace(inst).isub(n1, tt);
             } else {
                 pos.func.dfg.replace(inst).copy(qf);
             }
         }
 
         // -------------------- S32 --------------------
@@ -304,43 +300,43 @@ fn do_divrem_transformation(divrem_info:
         DivRemByConstInfo::DivS32(_n1, -1)
         | DivRemByConstInfo::RemS32(_n1, -1)
         | DivRemByConstInfo::DivS32(_n1, 0)
         | DivRemByConstInfo::RemS32(_n1, 0) => {}
 
         // S32 div by 1: identity
         // S32 rem by 1: zero
         DivRemByConstInfo::DivS32(n1, 1) | DivRemByConstInfo::RemS32(n1, 1) => {
-            if is_rem {
+            if isRem {
                 pos.func.dfg.replace(inst).iconst(I32, 0);
             } else {
                 pos.func.dfg.replace(inst).copy(n1);
             }
         }
 
         DivRemByConstInfo::DivS32(n1, d) | DivRemByConstInfo::RemS32(n1, d) => {
-            if let Some((is_negative, k)) = i32_is_power_of_two(d) {
+            if let Some((isNeg, k)) = isPowerOf2_S32(d) {
                 // k can be 31 only in the case that d is -2^31.
                 debug_assert!(k >= 1 && k <= 31);
                 let t1 = if k - 1 == 0 {
                     n1
                 } else {
                     pos.ins().sshr_imm(n1, (k - 1) as i64)
                 };
                 let t2 = pos.ins().ushr_imm(t1, (32 - k) as i64);
                 let t3 = pos.ins().iadd(n1, t2);
-                if is_rem {
+                if isRem {
                     // S32 rem by a power-of-2
                     let t4 = pos.ins().band_imm(t3, i32::wrapping_neg(1 << k) as i64);
                     // Curiously, we don't care here what the sign of d is.
                     pos.func.dfg.replace(inst).isub(n1, t4);
                 } else {
                     // S32 div by a power-of-2
                     let t4 = pos.ins().sshr_imm(t3, k as i64);
-                    if is_negative {
+                    if isNeg {
                         pos.func.dfg.replace(inst).irsub_imm(t4, 0);
                     } else {
                         pos.func.dfg.replace(inst).copy(t4);
                     }
                 }
             } else {
                 // S32 div, rem by a non-power-of-2
                 debug_assert!(d < -2 || d > 2);
@@ -359,17 +355,17 @@ fn do_divrem_transformation(divrem_info:
                     q2
                 } else {
                     pos.ins().sshr_imm(q2, shift_by as i64)
                 };
                 let t1 = pos.ins().ushr_imm(q3, 31);
                 let qf = pos.ins().iadd(q3, t1);
                 // Now qf holds the final quotient. If necessary calculate
                 // the remainder instead.
-                if is_rem {
+                if isRem {
                     let tt = pos.ins().imul_imm(qf, d as i64);
                     pos.func.dfg.replace(inst).isub(n1, tt);
                 } else {
                     pos.func.dfg.replace(inst).copy(qf);
                 }
             }
         }
 
@@ -379,43 +375,43 @@ fn do_divrem_transformation(divrem_info:
         DivRemByConstInfo::DivS64(_n1, -1)
         | DivRemByConstInfo::RemS64(_n1, -1)
         | DivRemByConstInfo::DivS64(_n1, 0)
         | DivRemByConstInfo::RemS64(_n1, 0) => {}
 
         // S64 div by 1: identity
         // S64 rem by 1: zero
         DivRemByConstInfo::DivS64(n1, 1) | DivRemByConstInfo::RemS64(n1, 1) => {
-            if is_rem {
+            if isRem {
                 pos.func.dfg.replace(inst).iconst(I64, 0);
             } else {
                 pos.func.dfg.replace(inst).copy(n1);
             }
         }
 
         DivRemByConstInfo::DivS64(n1, d) | DivRemByConstInfo::RemS64(n1, d) => {
-            if let Some((is_negative, k)) = i64_is_power_of_two(d) {
+            if let Some((isNeg, k)) = isPowerOf2_S64(d) {
                 // k can be 63 only in the case that d is -2^63.
                 debug_assert!(k >= 1 && k <= 63);
                 let t1 = if k - 1 == 0 {
                     n1
                 } else {
                     pos.ins().sshr_imm(n1, (k - 1) as i64)
                 };
                 let t2 = pos.ins().ushr_imm(t1, (64 - k) as i64);
                 let t3 = pos.ins().iadd(n1, t2);
-                if is_rem {
+                if isRem {
                     // S64 rem by a power-of-2
                     let t4 = pos.ins().band_imm(t3, i64::wrapping_neg(1 << k));
                     // Curiously, we don't care here what the sign of d is.
                     pos.func.dfg.replace(inst).isub(n1, t4);
                 } else {
                     // S64 div by a power-of-2
                     let t4 = pos.ins().sshr_imm(t3, k as i64);
-                    if is_negative {
+                    if isNeg {
                         pos.func.dfg.replace(inst).irsub_imm(t4, 0);
                     } else {
                         pos.func.dfg.replace(inst).copy(t4);
                     }
                 }
             } else {
                 // S64 div, rem by a non-power-of-2
                 debug_assert!(d < -2 || d > 2);
@@ -434,17 +430,17 @@ fn do_divrem_transformation(divrem_info:
                     q2
                 } else {
                     pos.ins().sshr_imm(q2, shift_by as i64)
                 };
                 let t1 = pos.ins().ushr_imm(q3, 63);
                 let qf = pos.ins().iadd(q3, t1);
                 // Now qf holds the final quotient. If necessary calculate
                 // the remainder instead.
-                if is_rem {
+                if isRem {
                     let tt = pos.ins().imul_imm(qf, d);
                     pos.func.dfg.replace(inst).isub(n1, tt);
                 } else {
                     pos.func.dfg.replace(inst).copy(qf);
                 }
             }
         }
     }
@@ -769,19 +765,23 @@ fn branch_order(pos: &mut FuncCursor, cf
 pub fn do_preopt(func: &mut Function, cfg: &mut ControlFlowGraph) {
     let _tt = timing::preopt();
     let mut pos = FuncCursor::new(func);
     while let Some(ebb) = pos.next_ebb() {
         while let Some(inst) = pos.next_inst() {
             // Apply basic simplifications.
             simplify(&mut pos, inst);
 
-            // Try to transform divide-by-constant into simpler operations.
-            if let Some(divrem_info) = get_div_info(inst, &pos.func.dfg) {
+            //-- BEGIN -- division by constants ----------------
+
+            let mb_dri = get_div_info(inst, &pos.func.dfg);
+            if let Some(divrem_info) = mb_dri {
                 do_divrem_transformation(&divrem_info, &mut pos, inst);
                 continue;
             }
 
+            //-- END -- division by constants ------------------
+
             branch_opt(&mut pos, inst);
             branch_order(&mut pos, cfg, ebb, inst);
         }
     }
 }
--- a/third_party/rust/cranelift-wasm/.cargo-checksum.json
+++ b/third_party/rust/cranelift-wasm/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"8ce435ab1fc1e02e80cca53b06c7535dfbd264d7a4ed08bb3864058d43236f15","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"5c6ce509d72ca72c8dbf08beb2660c7e604fb8612274fe24ffd5eb8849ba027e","src/environ/dummy.rs":"83969d9fb4505d64aa4b9cfcef7dac55d1b4e519e7871ed7569ce7999385a131","src/environ/mod.rs":"617c147485038dfd797ab0ea71b4cfa9574d95d5d5b1ca362c6b7b6a462cf577","src/environ/spec.rs":"f37f60dd7ee664446cb2ef2480c8e5c6e6685ca9c350a104b1dc35a9142062c2","src/func_translator.rs":"7df33c55f193f25436dbefabb506e9c5f40c633c14631c78f8289cc317812956","src/lib.rs":"15b3cebafa8c6c2ce3964def7afd0af30d8eee22880e6dd903134e3ced24efd3","src/module_translator.rs":"ac54c24aaa3775f72ccd16d1781be648bb0e83ea83909f933d07e86ef1879213","src/sections_translator.rs":"55290a6b5d2a71719404d4d5f08a389dbf37c053264d17f3b292a57d1bdd5b62","src/state.rs":"9e4f67900439f6aa18cfa3f16c694487374ddf42530db4504bccab0ebc360c96","src/translation_utils.rs":"50b45794018e1c471694f4f60707329213c9fb4153798a879953a479213b8a56","tests/wasm_testsuite.rs":"c6eac90ebdb6b58d8247c22e04454d95943c5ab0621084b624eb20c0ce2a96a3"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"9827446df24b295abe90539e7ccfda7c54955f1cb44e4d49c3a4e5a66bfa5fae","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"96fc0bf7b2c2f0de0596724bfe72d7fbcf5db1b676721fe024f5555ddbcbb7b6","src/environ/dummy.rs":"42df6db37892ea28e9a004934599d8bbcbd62db52f787486cd81a23f1a563613","src/environ/mod.rs":"617c147485038dfd797ab0ea71b4cfa9574d95d5d5b1ca362c6b7b6a462cf577","src/environ/spec.rs":"1c22dfbf956d80cbf34a6b8087dfb38b1f73a5cf010c341b673dba4286468bfe","src/func_translator.rs":"b27debdc0d17f30ecfa7a9bf4bdeea6054966507b5d398ccd4165574da4f674a","src/lib.rs":"95183fc86a20687e547d2edbd9868681005f0c3a2ca1ae1471e2ae38098f85c6","src/module_translator.rs":"ac54c24aaa3775f72ccd16d1781be648bb0e83ea83909f933d07e86ef1879213","src/sections_translator.rs":"55290a6b5d2a71719404d4d5f08a389dbf37c053264d17f3b292a57d1bdd5b62","src/state.rs":"1b1fa08736702d062c49118fba67f0a13752b4d863c1d11abd90eeb219777a23","src/translation_utils.rs":"50b45794018e1c471694f4f60707329213c9fb4153798a879953a479213b8a56","tests/wasm_testsuite.rs":"c6eac90ebdb6b58d8247c22e04454d95943c5ab0621084b624eb20c0ce2a96a3"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-wasm/Cargo.toml
+++ b/third_party/rust/cranelift-wasm/Cargo.toml
@@ -22,14 +22,14 @@ log = { version = "0.4.6", default-featu
 cast = { version = "0.2.2", default-features = false }
 
 [dev-dependencies]
 wabt = "0.7.0"
 target-lexicon = "0.4.0"
 
 [features]
 default = ["std"]
-std = ["cranelift-codegen/std", "cranelift-frontend/std", "wasmparser/std", "failure/std"]
+std = ["cranelift-codegen/std", "cranelift-frontend/std", "wasmparser/std"]
 core = ["hashmap_core", "cranelift-codegen/core", "cranelift-frontend/core", "wasmparser/core"]
 
 [badges]
 maintenance = { status = "experimental" }
 travis-ci = { repository = "CraneStation/cranelift" }
--- a/third_party/rust/cranelift-wasm/src/code_translator.rs
+++ b/third_party/rust/cranelift-wasm/src/code_translator.rs
@@ -66,28 +66,28 @@ pub fn translate_operator<FE: FuncEnviro
         Operator::TeeLocal { local_index } => {
             let val = state.peek1();
             builder.def_var(Variable::with_u32(local_index), val);
         }
         /********************************** Globals ****************************************
          *  `get_global` and `set_global` are handled by the environment.
          ***********************************************************************************/
         Operator::GetGlobal { global_index } => {
-            let val = match state.get_global(builder.func, global_index, environ)? {
+            let val = match state.get_global(builder.func, global_index, environ) {
                 GlobalVariable::Const(val) => val,
                 GlobalVariable::Memory { gv, offset, ty } => {
                     let addr = builder.ins().global_value(environ.pointer_type(), gv);
                     let flags = ir::MemFlags::trusted();
                     builder.ins().load(ty, flags, addr, offset)
                 }
             };
             state.push1(val);
         }
         Operator::SetGlobal { global_index } => {
-            match state.get_global(builder.func, global_index, environ)? {
+            match state.get_global(builder.func, global_index, environ) {
                 GlobalVariable::Const(_) => panic!("global #{} is a constant", global_index),
                 GlobalVariable::Memory { gv, offset, ty } => {
                     let addr = builder.ins().global_value(environ.pointer_type(), gv);
                     let flags = ir::MemFlags::trusted();
                     let val = state.pop1();
                     debug_assert_eq!(ty, builder.func.dfg.value_type(val));
                     builder.ins().store(flags, val, addr, offset);
                 }
@@ -132,17 +132,17 @@ pub fn translate_operator<FE: FuncEnviro
             let loop_body = builder.create_ebb();
             let next = builder.create_ebb();
             if let Ok(ty_cre) = type_to_type(ty) {
                 builder.append_ebb_param(next, ty_cre);
             }
             builder.ins().jump(loop_body, &[]);
             state.push_loop(loop_body, next, num_return_values(ty));
             builder.switch_to_block(loop_body);
-            environ.translate_loop_header(builder.cursor())?;
+            environ.translate_loop_header(builder.cursor());
         }
         Operator::If { ty } => {
             let val = state.pop1();
             let if_not = builder.create_ebb();
             let jump_inst = builder.ins().brz(val, if_not, &[]);
             // Here we append an argument to an Ebb targeted by an argumentless jump instruction
             // But in fact there are two cases:
             // - either the If does not have a Else clause, in that case ty = EmptyBlock
@@ -343,17 +343,17 @@ pub fn translate_operator<FE: FuncEnviro
             state.reachable = false;
         }
         /************************************ Calls ****************************************
          * The call instructions pop off their arguments from the stack and append their
          * return values to it. `call_indirect` needs environment support because there is an
          * argument referring to an index in the external functions table of the module.
          ************************************************************************************/
         Operator::Call { function_index } => {
-            let (fref, num_args) = state.get_direct_func(builder.func, function_index, environ)?;
+            let (fref, num_args) = state.get_direct_func(builder.func, function_index, environ);
             let call = environ.translate_call(
                 builder.cursor(),
                 FuncIndex::from_u32(function_index),
                 fref,
                 state.peekn(num_args),
             )?;
             let inst_results = builder.inst_results(call);
             debug_assert_eq!(
@@ -364,18 +364,18 @@ pub fn translate_operator<FE: FuncEnviro
                 "translate_call results should match the call signature"
             );
             state.popn(num_args);
             state.pushn(inst_results);
         }
         Operator::CallIndirect { index, table_index } => {
             // `index` is the index of the function's signature and `table_index` is the index of
             // the table to search the function in.
-            let (sigref, num_args) = state.get_indirect_sig(builder.func, index, environ)?;
-            let table = state.get_table(builder.func, table_index, environ)?;
+            let (sigref, num_args) = state.get_indirect_sig(builder.func, index, environ);
+            let table = state.get_table(builder.func, table_index, environ);
             let callee = state.pop1();
             let call = environ.translate_call_indirect(
                 builder.cursor(),
                 TableIndex::from_u32(table_index),
                 table,
                 SignatureIndex::from_u32(index),
                 sigref,
                 callee,
@@ -393,98 +393,98 @@ pub fn translate_operator<FE: FuncEnviro
         /******************************* Memory management ***********************************
          * Memory management is handled by environment. It is usually translated into calls to
          * special functions.
          ************************************************************************************/
         Operator::MemoryGrow { reserved } => {
             // The WebAssembly MVP only supports one linear memory, but we expect the reserved
             // argument to be a memory index.
             let heap_index = MemoryIndex::from_u32(reserved);
-            let heap = state.get_heap(builder.func, reserved, environ)?;
+            let heap = state.get_heap(builder.func, reserved, environ);
             let val = state.pop1();
             state.push1(environ.translate_memory_grow(builder.cursor(), heap_index, heap, val)?)
         }
         Operator::MemorySize { reserved } => {
             let heap_index = MemoryIndex::from_u32(reserved);
-            let heap = state.get_heap(builder.func, reserved, environ)?;
+            let heap = state.get_heap(builder.func, reserved, environ);
             state.push1(environ.translate_memory_size(builder.cursor(), heap_index, heap)?);
         }
         /******************************* Load instructions ***********************************
          * Wasm specifies an integer alignment flag but we drop it in Cranelift.
          * The memory base address is provided by the environment.
          ************************************************************************************/
         Operator::I32Load8U {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Uload8, I32, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Uload8, I32, builder, state, environ);
         }
         Operator::I32Load16U {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Uload16, I32, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Uload16, I32, builder, state, environ);
         }
         Operator::I32Load8S {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Sload8, I32, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Sload8, I32, builder, state, environ);
         }
         Operator::I32Load16S {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Sload16, I32, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Sload16, I32, builder, state, environ);
         }
         Operator::I64Load8U {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Uload8, I64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Uload8, I64, builder, state, environ);
         }
         Operator::I64Load16U {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Uload16, I64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Uload16, I64, builder, state, environ);
         }
         Operator::I64Load8S {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Sload8, I64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Sload8, I64, builder, state, environ);
         }
         Operator::I64Load16S {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Sload16, I64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Sload16, I64, builder, state, environ);
         }
         Operator::I64Load32S {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Sload32, I64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Sload32, I64, builder, state, environ);
         }
         Operator::I64Load32U {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Uload32, I64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Uload32, I64, builder, state, environ);
         }
         Operator::I32Load {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Load, I32, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Load, I32, builder, state, environ);
         }
         Operator::F32Load {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Load, F32, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Load, F32, builder, state, environ);
         }
         Operator::I64Load {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Load, I64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Load, I64, builder, state, environ);
         }
         Operator::F64Load {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_load(offset, ir::Opcode::Load, F64, builder, state, environ)?;
+            translate_load(offset, ir::Opcode::Load, F64, builder, state, environ);
         }
         /****************************** Store instructions ***********************************
          * Wasm specifies an integer alignment flag but we drop it in Cranelift.
          * The memory base address is provided by the environment.
          ************************************************************************************/
         Operator::I32Store {
             memarg: MemoryImmediate { flags: _, offset },
         }
@@ -492,38 +492,38 @@ pub fn translate_operator<FE: FuncEnviro
             memarg: MemoryImmediate { flags: _, offset },
         }
         | Operator::F32Store {
             memarg: MemoryImmediate { flags: _, offset },
         }
         | Operator::F64Store {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_store(offset, ir::Opcode::Store, builder, state, environ)?;
+            translate_store(offset, ir::Opcode::Store, builder, state, environ);
         }
         Operator::I32Store8 {
             memarg: MemoryImmediate { flags: _, offset },
         }
         | Operator::I64Store8 {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_store(offset, ir::Opcode::Istore8, builder, state, environ)?;
+            translate_store(offset, ir::Opcode::Istore8, builder, state, environ);
         }
         Operator::I32Store16 {
             memarg: MemoryImmediate { flags: _, offset },
         }
         | Operator::I64Store16 {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_store(offset, ir::Opcode::Istore16, builder, state, environ)?;
+            translate_store(offset, ir::Opcode::Istore16, builder, state, environ);
         }
         Operator::I64Store32 {
             memarg: MemoryImmediate { flags: _, offset },
         } => {
-            translate_store(offset, ir::Opcode::Istore32, builder, state, environ)?;
+            translate_store(offset, ir::Opcode::Istore32, builder, state, environ);
         }
         /****************************** Nullary Operators ************************************/
         Operator::I32Const { value } => state.push1(builder.ins().iconst(I32, i64::from(value))),
         Operator::I64Const { value } => state.push1(builder.ins().iconst(I64, value)),
         Operator::F32Const { value } => {
             state.push1(builder.ins().f32const(f32_translation(value)));
         }
         Operator::F64Const { value } => {
@@ -1170,52 +1170,50 @@ fn get_heap_addr(
 /// Translate a load instruction.
 fn translate_load<FE: FuncEnvironment + ?Sized>(
     offset: u32,
     opcode: ir::Opcode,
     result_ty: Type,
     builder: &mut FunctionBuilder,
     state: &mut TranslationState,
     environ: &mut FE,
-) -> WasmResult<()> {
+) {
     let addr32 = state.pop1();
     // We don't yet support multiple linear memories.
-    let heap = state.get_heap(builder.func, 0, environ)?;
+    let heap = state.get_heap(builder.func, 0, environ);
     let (base, offset) = get_heap_addr(heap, addr32, offset, environ.pointer_type(), builder);
     // Note that we don't set `is_aligned` here, even if the load instruction's
     // alignment immediate says it's aligned, because WebAssembly's immediate
     // field is just a hint, while Cranelift's aligned flag needs a guarantee.
     let flags = MemFlags::new();
     let (load, dfg) = builder
         .ins()
         .Load(opcode, result_ty, flags, offset.into(), base);
     state.push1(dfg.first_result(load));
-    Ok(())
 }
 
 /// Translate a store instruction.
 fn translate_store<FE: FuncEnvironment + ?Sized>(
     offset: u32,
     opcode: ir::Opcode,
     builder: &mut FunctionBuilder,
     state: &mut TranslationState,
     environ: &mut FE,
-) -> WasmResult<()> {
+) {
     let (addr32, val) = state.pop2();
     let val_ty = builder.func.dfg.value_type(val);
 
     // We don't yet support multiple linear memories.
-    let heap = state.get_heap(builder.func, 0, environ)?;
+    let heap = state.get_heap(builder.func, 0, environ);
     let (base, offset) = get_heap_addr(heap, addr32, offset, environ.pointer_type(), builder);
     // See the comments in `translate_load` about the flags.
     let flags = MemFlags::new();
     builder
         .ins()
         .Store(opcode, val_ty, flags, offset.into(), val, base);
-    Ok(())
 }
 
 fn translate_icmp(cc: IntCC, builder: &mut FunctionBuilder, state: &mut TranslationState) {
     let (arg0, arg1) = state.pop2();
     let val = builder.ins().icmp(cc, arg0, arg1);
     state.push1(builder.ins().bint(I32, val));
 }
 
--- a/third_party/rust/cranelift-wasm/src/environ/dummy.rs
+++ b/third_party/rust/cranelift-wasm/src/environ/dummy.rs
@@ -177,106 +177,90 @@ impl<'dummy_environment> DummyFuncEnviro
     }
 }
 
 impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environment> {
     fn target_config(&self) -> TargetFrontendConfig {
         self.mod_info.config
     }
 
-    fn return_mode(&self) -> ReturnMode {
-        self.return_mode
-    }
-
-    fn make_global(
-        &mut self,
-        func: &mut ir::Function,
-        index: GlobalIndex,
-    ) -> WasmResult<GlobalVariable> {
+    fn make_global(&mut self, func: &mut ir::Function, index: GlobalIndex) -> GlobalVariable {
         // Just create a dummy `vmctx` global.
         let offset = cast::i32((index.index() * 8) + 8).unwrap().into();
         let vmctx = func.create_global_value(ir::GlobalValueData::VMContext {});
-        Ok(GlobalVariable::Memory {
+        GlobalVariable::Memory {
             gv: vmctx,
             offset,
             ty: self.mod_info.globals[index].entity.ty,
-        })
+        }
     }
 
-    fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> WasmResult<ir::Heap> {
+    fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> ir::Heap {
         // Create a static heap whose base address is stored at `vmctx+0`.
         let addr = func.create_global_value(ir::GlobalValueData::VMContext);
         let gv = func.create_global_value(ir::GlobalValueData::Load {
             base: addr,
             offset: Offset32::new(0),
             global_type: self.pointer_type(),
             readonly: true,
         });
 
-        Ok(func.create_heap(ir::HeapData {
+        func.create_heap(ir::HeapData {
             base: gv,
             min_size: 0.into(),
             offset_guard_size: 0x8000_0000.into(),
             style: ir::HeapStyle::Static {
                 bound: 0x1_0000_0000.into(),
             },
             index_type: I32,
-        }))
+        })
     }
 
-    fn make_table(&mut self, func: &mut ir::Function, _index: TableIndex) -> WasmResult<ir::Table> {
+    fn make_table(&mut self, func: &mut ir::Function, _index: TableIndex) -> ir::Table {
         // Create a table whose base address is stored at `vmctx+0`.
         let vmctx = func.create_global_value(ir::GlobalValueData::VMContext);
         let base_gv = func.create_global_value(ir::GlobalValueData::Load {
             base: vmctx,
             offset: Offset32::new(0),
             global_type: self.pointer_type(),
             readonly: true, // when tables in wasm become "growable", revisit whether this can be readonly or not.
         });
         let bound_gv = func.create_global_value(ir::GlobalValueData::Load {
             base: vmctx,
             offset: Offset32::new(0),
             global_type: I32,
             readonly: true,
         });
 
-        Ok(func.create_table(ir::TableData {
+        func.create_table(ir::TableData {
             base_gv,
             min_size: Uimm64::new(0),
             bound_gv,
             element_size: Uimm64::from(u64::from(self.pointer_bytes()) * 2),
             index_type: I32,
-        }))
+        })
     }
 
-    fn make_indirect_sig(
-        &mut self,
-        func: &mut ir::Function,
-        index: SignatureIndex,
-    ) -> WasmResult<ir::SigRef> {
+    fn make_indirect_sig(&mut self, func: &mut ir::Function, index: SignatureIndex) -> ir::SigRef {
         // A real implementation would probably change the calling convention and add `vmctx` and
         // signature index arguments.
-        Ok(func.import_signature(self.vmctx_sig(index)))
+        func.import_signature(self.vmctx_sig(index))
     }
 
-    fn make_direct_func(
-        &mut self,
-        func: &mut ir::Function,
-        index: FuncIndex,
-    ) -> WasmResult<ir::FuncRef> {
+    fn make_direct_func(&mut self, func: &mut ir::Function, index: FuncIndex) -> ir::FuncRef {
         let sigidx = self.mod_info.functions[index].entity;
         // A real implementation would probably add a `vmctx` argument.
         // And maybe attempt some signature de-duplication.
         let signature = func.import_signature(self.vmctx_sig(sigidx));
         let name = get_func_name(index);
-        Ok(func.import_function(ir::ExtFuncData {
+        func.import_function(ir::ExtFuncData {
             name,
             signature,
             colocated: false,
-        }))
+        })
     }
 
     fn translate_call_indirect(
         &mut self,
         mut pos: FuncCursor,
         _table_index: TableIndex,
         _table: ir::Table,
         _sig_index: SignatureIndex,
@@ -351,16 +335,20 @@ impl<'dummy_environment> FuncEnvironment
     fn translate_memory_size(
         &mut self,
         mut pos: FuncCursor,
         _index: MemoryIndex,
         _heap: ir::Heap,
     ) -> WasmResult<ir::Value> {
         Ok(pos.ins().iconst(I32, -1))
     }
+
+    fn return_mode(&self) -> ReturnMode {
+        self.return_mode
+    }
 }
 
 impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
     fn target_config(&self) -> TargetFrontendConfig {
         self.info.config
     }
 
     fn declare_signature(&mut self, sig: ir::Signature) {
--- a/third_party/rust/cranelift-wasm/src/environ/spec.rs
+++ b/third_party/rust/cranelift-wasm/src/environ/spec.rs
@@ -34,17 +34,17 @@ pub enum GlobalVariable {
         ty: ir::Type,
     },
 }
 
 /// A WebAssembly translation error.
 ///
 /// When a WebAssembly function can't be translated, one of these error codes will be returned
 /// to describe the failure.
-#[derive(Fail, Debug)]
+#[derive(Fail, Debug, PartialEq, Eq)]
 pub enum WasmError {
     /// The input WebAssembly code is invalid.
     ///
     /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
     /// code. This should never happen for validated WebAssembly code.
     #[fail(display = "Invalid input WebAssembly code at offset {}: {}", _1, _0)]
     InvalidWebAssembly {
         /// A string describing the validation error.
@@ -62,28 +62,16 @@ pub enum WasmError {
     /// An implementation limit was exceeded.
     ///
     /// Cranelift can compile very large and complicated functions, but the [implementation has
     /// limits][limits] that cause compilation to fail when they are exceeded.
     ///
     /// [limits]: https://cranelift.readthedocs.io/en/latest/ir.html#implementation-limits
     #[fail(display = "Implementation limit exceeded")]
     ImplLimitExceeded,
-
-    /// Any user-defined error. Requires an std build, where failure::Error is defined.
-    #[cfg(feature = "std")]
-    #[fail(display = "User error: {}", _0)]
-    User(failure::Error),
-}
-
-#[cfg(feature = "std")]
-impl From<failure::Error> for WasmError {
-    fn from(err: failure::Error) -> Self {
-        WasmError::User(err)
-    }
 }
 
 impl From<BinaryReaderError> for WasmError {
     /// Convert from a `BinaryReaderError` to a `WasmError`.
     fn from(e: BinaryReaderError) -> Self {
         let BinaryReaderError { message, offset } = e;
         WasmError::InvalidWebAssembly { message, offset }
     }
@@ -117,79 +105,60 @@ pub trait FuncEnvironment {
         ir::Type::int(u16::from(self.target_config().pointer_bits())).unwrap()
     }
 
     /// Get the size of a native pointer, in bytes.
     fn pointer_bytes(&self) -> u8 {
         self.target_config().pointer_bytes()
     }
 
-    /// Should the code be structured to use a single `fallthrough_return` instruction at the end
-    /// of the function body, rather than `return` instructions as needed? This is used by VMs
-    /// to append custom epilogues.
-    fn return_mode(&self) -> ReturnMode {
-        ReturnMode::NormalReturns
-    }
-
     /// Set up the necessary preamble definitions in `func` to access the global variable
     /// identified by `index`.
     ///
     /// The index space covers both imported globals and globals defined by the module.
     ///
     /// Return the global variable reference that should be used to access the global and the
     /// WebAssembly type of the global.
-    fn make_global(
-        &mut self,
-        func: &mut ir::Function,
-        index: GlobalIndex,
-    ) -> WasmResult<GlobalVariable>;
+    fn make_global(&mut self, func: &mut ir::Function, index: GlobalIndex) -> GlobalVariable;
 
     /// Set up the necessary preamble definitions in `func` to access the linear memory identified
     /// by `index`.
     ///
     /// The index space covers both imported and locally declared memories.
-    fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult<ir::Heap>;
+    fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> ir::Heap;
 
     /// Set up the necessary preamble definitions in `func` to access the table identified
     /// by `index`.
     ///
     /// The index space covers both imported and locally declared tables.
-    fn make_table(&mut self, func: &mut ir::Function, index: TableIndex) -> WasmResult<ir::Table>;
+    fn make_table(&mut self, func: &mut ir::Function, index: TableIndex) -> ir::Table;
 
     /// Set up a signature definition in the preamble of `func` that can be used for an indirect
     /// call with signature `index`.
     ///
     /// The signature may contain additional arguments needed for an indirect call, but the
     /// arguments marked as `ArgumentPurpose::Normal` must correspond to the WebAssembly signature
     /// arguments.
     ///
     /// The signature will only be used for indirect calls, even if the module has direct function
     /// calls with the same WebAssembly type.
-    fn make_indirect_sig(
-        &mut self,
-        func: &mut ir::Function,
-        index: SignatureIndex,
-    ) -> WasmResult<ir::SigRef>;
+    fn make_indirect_sig(&mut self, func: &mut ir::Function, index: SignatureIndex) -> ir::SigRef;
 
     /// Set up an external function definition in the preamble of `func` that can be used to
     /// directly call the function `index`.
     ///
     /// The index space covers both imported functions and functions defined in the current module.
     ///
     /// The function's signature may contain additional arguments needed for a direct call, but the
     /// arguments marked as `ArgumentPurpose::Normal` must correspond to the WebAssembly signature
     /// arguments.
     ///
     /// The function's signature will only be used for direct calls, even if the module has
     /// indirect calls with the same WebAssembly type.
-    fn make_direct_func(
-        &mut self,
-        func: &mut ir::Function,
-        index: FuncIndex,
-    ) -> WasmResult<ir::FuncRef>;
+    fn make_direct_func(&mut self, func: &mut ir::Function, index: FuncIndex) -> ir::FuncRef;
 
     /// Translate a `call_indirect` WebAssembly instruction at `pos`.
     ///
     /// Insert instructions at `pos` for an indirect call to the function `callee` in the table
     /// `table_index` with WebAssembly signature `sig_index`. The `callee` value will have type
     /// `i32`.
     ///
     /// The signature `sig_ref` was previously created by `make_indirect_sig()`.
@@ -252,19 +221,25 @@ pub trait FuncEnvironment {
         index: MemoryIndex,
         heap: ir::Heap,
     ) -> WasmResult<ir::Value>;
 
     /// Emit code at the beginning of every wasm loop.
     ///
     /// This can be used to insert explicit interrupt or safepoint checking at
     /// the beginnings of loops.
-    fn translate_loop_header(&mut self, _pos: FuncCursor) -> WasmResult<()> {
+    fn translate_loop_header(&mut self, _pos: FuncCursor) {
         // By default, don't emit anything.
-        Ok(())
+    }
+
+    /// Should the code be structured to use a single `fallthrough_return` instruction at the end
+    /// of the function body, rather than `return` instructions as needed? This is used by VMs
+    /// to append custom epilogues.
+    fn return_mode(&self) -> ReturnMode {
+        ReturnMode::NormalReturns
     }
 }
 
 /// An object satisfying the `ModuleEnvironment` trait can be passed as argument to the
 /// [`translate_module`](fn.translate_module.html) function. These methods should not be called
 /// by the user, they are only for `cranelift-wasm` internal use.
 pub trait ModuleEnvironment<'data> {
     /// Get the information needed to produce Cranelift IR for the current target.
--- a/third_party/rust/cranelift-wasm/src/func_translator.rs
+++ b/third_party/rust/cranelift-wasm/src/func_translator.rs
@@ -1,16 +1,16 @@
 //! Stand-alone WebAssembly to Cranelift IR translator.
 //!
 //! This module defines the `FuncTranslator` type which can translate a single WebAssembly
 //! function to Cranelift IR guided by a `FuncEnvironment` which provides information about the
 //! WebAssembly module and the runtime environment.
 
 use crate::code_translator::translate_operator;
-use crate::environ::{FuncEnvironment, ReturnMode, WasmError, WasmResult};
+use crate::environ::{FuncEnvironment, ReturnMode, WasmResult};
 use crate::state::TranslationState;
 use cranelift_codegen::entity::EntityRef;
 use cranelift_codegen::ir::{self, Ebb, InstBuilder};
 use cranelift_codegen::timing;
 use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
 use log::info;
 use wasmparser::{self, BinaryReader};
 
@@ -142,49 +142,48 @@ fn parse_local_decls(
 ) -> WasmResult<()> {
     let mut next_local = num_params;
     let local_count = reader.read_local_count()?;
 
     let mut locals_total = 0;
     for _ in 0..local_count {
         builder.set_srcloc(cur_srcloc(reader));
         let (count, ty) = reader.read_local_decl(&mut locals_total)?;
-        declare_locals(builder, count, ty, &mut next_local)?;
+        declare_locals(builder, count, ty, &mut next_local);
     }
 
     Ok(())
 }
 
 /// Declare `count` local variables of the same type, starting from `next_local`.
 ///
 /// Fail of too many locals are declared in the function, or if the type is not valid for a local.
 fn declare_locals(
     builder: &mut FunctionBuilder,
     count: u32,
     wasm_type: wasmparser::Type,
     next_local: &mut usize,
-) -> WasmResult<()> {
+) {
     // All locals are initialized to 0.
     use wasmparser::Type::*;
     let zeroval = match wasm_type {
         I32 => builder.ins().iconst(ir::types::I32, 0),
         I64 => builder.ins().iconst(ir::types::I64, 0),
         F32 => builder.ins().f32const(ir::immediates::Ieee32::with_bits(0)),
         F64 => builder.ins().f64const(ir::immediates::Ieee64::with_bits(0)),
-        _ => return Err(WasmError::Unsupported("unsupported local type")),
+        _ => panic!("invalid local type"),
     };
 
     let ty = builder.func.dfg.value_type(zeroval);
     for _ in 0..count {
         let local = Variable::new(*next_local);
         builder.declare_var(local, ty);
         builder.def_var(local, zeroval);
         *next_local += 1;
     }
-    Ok(())
 }
 
 /// Parse the function body in `reader`.
 ///
 /// This assumes that the local variable declarations have already been parsed and function
 /// arguments and locals are declared in the builder.
 fn parse_function_body<FE: FuncEnvironment + ?Sized>(
     mut reader: BinaryReader,
--- a/third_party/rust/cranelift-wasm/src/lib.rs
+++ b/third_party/rust/cranelift-wasm/src/lib.rs
@@ -33,26 +33,19 @@
 #[cfg(not(feature = "std"))]
 #[macro_use]
 extern crate alloc as std;
 #[cfg(feature = "std")]
 #[macro_use]
 extern crate std;
 
 #[cfg(not(feature = "std"))]
-use hashmap_core::{
-    hash_map::Entry::{Occupied, Vacant},
-    map as hash_map, HashMap,
-};
+use hashmap_core::{map as hash_map, HashMap};
 #[cfg(feature = "std")]
-use std::collections::{
-    hash_map,
-    hash_map::Entry::{Occupied, Vacant},
-    HashMap,
-};
+use std::collections::{hash_map, HashMap};
 
 mod code_translator;
 mod environ;
 mod func_translator;
 mod module_translator;
 mod sections_translator;
 mod state;
 mod translation_utils;
--- a/third_party/rust/cranelift-wasm/src/state.rs
+++ b/third_party/rust/cranelift-wasm/src/state.rs
@@ -1,15 +1,15 @@
 //! WebAssembly function translation state.
 //!
 //! The `TranslationState` struct defined in this module is used to keep track of the WebAssembly
 //! value and control stacks during the translation of a single function.
 
-use super::{HashMap, Occupied, Vacant};
-use crate::environ::{FuncEnvironment, GlobalVariable, WasmResult};
+use super::HashMap;
+use crate::environ::{FuncEnvironment, GlobalVariable};
 use crate::translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};
 use cranelift_codegen::ir::{self, Ebb, Inst, Value};
 use std::vec::Vec;
 
 /// A control stack frame can be an `if`, a `block` or a `loop`, each one having the following
 /// fields:
 ///
 /// - `destination`: reference to the `Ebb` that will hold the code after the control block;
@@ -280,93 +280,87 @@ impl TranslationState {
     /// Get the `GlobalVariable` reference that should be used to access the global variable
     /// `index`. Create the reference if necessary.
     /// Also return the WebAssembly type of the global.
     pub fn get_global<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
-    ) -> WasmResult<GlobalVariable> {
+    ) -> GlobalVariable {
         let index = GlobalIndex::from_u32(index);
-        match self.globals.entry(index) {
-            Occupied(entry) => Ok(*entry.get()),
-            Vacant(entry) => Ok(*entry.insert(environ.make_global(func, index)?)),
-        }
+        *self
+            .globals
+            .entry(index)
+            .or_insert_with(|| environ.make_global(func, index))
     }
 
     /// Get the `Heap` reference that should be used to access linear memory `index`.
     /// Create the reference if necessary.
     pub fn get_heap<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
-    ) -> WasmResult<ir::Heap> {
+    ) -> ir::Heap {
         let index = MemoryIndex::from_u32(index);
-        match self.heaps.entry(index) {
-            Occupied(entry) => Ok(*entry.get()),
-            Vacant(entry) => Ok(*entry.insert(environ.make_heap(func, index)?)),
-        }
+        *self
+            .heaps
+            .entry(index)
+            .or_insert_with(|| environ.make_heap(func, index))
     }
 
     /// Get the `Table` reference that should be used to access table `index`.
     /// Create the reference if necessary.
     pub fn get_table<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
-    ) -> WasmResult<ir::Table> {
+    ) -> ir::Table {
         let index = TableIndex::from_u32(index);
-        match self.tables.entry(index) {
-            Occupied(entry) => Ok(*entry.get()),
-            Vacant(entry) => Ok(*entry.insert(environ.make_table(func, index)?)),
-        }
+        *self
+            .tables
+            .entry(index)
+            .or_insert_with(|| environ.make_table(func, index))
     }
 
     /// Get the `SigRef` reference that should be used to make an indirect call with signature
     /// `index`. Also return the number of WebAssembly arguments in the signature.
     ///
     /// Create the signature if necessary.
     pub fn get_indirect_sig<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
-    ) -> WasmResult<(ir::SigRef, usize)> {
+    ) -> (ir::SigRef, usize) {
         let index = SignatureIndex::from_u32(index);
-        match self.signatures.entry(index) {
-            Occupied(entry) => Ok(*entry.get()),
-            Vacant(entry) => {
-                let sig = environ.make_indirect_sig(func, index)?;
-                Ok(*entry.insert((sig, normal_args(&func.dfg.signatures[sig]))))
-            }
-        }
+        *self.signatures.entry(index).or_insert_with(|| {
+            let sig = environ.make_indirect_sig(func, index);
+            (sig, normal_args(&func.dfg.signatures[sig]))
+        })
     }
 
     /// Get the `FuncRef` reference that should be used to make a direct call to function
     /// `index`. Also return the number of WebAssembly arguments in the signature.
     ///
     /// Create the function reference if necessary.
     pub fn get_direct_func<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
-    ) -> WasmResult<(ir::FuncRef, usize)> {
+    ) -> (ir::FuncRef, usize) {
         let index = FuncIndex::from_u32(index);
-        match self.functions.entry(index) {
-            Occupied(entry) => Ok(*entry.get()),
-            Vacant(entry) => {
-                let fref = environ.make_direct_func(func, index)?;
-                let sig = func.dfg.ext_funcs[fref].signature;
-                Ok(*entry.insert((fref, normal_args(&func.dfg.signatures[sig]))))
-            }
-        }
+        *self.functions.entry(index).or_insert_with(|| {
+            let fref = environ.make_direct_func(func, index);
+            let sig = func.dfg.ext_funcs[fref].signature;
+            (fref, normal_args(&func.dfg.signatures[sig]))
+        })
     }
 }
 
 /// Count the number of normal parameters in a signature.
 /// Exclude special-purpose parameters that represent runtime stuff and not WebAssembly arguments.
 fn normal_args(sig: &ir::Signature) -> usize {
     sig.params
         .iter()