Skip to content

Commit

Permalink
feat: implement some helper functions required for common sub-express…
Browse files Browse the repository at this point in the history
…ion elimination.
  • Loading branch information
plusvic committed Oct 31, 2024
1 parent 8917e35 commit 1846f42
Show file tree
Hide file tree
Showing 8 changed files with 822 additions and 295 deletions.
611 changes: 549 additions & 62 deletions lib/src/compiler/ir/mod.rs

Large diffs are not rendered by default.

42 changes: 41 additions & 1 deletion lib/src/compiler/ir/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use std::fs;
use std::io::BufWriter;
use std::mem::size_of;

use crate::compiler::Expr;
use crate::compiler::{Expr, IR};
use crate::types::TypeValue;
use crate::Compiler;

#[test]
Expand All @@ -12,6 +13,45 @@ fn expr_size() {
assert_eq!(size_of::<Expr>(), 32);
}

#[test]
fn ancestors() {
let mut ir = IR::new();

let const_1 = ir.constant(TypeValue::const_integer_from(1));
let const_2 = ir.constant(TypeValue::const_integer_from(2));
let const_3 = ir.constant(TypeValue::const_integer_from(2));
let add = ir.add(vec![const_2, const_3]).unwrap();
let root = ir.add(vec![const_1, add]).unwrap();

let mut ancestors = ir.ancestors(const_3);
assert_eq!(ancestors.next(), Some(add));
assert_eq!(ancestors.next(), Some(root));
assert_eq!(ancestors.next(), None);

let mut ancestors = ir.ancestors(const_1);
assert_eq!(ancestors.next(), Some(root));
assert_eq!(ancestors.next(), None);

let mut ancestors = ir.ancestors(root);
assert_eq!(ancestors.next(), None);
}

#[test]
fn common_ancestor() {
let mut ir = IR::new();

let const_1 = ir.constant(TypeValue::const_integer_from(1));
let const_2 = ir.constant(TypeValue::const_integer_from(2));
let const_3 = ir.constant(TypeValue::const_integer_from(2));
let add = ir.add(vec![const_2, const_3]).unwrap();
let root = ir.add(vec![const_1, add]).unwrap();

assert_eq!(ir.common_ancestor(&[const_1, const_3]), root);
assert_eq!(ir.common_ancestor(&[const_2, const_3]), add);
assert_eq!(ir.common_ancestor(&[const_1, const_1]), const_1);
assert_eq!(ir.common_ancestor(&[const_1, add, const_2]), root);
}

#[test]
fn ir() {
let files: Vec<_> = globwalk::glob("src/compiler/ir/tests/testdata/*.in")
Expand Down
98 changes: 49 additions & 49 deletions lib/src/compiler/ir/tests/testdata/1.folding.ir
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
RULE test_1
EQ [0x1e87f9ecd59c9f97]
CONST integer(1)
CONST integer(1)
id:12 parent:None: EQ [0x1e87f9ecd59c9f97]
id:10 parent:12: CONST integer(1)
id:11 parent:12: CONST integer(1)

RULE test_2
GT [0x936af95517c74992]
DIV [0x75c0510b526a94ab]
CONST integer(2)
CONST integer(1)
CONST integer(1)
id:6 parent:None: GT [0x936af95517c74992]
id:4 parent:6: DIV [0x75c0510b526a94ab]
id:2 parent:4: CONST integer(2)
id:3 parent:4: CONST integer(1)
id:5 parent:6: CONST integer(1)

RULE test_3
LE [0x63b2e857a1254c2b]
SHR [0x8dd6307742aa2311]
SHL [0x48eeb57428a0dbf0]
CONST integer(1)
CONST integer(2)
CONST integer(1)
CONST integer(2)
id:6 parent:None: LE [0x63b2e857a1254c2b]
id:4 parent:6: SHR [0x8dd6307742aa2311]
id:2 parent:4: SHL [0x48eeb57428a0dbf0]
id:0 parent:2: CONST integer(1)
id:1 parent:2: CONST integer(2)
id:3 parent:4: CONST integer(1)
id:5 parent:6: CONST integer(2)

RULE test_4
EQ [0x82d0fbda86ff9c76]
CONST integer(8)
CONST integer(8)
id:14 parent:None: EQ [0x82d0fbda86ff9c76]
id:12 parent:14: CONST integer(8)
id:13 parent:14: CONST integer(8)

RULE test_5
AND [0xf8ebdbba687cc112]
EQ [0x78262602520cebf1]
FIELD_ACCESS [0x6d93cf8c80a38e93]
IDENT Field { index: 0, is_root: true, type_value: struct }
IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
CONST integer(0)
id:12 parent:None: AND [0xf8ebdbba687cc112]
id:8 parent:12: EQ [0x78262602520cebf1]
id:6 parent:8: FIELD_ACCESS [0x6d93cf8c80a38e93]
id:4 parent:6: IDENT Field { index: 0, is_root: true, type_value: struct }
id:5 parent:6: IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
id:7 parent:8: CONST integer(0)

RULE test_6
ADD [0xeb09fb0c289a1e4a]
FIELD_ACCESS [0x6d93cf8c80a38e93]
IDENT Field { index: 0, is_root: true, type_value: struct }
IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
CONST integer(1)
CONST integer(2)
id:5 parent:None: ADD [0xeb09fb0c289a1e4a]
id:2 parent:5: FIELD_ACCESS [0x6d93cf8c80a38e93]
id:0 parent:2: IDENT Field { index: 0, is_root: true, type_value: struct }
id:1 parent:2: IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
id:3 parent:5: CONST integer(1)
id:4 parent:5: CONST integer(2)

RULE test_7
AND [0xb21fa80def581aea]
CONTAINS [0x702eaf70b18909ff]
CONST string("foobar")
CONST string("bar")
ICONTAINS [0xe30a191883a20729]
CONST string("foobar")
CONST string("BAR")
STARTS_WITH [0xc963b1bf1e8d9506]
CONST string("foobar")
CONST string("foo")
ISTARTS_WITH [0x1ce5974aa4aaacaa]
CONST string("foobar")
CONST string("FOO")
ENDS_WITH [0x4394dbecb8c89956]
CONST string("foobar")
CONST string("bar")
IENDS_WITH [0xb67045948ae19680]
CONST string("foobar")
CONST string("BAR")
id:18 parent:None: AND [0xb21fa80def581aea]
id:2 parent:18: CONTAINS [0x702eaf70b18909ff]
id:0 parent:2: CONST string("foobar")
id:1 parent:2: CONST string("bar")
id:5 parent:18: ICONTAINS [0xe30a191883a20729]
id:3 parent:5: CONST string("foobar")
id:4 parent:5: CONST string("BAR")
id:8 parent:18: STARTS_WITH [0xc963b1bf1e8d9506]
id:6 parent:8: CONST string("foobar")
id:7 parent:8: CONST string("foo")
id:11 parent:18: ISTARTS_WITH [0x1ce5974aa4aaacaa]
id:9 parent:11: CONST string("foobar")
id:10 parent:11: CONST string("FOO")
id:14 parent:18: ENDS_WITH [0x4394dbecb8c89956]
id:12 parent:14: CONST string("foobar")
id:13 parent:14: CONST string("bar")
id:17 parent:18: IENDS_WITH [0xb67045948ae19680]
id:15 parent:17: CONST string("foobar")
id:16 parent:17: CONST string("BAR")

126 changes: 63 additions & 63 deletions lib/src/compiler/ir/tests/testdata/1.no-folding.ir
Original file line number Diff line number Diff line change
@@ -1,77 +1,77 @@
RULE test_1
EQ [0x65918958e229b41b]
SUB [0xbb5b2d3c003a978d]
ADD [0x32e284abcc26d05b]
CONST integer(1)
CONST integer(1)
CONST integer(1)
CONST integer(1)
id:12 parent:None: EQ [0x65918958e229b41b]
id:10 parent:12: SUB [0xbb5b2d3c003a978d]
id:8 parent:10: ADD [0x32e284abcc26d05b]
id:6 parent:8: CONST integer(1)
id:7 parent:8: CONST integer(1)
id:9 parent:10: CONST integer(1)
id:11 parent:12: CONST integer(1)

RULE test_2
GT [0x931bcdb2c7afb608]
DIV [0xf2b3602767487d08]
MUL [0x23a380280d1b4f32]
CONST integer(1)
CONST integer(2)
CONST integer(1)
CONST integer(1)
id:6 parent:None: GT [0x931bcdb2c7afb608]
id:4 parent:6: DIV [0xf2b3602767487d08]
id:2 parent:4: MUL [0x23a380280d1b4f32]
id:0 parent:2: CONST integer(1)
id:1 parent:2: CONST integer(2)
id:3 parent:4: CONST integer(1)
id:5 parent:6: CONST integer(1)

RULE test_3
LE [0x63b2e857a1254c2b]
SHR [0x8dd6307742aa2311]
SHL [0x48eeb57428a0dbf0]
CONST integer(1)
CONST integer(2)
CONST integer(1)
CONST integer(2)
id:6 parent:None: LE [0x63b2e857a1254c2b]
id:4 parent:6: SHR [0x8dd6307742aa2311]
id:2 parent:4: SHL [0x48eeb57428a0dbf0]
id:0 parent:2: CONST integer(1)
id:1 parent:2: CONST integer(2)
id:3 parent:4: CONST integer(1)
id:5 parent:6: CONST integer(2)

RULE test_4
EQ [0x2240111cff945ff5]
SUB [0xa076dada583953db]
CONST integer(4)
MUL [0xd1635797e1f50589]
MINUS [0xb5577ca94105cb4b]
CONST integer(2)
CONST integer(2)
CONST integer(8)
id:14 parent:None: EQ [0x2240111cff945ff5]
id:12 parent:14: SUB [0xa076dada583953db]
id:7 parent:12: CONST integer(4)
id:11 parent:12: MUL [0xd1635797e1f50589]
id:9 parent:11: MINUS [0xb5577ca94105cb4b]
id:8 parent:9: CONST integer(2)
id:10 parent:11: CONST integer(2)
id:13 parent:14: CONST integer(8)

RULE test_5
AND [0x1e7c6065ed040c49]
EQ [0x78262602520cebf1]
FIELD_ACCESS [0x6d93cf8c80a38e93]
IDENT Field { index: 0, is_root: true, type_value: struct }
IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
CONST integer(0)
CONST boolean(true)
NOT [0x2c3c4fda5217a5f3]
CONST boolean(false)
id:12 parent:None: AND [0x1e7c6065ed040c49]
id:8 parent:12: EQ [0x78262602520cebf1]
id:6 parent:8: FIELD_ACCESS [0x6d93cf8c80a38e93]
id:4 parent:6: IDENT Field { index: 0, is_root: true, type_value: struct }
id:5 parent:6: IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
id:7 parent:8: CONST integer(0)
id:9 parent:12: CONST boolean(true)
id:11 parent:12: NOT [0x2c3c4fda5217a5f3]
id:10 parent:11: CONST boolean(false)

RULE test_6
ADD [0xeb09fb0c289a1e4a]
FIELD_ACCESS [0x6d93cf8c80a38e93]
IDENT Field { index: 0, is_root: true, type_value: struct }
IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
CONST integer(1)
CONST integer(2)
id:5 parent:None: ADD [0xeb09fb0c289a1e4a]
id:2 parent:5: FIELD_ACCESS [0x6d93cf8c80a38e93]
id:0 parent:2: IDENT Field { index: 0, is_root: true, type_value: struct }
id:1 parent:2: IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
id:3 parent:5: CONST integer(1)
id:4 parent:5: CONST integer(2)

RULE test_7
AND [0xb21fa80def581aea]
CONTAINS [0x702eaf70b18909ff]
CONST string("foobar")
CONST string("bar")
ICONTAINS [0xe30a191883a20729]
CONST string("foobar")
CONST string("BAR")
STARTS_WITH [0xc963b1bf1e8d9506]
CONST string("foobar")
CONST string("foo")
ISTARTS_WITH [0x1ce5974aa4aaacaa]
CONST string("foobar")
CONST string("FOO")
ENDS_WITH [0x4394dbecb8c89956]
CONST string("foobar")
CONST string("bar")
IENDS_WITH [0xb67045948ae19680]
CONST string("foobar")
CONST string("BAR")
id:18 parent:None: AND [0xb21fa80def581aea]
id:2 parent:18: CONTAINS [0x702eaf70b18909ff]
id:0 parent:2: CONST string("foobar")
id:1 parent:2: CONST string("bar")
id:5 parent:18: ICONTAINS [0xe30a191883a20729]
id:3 parent:5: CONST string("foobar")
id:4 parent:5: CONST string("BAR")
id:8 parent:18: STARTS_WITH [0xc963b1bf1e8d9506]
id:6 parent:8: CONST string("foobar")
id:7 parent:8: CONST string("foo")
id:11 parent:18: ISTARTS_WITH [0x1ce5974aa4aaacaa]
id:9 parent:11: CONST string("foobar")
id:10 parent:11: CONST string("FOO")
id:14 parent:18: ENDS_WITH [0x4394dbecb8c89956]
id:12 parent:14: CONST string("foobar")
id:13 parent:14: CONST string("bar")
id:17 parent:18: IENDS_WITH [0xb67045948ae19680]
id:15 parent:17: CONST string("foobar")
id:16 parent:17: CONST string("BAR")

86 changes: 43 additions & 43 deletions lib/src/compiler/ir/tests/testdata/2.folding.ir
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
RULE test
FOR_IN [0x99a2a38042db5122]
CONST integer(0)
PATTERN_COUNT PatternIdx(0) [0xa0a54267ad7f087f]
FOR_IN [0x72faaec8968d2cad]
CONST integer(0)
PATTERN_COUNT PatternIdx(1) [0x5378b902c7004afb]
FOR_IN [0xca11ac274b61c7b1]
FIELD_ACCESS [0x7226744cca3b46]
IDENT Field { index: 0, is_root: true, type_value: struct }
IDENT Field { index: 19, is_root: false, type_value: array }
AND [0xb7cf927507bf6496]
LE [0x33cdc6e2f17a3eac]
FIELD_ACCESS [0xa441e24a6191870f]
IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
PATTERN_OFFSET PatternIdx(0) INDEX [0xc12206c6ddd8d9c9]
IDENT Var { var: Var { frame_id: 1, ty: integer, index: 5 }, type_value: integer(unknown) }
LE [0xfceeb4c35fe4948]
PATTERN_OFFSET PatternIdx(0) INDEX [0xc12206c6ddd8d9c9]
IDENT Var { var: Var { frame_id: 1, ty: integer, index: 5 }, type_value: integer(unknown) }
ADD [0x10e80dd91c17496c]
FIELD_ACCESS [0xa441e24a6191870f]
IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
FIELD_ACCESS [0x571558e57b22c98b]
IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
LE [0xa9d3de09cdf88a2e]
FIELD_ACCESS [0xa441e24a6191870f]
IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
PATTERN_OFFSET PatternIdx(1) INDEX [0x37281dedba57254c]
IDENT Var { var: Var { frame_id: 2, ty: integer, index: 11 }, type_value: integer(unknown) }
LE [0xd470a5399c77b4a4]
PATTERN_OFFSET PatternIdx(1) INDEX [0x37281dedba57254c]
IDENT Var { var: Var { frame_id: 2, ty: integer, index: 11 }, type_value: integer(unknown) }
ADD [0x10e80dd91c17496c]
FIELD_ACCESS [0xa441e24a6191870f]
IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
FIELD_ACCESS [0x571558e57b22c98b]
IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
id:42 parent:None: FOR_IN [0x99a2a38042db5122]
id:0 parent:42: CONST integer(0)
id:1 parent:42: PATTERN_COUNT PatternIdx(0) [0xa0a54267ad7f087f]
id:41 parent:42: FOR_IN [0x72faaec8968d2cad]
id:2 parent:41: CONST integer(0)
id:3 parent:41: PATTERN_COUNT PatternIdx(1) [0x5378b902c7004afb]
id:40 parent:41: FOR_IN [0xca11ac274b61c7b1]
id:6 parent:40: FIELD_ACCESS [0x7226744cca3b46]
id:4 parent:6: IDENT Field { index: 0, is_root: true, type_value: struct }
id:5 parent:6: IDENT Field { index: 19, is_root: false, type_value: array }
id:39 parent:40: AND [0xb7cf927507bf6496]
id:12 parent:39: LE [0x33cdc6e2f17a3eac]
id:9 parent:12: FIELD_ACCESS [0xa441e24a6191870f]
id:7 parent:9: IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
id:8 parent:9: IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
id:11 parent:12: PATTERN_OFFSET PatternIdx(0) INDEX [0xc12206c6ddd8d9c9]
id:10 parent:11: IDENT Var { var: Var { frame_id: 1, ty: integer, index: 5 }, type_value: integer(unknown) }
id:22 parent:39: LE [0xfceeb4c35fe4948]
id:14 parent:22: PATTERN_OFFSET PatternIdx(0) INDEX [0xc12206c6ddd8d9c9]
id:13 parent:14: IDENT Var { var: Var { frame_id: 1, ty: integer, index: 5 }, type_value: integer(unknown) }
id:21 parent:22: ADD [0x10e80dd91c17496c]
id:17 parent:21: FIELD_ACCESS [0xa441e24a6191870f]
id:15 parent:17: IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
id:16 parent:17: IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
id:20 parent:21: FIELD_ACCESS [0x571558e57b22c98b]
id:18 parent:20: IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
id:19 parent:20: IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }
id:28 parent:39: LE [0xa9d3de09cdf88a2e]
id:25 parent:28: FIELD_ACCESS [0xa441e24a6191870f]
id:23 parent:25: IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
id:24 parent:25: IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
id:27 parent:28: PATTERN_OFFSET PatternIdx(1) INDEX [0x37281dedba57254c]
id:26 parent:27: IDENT Var { var: Var { frame_id: 2, ty: integer, index: 11 }, type_value: integer(unknown) }
id:38 parent:39: LE [0xd470a5399c77b4a4]
id:30 parent:38: PATTERN_OFFSET PatternIdx(1) INDEX [0x37281dedba57254c]
id:29 parent:30: IDENT Var { var: Var { frame_id: 2, ty: integer, index: 11 }, type_value: integer(unknown) }
id:37 parent:38: ADD [0x10e80dd91c17496c]
id:33 parent:37: FIELD_ACCESS [0xa441e24a6191870f]
id:31 parent:33: IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
id:32 parent:33: IDENT Field { index: 0, is_root: false, type_value: integer(unknown) }
id:36 parent:37: FIELD_ACCESS [0x571558e57b22c98b]
id:34 parent:36: IDENT Var { var: Var { frame_id: 3, ty: struct, index: 17 }, type_value: struct }
id:35 parent:36: IDENT Field { index: 1, is_root: false, type_value: integer(unknown) }

Loading

0 comments on commit 1846f42

Please # to comment.