ISLE: add support for extended left-hand sides with if-let clauses. (#4072)
This PR adds support for `if-let` clauses, as proposed in bytecodealliance/rfcs#21. These clauses augment the left-hand side (pattern-matching phase) of rules in the ISLE instruction-selection DSL with sub-patterns matching on sub-expressions. The ability to list additional match operations to perform, out-of-line from the original toplevel pattern, greatly simplifies some idioms. See the RFC for more details and examples of use.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
(type u32 (primitive u32))
|
||||
|
||||
(decl ctor (u32) u32)
|
||||
(rule (ctor x) x)
|
||||
|
||||
(decl entry (u32) u32)
|
||||
|
||||
(rule (entry x)
|
||||
(if-let y (ctor x))
|
||||
y)
|
||||
15
cranelift/isle/isle/isle_examples/fail/impure_rhs.isle
Normal file
15
cranelift/isle/isle/isle_examples/fail/impure_rhs.isle
Normal file
@@ -0,0 +1,15 @@
|
||||
(type u32 (primitive u32))
|
||||
|
||||
(decl pure ctor (u32) u32)
|
||||
(decl impure (u32) u32)
|
||||
|
||||
(decl entry (u32) u32)
|
||||
|
||||
(rule (entry x)
|
||||
(if-let y (ctor x))
|
||||
y)
|
||||
|
||||
(rule (ctor x)
|
||||
(impure x))
|
||||
|
||||
(rule (impure x) x)
|
||||
15
cranelift/isle/isle/isle_examples/link/borrows.isle
Normal file
15
cranelift/isle/isle/isle_examples/link/borrows.isle
Normal file
@@ -0,0 +1,15 @@
|
||||
(type u32 (primitive u32))
|
||||
(type A extern (enum (B (x u32) (y u32))))
|
||||
|
||||
(decl get_a (A) u32)
|
||||
(extern extractor get_a get_a)
|
||||
|
||||
(decl pure u32_pure (u32) u32)
|
||||
(extern constructor u32_pure u32_pure)
|
||||
|
||||
(decl entry (u32) u32)
|
||||
(rule (entry x @ (get_a a1))
|
||||
(if-let (get_a a2) x)
|
||||
(if-let (A.B p q) a1)
|
||||
(if-let r (u32_pure p))
|
||||
r)
|
||||
21
cranelift/isle/isle/isle_examples/link/borrows_main.rs
Normal file
21
cranelift/isle/isle/isle_examples/link/borrows_main.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
mod borrows;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum A {
|
||||
B { x: u32, y: u32 },
|
||||
}
|
||||
|
||||
struct Context(A);
|
||||
impl borrows::Context for Context {
|
||||
fn get_a(&mut self, _: u32) -> Option<A> {
|
||||
Some(self.0.clone())
|
||||
}
|
||||
|
||||
fn u32_pure(&mut self, value: u32) -> Option<u32> {
|
||||
Some(value + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
borrows::constructor_entry(&mut Context(A::B { x: 1, y: 2 }), 42);
|
||||
}
|
||||
29
cranelift/isle/isle/isle_examples/link/iflets.isle
Normal file
29
cranelift/isle/isle/isle_examples/link/iflets.isle
Normal file
@@ -0,0 +1,29 @@
|
||||
(type u32 (primitive u32))
|
||||
|
||||
(decl pure A (u32 u32) u32)
|
||||
(extern constructor A A)
|
||||
|
||||
(decl B (u32 u32) u32)
|
||||
(extern extractor B B)
|
||||
|
||||
(decl C (u32 u32 u32 u32) u32)
|
||||
|
||||
(decl pure predicate () u32)
|
||||
(rule (predicate) 1)
|
||||
|
||||
(rule (C a b c (B d e))
|
||||
(if-let (B f g) d)
|
||||
(if-let h (A a b))
|
||||
(A h a))
|
||||
|
||||
(rule (C a b c d)
|
||||
(if (predicate))
|
||||
42)
|
||||
|
||||
(rule (C a b a b)
|
||||
(if-let x (D a b))
|
||||
x)
|
||||
|
||||
(decl pure D (u32 u32) u32)
|
||||
(rule (D x 0) x)
|
||||
(rule (D 0 x) x)
|
||||
16
cranelift/isle/isle/isle_examples/link/iflets_main.rs
Normal file
16
cranelift/isle/isle/isle_examples/link/iflets_main.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
mod iflets;
|
||||
|
||||
struct Context;
|
||||
impl iflets::Context for Context {
|
||||
fn A(&mut self, a: u32, b: u32) -> Option<u32> {
|
||||
Some(a + b)
|
||||
}
|
||||
|
||||
fn B(&mut self, value: u32) -> Option<(u32, u32)> {
|
||||
Some((value, value + 1))
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
iflets::constructor_C(&mut Context, 1, 2, 3, 4);
|
||||
}
|
||||
Reference in New Issue
Block a user