Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve module #85

Merged
merged 32 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
37b1ff1
Add `new_unchecked` methods to inst types
Y-Nak Nov 16, 2024
2f0272b
Improve builder usability
Y-Nak Nov 16, 2024
768955f
Add missing `EvmCallDataSize`
Y-Nak Nov 16, 2024
5cd52e8
Add missing `EvmMcopy`
Y-Nak Nov 16, 2024
d9f3399
Add missing `EvmCallCode`
Y-Nak Nov 16, 2024
5f1b96d
Add `EvmInvalid` inst
Y-Nak Nov 17, 2024
f1b8c8e
Remove unnecessary `ret_ty` field from `Call` inst
Y-Nak Nov 17, 2024
7969ae1
Add some utility methods in `FuncBuilder`
Y-Nak Nov 17, 2024
93cb58d
Add `Undef` value
Y-Nak Nov 19, 2024
be31bc1
Add `InsertValue/ExtractValue` inst
Y-Nak Nov 19, 2024
31bfe4e
Make interpreter handle aggregate types
Y-Nak Nov 19, 2024
5a98441
Parse `undef` value
Y-Nak Nov 19, 2024
b19d2bb
Impl `Interpret` for `InsertValue/ExtractValue`
Y-Nak Nov 19, 2024
064fc8b
Use `DashMap` to store functions
Y-Nak Nov 20, 2024
5e27011
Fix lifetime unsound problem in downcast implementations
Y-Nak Nov 21, 2024
894da7e
Update `ModuleBuilder`: all methods now take immutable `self`
Y-Nak Nov 21, 2024
c57a9ad
Rename `build_function` to `func_builder`
Y-Nak Nov 21, 2024
571c677
Update EVM versions
Y-Nak Nov 21, 2024
3ab2fd5
Fix bug in SSA builder: reflect alias value properly
Y-Nak Nov 22, 2024
960b1f2
Improve IR formatting
Y-Nak Nov 22, 2024
f7b4ac5
Fix bug in mod interpretation
Y-Nak Nov 22, 2024
ff95f31
Add function type
Y-Nak Nov 24, 2024
0ea6b15
Add `GetFunctionPtr` instruction
Y-Nak Nov 24, 2024
07977b2
Add `EvmContractSize` instruction
Y-Nak Nov 24, 2024
91f8fd3
Add parser for global variable
Y-Nak Nov 25, 2024
2644475
Configure insta to remove expression metadata from snapshot result
Y-Nak Nov 26, 2024
fae1c10
Parse global value
Y-Nak Nov 26, 2024
80af8b0
Remove outdated parser stmt tests
Y-Nak Nov 26, 2024
43461dd
Add duplicated declaration check in parser
Y-Nak Nov 26, 2024
7f349e4
Add test for simple type check in global initializer
Y-Nak Nov 26, 2024
69c8f76
Add `GlobalVariable::ty` and `Type::to_ptr` methods
Y-Nak Nov 26, 2024
8845911
Register new instructions to `EvmInstSet`
Y-Nak Nov 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 44 additions & 37 deletions crates/codegen/src/critical_edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ mod tests {

#[test]
fn critical_edge_basic() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let a = builder.append_block();
Expand All @@ -159,12 +160,15 @@ mod tests {
builder.insert_inst_no_result(ret);

builder.seal_all();
let mut module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &mut module.funcs[func_ref];
builder.finish();

let module = mb.build();
let func_ref = module.funcs()[0];
let mut cfg = ControlFlowGraph::default();
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
module.funcs.modify(func_ref, |func| {
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
});

assert_eq!(
dump_func(&module, func_ref),
Expand All @@ -180,21 +184,20 @@ mod tests {

block3:
jump block2;

}
"
);

let func = &mut module.funcs[func_ref];
let mut cfg_split = ControlFlowGraph::default();
cfg_split.compute(func);
module.funcs.view(func_ref, |func| cfg_split.compute(func));
assert_eq!(cfg, cfg_split);
}

#[test]
#[allow(clippy::many_single_char_names)]
fn critical_edge_to_same_block() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let a = builder.append_block();
Expand Down Expand Up @@ -225,12 +228,15 @@ mod tests {
builder.insert_inst_no_result(ret);

builder.seal_all();
let mut module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &mut module.funcs[func_ref];
builder.finish();

let module = mb.build();
let func_ref = module.funcs()[0];
let mut cfg = ControlFlowGraph::default();
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
module.funcs.modify(func_ref, |func| {
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
});

assert_eq!(
dump_func(&module, func_ref),
Expand All @@ -255,20 +261,19 @@ mod tests {

block6:
jump block3;

}
"
);

let func = &mut module.funcs[func_ref];
let mut cfg_split = ControlFlowGraph::default();
cfg_split.compute(func);
module.funcs.view(func_ref, |func| cfg_split.compute(func));
assert_eq!(cfg, cfg_split);
}

#[test]
fn critical_edge_phi() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let a = builder.append_block();
Expand All @@ -290,13 +295,15 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
let mut module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &mut module.funcs[func_ref];
let mut cfg = ControlFlowGraph::default();
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
builder.finish();

let module = mb.build();
let func_ref = module.funcs()[0];
let mut cfg = ControlFlowGraph::default();
module.funcs.modify(func_ref, |func| {
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
});
assert_eq!(
dump_func(&module, func_ref),
"func public %test_func() -> unit {
Expand All @@ -313,20 +320,19 @@ mod tests {

block3:
jump block1;

}
"
);

let func = &mut module.funcs[func_ref];
let mut cfg_split = ControlFlowGraph::default();
cfg_split.compute(func);
module.funcs.view(func_ref, |func| cfg_split.compute(func));
assert_eq!(cfg, cfg_split);
}

#[test]
fn critical_edge_br_table() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let a = builder.append_block();
Expand Down Expand Up @@ -356,12 +362,15 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
let mut module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &mut module.funcs[func_ref];
builder.finish();

let module = mb.build();
let func_ref = module.funcs()[0];
let mut cfg = ControlFlowGraph::default();
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
module.funcs.modify(func_ref, |func| {
cfg.compute(func);
CriticalEdgeSplitter::new().run(func, &mut cfg);
});

assert_eq!(
dump_func(&module, func_ref),
Expand Down Expand Up @@ -389,14 +398,12 @@ mod tests {

block7:
jump block4;

}
"
);

let func = &mut module.funcs[func_ref];
let mut cfg_split = ControlFlowGraph::default();
cfg_split.compute(func);
module.funcs.view(func_ref, |func| cfg_split.compute(func));
assert_eq!(cfg, cfg_split);
}
}
44 changes: 24 additions & 20 deletions crates/codegen/src/domtree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ mod tests {

#[test]
fn dom_tree_if_else() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let entry_block = builder.append_block();
Expand All @@ -257,12 +258,12 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let module = mb.build();
let func_ref = module.funcs()[0];
let (dom_tree, df) = module.funcs.view(func_ref, calc_dom);

let (dom_tree, df) = calc_dom(func);
assert_eq!(dom_tree.idom_of(entry_block), None);
assert_eq!(dom_tree.idom_of(then_block), Some(entry_block));
assert_eq!(dom_tree.idom_of(else_block), Some(entry_block));
Expand All @@ -276,7 +277,8 @@ mod tests {

#[test]
fn unreachable_edge() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let a = builder.append_block();
Expand All @@ -302,12 +304,12 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let module = mb.build();
let func_ref = module.funcs()[0];
let (dom_tree, df) = module.funcs.view(func_ref, calc_dom);

let (dom_tree, df) = calc_dom(func);
assert_eq!(dom_tree.idom_of(a), None);
assert_eq!(dom_tree.idom_of(b), Some(a));
assert_eq!(dom_tree.idom_of(c), Some(a));
Expand All @@ -324,7 +326,8 @@ mod tests {

#[test]
fn dom_tree_complex() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let a = builder.append_block();
Expand Down Expand Up @@ -382,12 +385,12 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let module = mb.build();
let func_ref = module.funcs()[0];
let (dom_tree, df) = module.funcs.view(func_ref, calc_dom);

let (dom_tree, df) = calc_dom(func);
assert_eq!(dom_tree.idom_of(a), None);
assert_eq!(dom_tree.idom_of(b), Some(a));
assert_eq!(dom_tree.idom_of(c), Some(a));
Expand Down Expand Up @@ -417,7 +420,8 @@ mod tests {

#[test]
fn dom_tree_br_table() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let a = builder.append_block();
Expand Down Expand Up @@ -451,12 +455,12 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let module = mb.build();
let func_ref = module.funcs()[0];
let (dom_tree, df) = module.funcs.view(func_ref, calc_dom);

let (dom_tree, df) = calc_dom(func);
assert_eq!(dom_tree.idom_of(a), None);
assert_eq!(dom_tree.idom_of(b), Some(a));
assert_eq!(dom_tree.idom_of(c), Some(a));
Expand Down
44 changes: 24 additions & 20 deletions crates/codegen/src/loop_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ mod tests {

#[test]
fn simple_loop() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let b0 = builder.append_block();
Expand Down Expand Up @@ -301,11 +302,11 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let lpt = compute_loop(func);
let module = mb.build();
let func_ref = module.funcs()[0];
let lpt = &module.funcs.view(func_ref, compute_loop);

debug_assert_eq!(lpt.loop_num(), 1);
let lp0 = lpt.loops().next().unwrap();
Expand All @@ -319,7 +320,8 @@ mod tests {

#[test]
fn continue_loop() {
let (evm, mut builder) = test_func_builder(&[], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[], Type::Unit);
let is = evm.inst_set();

let b0 = builder.append_block();
Expand Down Expand Up @@ -365,11 +367,11 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let lpt = compute_loop(func);
let module = mb.build();
let func_ref = module.funcs()[0];
let lpt = &module.funcs.view(func_ref, compute_loop);

debug_assert_eq!(lpt.loop_num(), 1);
let lp0 = lpt.loops().next().unwrap();
Expand All @@ -387,7 +389,8 @@ mod tests {

#[test]
fn single_block_loop() {
let (evm, mut builder) = test_func_builder(&[Type::I1], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[Type::I1], Type::Unit);
let is = evm.inst_set();

let b0 = builder.append_block();
Expand All @@ -406,11 +409,11 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let lpt = compute_loop(func);
let module = mb.build();
let func_ref = module.funcs()[0];
let lpt = &module.funcs.view(func_ref, compute_loop);

debug_assert_eq!(lpt.loop_num(), 1);
let lp0 = lpt.loops().next().unwrap();
Expand All @@ -422,7 +425,8 @@ mod tests {

#[test]
fn nested_loop() {
let (evm, mut builder) = test_func_builder(&[Type::I1], Type::Unit);
let mb = test_module_builder();
let (evm, mut builder) = test_func_builder(&mb, &[Type::I1], Type::Unit);
let is = evm.inst_set();

let b0 = builder.append_block();
Expand Down Expand Up @@ -477,11 +481,11 @@ mod tests {
builder.insert_inst_no_result_with(|| Return::new(is, None));

builder.seal_all();
builder.finish();

let module = builder.finish().build();
let func_ref = module.iter_functions().next().unwrap();
let func = &module.funcs[func_ref];
let lpt = compute_loop(func);
let module = mb.build();
let func_ref = module.funcs()[0];
let lpt = &module.funcs.view(func_ref, compute_loop);

debug_assert_eq!(lpt.loop_num(), 4);
let l0 = lpt.loop_of_block(b1).unwrap();
Expand Down
Loading