Skip to content

Commit

Permalink
[sc-481] Add transformation passes to hvm-core. (#69)
Browse files Browse the repository at this point in the history
Co-authored-by: tjjfvi <[email protected]>
  • Loading branch information
FranchuFranchu and tjjfvi authored Mar 4, 2024
1 parent 2867cb7 commit f3135d7
Show file tree
Hide file tree
Showing 27 changed files with 480 additions and 208 deletions.
14 changes: 7 additions & 7 deletions benches/benches.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use hvmc::{
ast::{Book, Net},
host::Host,
run::{Heap, Net as RtNet, Strict},
stdlib::create_host,
};
use std::{
fs,
Expand Down Expand Up @@ -60,24 +60,24 @@ fn run_file(path: &PathBuf, group: Option<String>, c: &mut Criterion) {

fn benchmark(file_name: &str, book: Book, c: &mut Criterion) {
let area = Heap::new_words(1 << 29);
let host = Host::new(&book);
let host = create_host(&book);
c.bench_function(file_name, |b| {
b.iter(|| {
let mut net = RtNet::<Strict>::new(&area);
net.boot(host.defs.get("main").unwrap());
net.boot(host.lock().unwrap().defs.get("main").unwrap());
black_box(black_box(net).normal())
});
});
}

fn benchmark_group(file_name: &str, group: String, book: Book, c: &mut Criterion) {
let area = Heap::new_words(1 << 29);
let host = Host::new(&book);
let host = create_host(&book);

c.benchmark_group(group).bench_function(file_name, |b| {
b.iter(|| {
let mut net = RtNet::<Strict>::new(&area);
net.boot(host.defs.get("main").unwrap());
net.boot(host.lock().unwrap().defs.get("main").unwrap());
black_box(black_box(net).normal())
});
});
Expand All @@ -99,11 +99,11 @@ fn interact_benchmark(c: &mut Criterion) {
let mut book = Book::default();
book.insert("main".to_string(), Net { root: Era, redexes: vec![redex] });
let area = Heap::new_words(1 << 24);
let host = Host::new(&book);
let host = create_host(&book);
group.bench_function(name, |b| {
b.iter(|| {
let mut net = RtNet::<Strict>::new(&area);
net.boot(host.defs.get("main").unwrap());
net.boot(host.lock().unwrap().defs.get("main").unwrap());
black_box(black_box(net).normal())
});
});
Expand Down
4 changes: 3 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
"language": "en",
"words": [
"anni",
"annihilations",
"backlinks",
"backoffs",
"combinators",
"condvar",
"dereferencable",
"dref",
"dups",
"effectful",
"fmts",
"fuzzer",
"hasher",
Expand Down Expand Up @@ -57,5 +59,5 @@
"vtable"
],
"files": ["**/*.rs", "**/*.md"],
"ignoreRegExpList": ["HexValues"]
"ignoreRegExpList": ["HexValues", "(?<![a-zA-Z-])-O"]
}
2 changes: 1 addition & 1 deletion examples/machine_u32/num_match.hvm2
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pred = λx match x {
0: 0
+: x-1
1+: x-1
}

main = (pred 10)
4 changes: 2 additions & 2 deletions examples/sort/bitonic/bitonic_sort_lam.hvm2
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Node = @x0 @x1 @Leaf @Node (Node x0 x1)

swap = λn match n {
0: λx0 λx1 (Node x0 x1)
+: λx0 λx1 (Node x1 x0)
1+: λx0 λx1 (Node x1 x0)
}

warp = λa
Expand Down Expand Up @@ -42,7 +42,7 @@ sort = λa

gen = λn match n {
0: λx (Leaf x)
+: λx (Node (gen n-1 (* x 2)) (gen n-1 (+ (* x 2) 1)))
1+: λx (Node (gen n-1 (* x 2)) (gen n-1 (+ (* x 2) 1)))
}

rev = λa
Expand Down
4 changes: 2 additions & 2 deletions examples/sort/merge/merge_sort.hvm2
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ merge = λxs
let ys_nil = λx λxs (List.cons x xs)
let ys_cons = λy λys λx λxs
let t = λt (t (List.cons x) λx(x) (List.cons y))
let t = let k = (< x y); (t (match k { 0: λaλbλcλt(t c a b); +: λaλbλcλt(t a b c) }))
let t = let k = (< x y); (t (match k { 0: λaλbλcλt(t c a b); 1+: λaλbλcλt(t a b c) }))
(t λa λb λc (a (merge (b xs) (c ys))))
(ys ys_nil ys_cons x xs)
(xs xs_nil xs_cons)
Expand All @@ -23,7 +23,7 @@ sum = λxs

range = λn match n {
0: λx (Leaf x)
+: λx (Node (range n-1 (+ (* x 2) 1)) (range n-1 (* x 2)))
1+: λx (Node (range n-1 (+ (* x 2) 1)) (range n-1 (* x 2)))
}

main = (sum (sort (range 2 0)))
4 changes: 2 additions & 2 deletions examples/sort/radix/radix_sort_lam.hvm2
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Node = λx0 λx1 λfree λused λnode (node x0 x1)
// gen : u32 -> Arr
gen = λn match n {
0: λx (Single x)
+: λx
1+: λx
let x0 = (<< x 1)
let x1 = (| x0 1)
(Concat (gen n-1 x0) (gen n-1 x1))
Expand Down Expand Up @@ -102,7 +102,7 @@ radix = λn
// swap : u32 -> Map -> Map -> Map
swap = λn match n {
0: λx0 λx1 (Node x0 x1)
+: λx0 λx1 (Node x1 x0)
1+: λx0 λx1 (Node x1 x0)
}

// main : u32
Expand Down
25 changes: 21 additions & 4 deletions src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,43 @@ impl Host {
}

/// Converts all of the nets from the book into runtime defs, and inserts them
/// into the host.
/// into the host. The book must not have refs that are not in the book or the
/// host.
pub fn insert_book(&mut self, book: &Book) {
self.insert_book_with_default(book, &mut |x| panic!("Found reference {x:?}, which is not in the book!"))
}

/// Like `insert_book`, but allows specifying a function (`default_def`) that
/// will be run when the name of a definition is not found in the book.
/// The return value of the function will be inserted into the host.
pub fn insert_book_with_default(&mut self, book: &Book, default_def: &mut dyn FnMut(&str) -> DefRef) {
self.defs.reserve(book.len());
self.back.reserve(book.len());

// Because there may be circular dependencies, inserting the definitions
// must be done in two phases:

// First, we insert empty defs into the host. Even though their instructions
// are not yet set, the address of the def will not change, meaning that
// `net_to_runtime_def` can safely use `Port::new_def` on them.
for (name, labs) in calculate_label_sets(book, self) {
for (name, labs) in calculate_label_sets(book, |nam| match self.defs.get(nam) {
Some(x) => x.labs.clone(),
None => {
self.insert_def(&nam, default_def(nam));
self.defs[nam].labs.clone()
}
})
.into_iter()
{
let def = DefRef::Owned(Box::new(Def::new(labs, InterpretedDef::default())));
self.insert_def(name, def);
}

// Now that `defs` is fully populated, we can fill in the instructions of
// each of the new defs.
for (nam, net) in book.iter() {
let instr = ast_net_to_instructions(&self.defs, net);
let instr = ast_net_to_instructions(net, |nam| {
Port::new_ref(&self.defs[nam] /* calculate_label_sets already ensures all ref names are in self.defs */)
});
match self.defs.get_mut(nam).unwrap() {
DefRef::Owned(def) => def.downcast_mut::<InterpretedDef>().unwrap().data.instr = instr,
DefRef::Static(_) => unreachable!(),
Expand Down
Loading

0 comments on commit f3135d7

Please sign in to comment.