Skip to content

Commit

Permalink
fix: issues in CSE algorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
plusvic committed Nov 21, 2024
1 parent 4ee6955 commit 03f3ae9
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 168 deletions.
22 changes: 12 additions & 10 deletions lib/src/compiler/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -838,23 +838,25 @@ impl IR {
Some(hash) => hash,
None => continue 'dfs,
};
if let Some(exprs) = map.get(hash) {
// When the current expression is equal to some other
// expression, we don't want to traverse its children, as
// the children are going to be equal to the other
// expression's children.
if exprs.len() > 1 {
dfs.prune();
}
} else {
if !map.contains_key(hash) {
// When the entry was not found is because it was
// previously deleted while processing another expression
// that was equal to the current one. In such cases we
// won't need to traverse the current expression.
dfs.prune();
}
}
Event::Leave((expr_id, _, _)) => {
Event::Leave((expr_id, _, ctx)) => {
// All other expressions could be moved around, except those
// that are operands of a field access. That's because the
// operands of a field access can depend on the results
// produced by their siblings. For instance, in `foo[i].bar[0]`
// `bar[0]` depends on the result produced by `foo[i]`,
// `bar[0]` doesn't depend on `i` itself, but it depends on
// the result of `foo[i]`, which does.
if matches!(ctx, EventContext::FieldAccess) {
continue 'dfs;
}
let hash = match hashes.get(&expr_id) {
Some(hash) => hash,
None => continue 'dfs,
Expand Down
56 changes: 29 additions & 27 deletions lib/src/compiler/ir/tests/testdata/2.cse.ir
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
RULE test
42: FOR_IN -- hash: 0xd239eca0f1b10a3c -- parent: None
42: FOR_IN -- hash: 0x816e524676c15c3e -- parent: None
0: CONST integer(0) -- parent: 42
1: PATTERN_COUNT PatternIdx(0) -- hash: 0x2706f00cf1a9933a -- parent: 42
41: FOR_IN -- hash: 0xb61580e3f67c738d -- parent: 42
41: FOR_IN -- hash: 0x8a81c74ec1874673 -- parent: 42
2: CONST integer(0) -- parent: 41
3: PATTERN_COUNT PatternIdx(1) -- hash: 0xd9da66a80b3ad5b5 -- parent: 41
40: FOR_IN -- hash: 0xe936e2e916e9c798 -- parent: 41
40: FOR_IN -- hash: 0x5b8db8b10d7df78d -- parent: 41
6: FIELD_ACCESS -- hash: 0x648af520f5c87b4e -- parent: 40
4: SYMBOL Field { index: 0, is_root: true, type_value: struct, acl: None } -- parent: 6
5: SYMBOL Field { index: 19, is_root: false, type_value: array, acl: None } -- parent: 6
44: WITH -- hash: 0xebee4418f83e81ba -- parent: 40
44: WITH -- hash: 0xb93c55bc71470525 -- parent: 40
43: FIELD_ACCESS -- hash: 0x4a8febd1cb391875 -- parent: 44
7: SYMBOL Var { var: Var { frame_id: 3, ty: struct, index: 19 }, type_value: struct } -- parent: 43
8: SYMBOL Field { index: 0, is_root: false, type_value: integer(unknown), acl: None } -- parent: 43
46: WITH -- hash: 0xd2d91858c2b75a1b -- parent: 44
46: WITH -- hash: 0x4c785fe4fc95043 -- parent: 44
45: PATTERN_OFFSET PatternIdx(0) INDEX -- hash: 0x6df2db889a437dfc -- parent: 46
10: SYMBOL Var { var: Var { frame_id: 1, ty: integer, index: 5 }, type_value: integer(unknown) } -- parent: 45
48: WITH -- hash: 0xc2662b0706e491f9 -- parent: 46
47: ADD -- hash: 0x8a11aeefa8c5107e -- parent: 48
17: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 21 }, type_value: integer(unknown) } -- parent: 47
20: FIELD_ACCESS -- hash: 0xfd63626ce4ca5af0 -- parent: 47
18: SYMBOL Var { var: Var { frame_id: 3, ty: struct, index: 19 }, type_value: struct } -- parent: 20
19: SYMBOL Field { index: 1, is_root: false, type_value: integer(unknown), acl: None } -- parent: 20
50: WITH -- hash: 0x939456be50d6b11c -- parent: 48
49: PATTERN_OFFSET PatternIdx(1) INDEX -- hash: 0x929bd8da1310dcd6 -- parent: 50
26: SYMBOL Var { var: Var { frame_id: 2, ty: integer, index: 12 }, type_value: integer(unknown) } -- parent: 49
39: AND -- hash: 0x22fad221617d63ce -- parent: 50
12: LE -- hash: 0xc6e65a0d3c202e21 -- parent: 39
9: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 21 }, type_value: integer(unknown) } -- parent: 12
11: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 22 }, type_value: integer(unknown) } -- parent: 12
22: LE -- hash: 0xdcddb87106cfdc -- parent: 39
14: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 22 }, type_value: integer(unknown) } -- parent: 22
21: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 23 }, type_value: integer(unknown) } -- parent: 22
28: LE -- hash: 0x242c266274ce54d1 -- parent: 39
25: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 21 }, type_value: integer(unknown) } -- parent: 28
27: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 24 }, type_value: integer(unknown) } -- parent: 28
38: LE -- hash: 0x178418b9a225eca1 -- parent: 39
30: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 24 }, type_value: integer(unknown) } -- parent: 38
37: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 23 }, type_value: integer(unknown) } -- parent: 38
48: WITH -- hash: 0x7316de267d7cbea2 -- parent: 46
47: FIELD_ACCESS -- hash: 0xfd63626ce4ca5af0 -- parent: 48
18: SYMBOL Var { var: Var { frame_id: 3, ty: struct, index: 19 }, type_value: struct } -- parent: 47
19: SYMBOL Field { index: 1, is_root: false, type_value: integer(unknown), acl: None } -- parent: 47
50: WITH -- hash: 0x19b6eb37dce09b2d -- parent: 48
49: ADD -- hash: 0xdcca1966bd48e7f3 -- parent: 50
17: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 21 }, type_value: integer(unknown) } -- parent: 49
20: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 23 }, type_value: integer(unknown) } -- parent: 49
52: WITH -- hash: 0x87db38b1bd973dd0 -- parent: 50
51: PATTERN_OFFSET PatternIdx(1) INDEX -- hash: 0x929bd8da1310dcd6 -- parent: 52
26: SYMBOL Var { var: Var { frame_id: 2, ty: integer, index: 12 }, type_value: integer(unknown) } -- parent: 51
39: AND -- hash: 0x1741b414ce3df082 -- parent: 52
12: LE -- hash: 0xc6e65a0d3c202e21 -- parent: 39
9: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 21 }, type_value: integer(unknown) } -- parent: 12
11: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 22 }, type_value: integer(unknown) } -- parent: 12
22: LE -- hash: 0xaf7fc3e30d55e333 -- parent: 39
14: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 22 }, type_value: integer(unknown) } -- parent: 22
21: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 24 }, type_value: integer(unknown) } -- parent: 22
28: LE -- hash: 0xd2cf0c8d111d6828 -- parent: 39
25: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 21 }, type_value: integer(unknown) } -- parent: 28
27: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 25 }, type_value: integer(unknown) } -- parent: 28
38: LE -- hash: 0x517a9c64d70c8e5b -- parent: 39
30: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 25 }, type_value: integer(unknown) } -- parent: 38
37: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 24 }, type_value: integer(unknown) } -- parent: 38

64 changes: 34 additions & 30 deletions lib/src/compiler/ir/tests/testdata/4.cse.ir
Original file line number Diff line number Diff line change
@@ -1,38 +1,42 @@
RULE test
60: WITH -- hash: 0x514f37693369409e -- parent: None
60: WITH -- hash: 0xc163e7b3b317e56 -- parent: None
2: FIELD_ACCESS -- hash: 0x80c2b6e342dfa9ec -- parent: 60
0: SYMBOL Field { index: 0, is_root: true, type_value: struct, acl: None } -- parent: 2
1: SYMBOL Field { index: 12, is_root: false, type_value: integer(unknown), acl: None } -- parent: 2
62: WITH -- hash: 0x1f944fa48c01200a -- parent: 60
62: WITH -- hash: 0x9e76c9dd25d6a5c6 -- parent: 60
61: FN_CALL test_proto2.add@ii@i -- hash: 0xf798bcca1a3f3e3a -- parent: 62
16: CONST integer(1) -- parent: 61
17: CONST integer(2) -- parent: 61
64: WITH -- hash: 0xed9c7997a50e13ef -- parent: 62
63: EQ -- hash: 0x1dbb26e61da1eb70 -- parent: 64
31: ADD -- hash: 0xd171978cdc3d3d19 -- parent: 63
29: FIELD_ACCESS -- hash: 0x1b1bc9ad0fbd24f5 -- parent: 31
27: SYMBOL Field { index: 0, is_root: true, type_value: struct, acl: None } -- parent: 29
28: SYMBOL Field { index: 10, is_root: false, type_value: float(unknown), acl: None } -- parent: 29
30: CONST integer(1) -- parent: 31
32: CONST float(1.0) -- parent: 63
59: AND -- hash: 0x73647de6955d36af -- parent: 64
35: FOR_IN -- hash: 0xeda81b1cf9169c65 -- parent: 59
3: CONST integer(0) -- parent: 35
4: CONST integer(1) -- parent: 35
34: AND -- hash: 0x524595547ad679c1 -- parent: 35
9: EQ -- hash: 0xf948d5883ead1836 -- parent: 34
7: SYMBOL Var { var: Var { frame_id: 2, ty: integer, index: 8 }, type_value: integer(unknown) } -- parent: 9
8: SYMBOL Var { var: Var { frame_id: 1, ty: integer, index: 0 }, type_value: integer(unknown) } -- parent: 9
20: EQ -- hash: 0xa385188c35b1764c -- parent: 34
18: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 1 }, type_value: integer(unknown) } -- parent: 20
19: CONST integer(3) -- parent: 20
33: SYMBOL Var { var: Var { frame_id: 0, ty: boolean, index: 2 }, type_value: boolean(unknown) } -- parent: 34
58: FOR_IN -- hash: 0x9df2b30eb5d2040a -- parent: 59
36: CONST integer(0) -- parent: 58
37: CONST integer(1) -- parent: 58
57: AND -- hash: 0xbc4f81c1298c642 -- parent: 58
43: NE -- hash: 0x3dc3ef6d085f02d6 -- parent: 57
41: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 1 }, type_value: integer(unknown) } -- parent: 43
42: CONST integer(0) -- parent: 43
56: SYMBOL Var { var: Var { frame_id: 0, ty: boolean, index: 2 }, type_value: boolean(unknown) } -- parent: 57
64: WITH -- hash: 0xc90ab1bb0ed9a5b5 -- parent: 62
63: FIELD_ACCESS -- hash: 0x1b1bc9ad0fbd24f5 -- parent: 64
27: SYMBOL Field { index: 0, is_root: true, type_value: struct, acl: None } -- parent: 63
28: SYMBOL Field { index: 10, is_root: false, type_value: float(unknown), acl: None } -- parent: 63
66: WITH -- hash: 0x26be386f1115ad5f -- parent: 64
65: ADD -- hash: 0xd90aef571c7f8da -- parent: 66
29: SYMBOL Var { var: Var { frame_id: 0, ty: float, index: 2 }, type_value: float(unknown) } -- parent: 65
30: CONST integer(1) -- parent: 65
68: WITH -- hash: 0xf9fd74c40fc05ea4 -- parent: 66
67: EQ -- hash: 0x5befaeb1d3c2c110 -- parent: 68
31: SYMBOL Var { var: Var { frame_id: 0, ty: float, index: 3 }, type_value: float(unknown) } -- parent: 67
32: CONST float(1.0) -- parent: 67
59: AND -- hash: 0xcd986a8a9833e6b1 -- parent: 68
35: FOR_IN -- hash: 0xfcbaf6a6285ea318 -- parent: 59
3: CONST integer(0) -- parent: 35
4: CONST integer(1) -- parent: 35
34: AND -- hash: 0x615870ddaa1e8074 -- parent: 35
9: EQ -- hash: 0xff010896fcc34fc -- parent: 34
7: SYMBOL Var { var: Var { frame_id: 2, ty: integer, index: 10 }, type_value: integer(unknown) } -- parent: 9
8: SYMBOL Var { var: Var { frame_id: 1, ty: integer, index: 0 }, type_value: integer(unknown) } -- parent: 9
20: EQ -- hash: 0xa385188c35b1764c -- parent: 34
18: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 1 }, type_value: integer(unknown) } -- parent: 20
19: CONST integer(3) -- parent: 20
33: SYMBOL Var { var: Var { frame_id: 0, ty: boolean, index: 4 }, type_value: boolean(unknown) } -- parent: 34
58: FOR_IN -- hash: 0xfb387f63ee702ab9 -- parent: 59
36: CONST integer(0) -- parent: 58
37: CONST integer(1) -- parent: 58
57: AND -- hash: 0x690ac4714b36ecf1 -- parent: 58
43: NE -- hash: 0x3dc3ef6d085f02d6 -- parent: 57
41: SYMBOL Var { var: Var { frame_id: 0, ty: integer, index: 1 }, type_value: integer(unknown) } -- parent: 43
42: CONST integer(0) -- parent: 43
56: SYMBOL Var { var: Var { frame_id: 0, ty: boolean, index: 4 }, type_value: boolean(unknown) } -- parent: 57

Loading

0 comments on commit 03f3ae9

Please sign in to comment.