WIP.
This commit is contained in:
parent
539af66b88
commit
3bde79a15d
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,3 +2,5 @@
|
||||||
*~
|
*~
|
||||||
.*.swp
|
.*.swp
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
/*.wasm
|
||||||
|
wasm_tests/*.wasm
|
||||||
|
|
|
@ -25,7 +25,7 @@ impl<'a> WasmBackend<'a> {
|
||||||
log::trace!("RPO:\n{:?}\n", rpo);
|
log::trace!("RPO:\n{:?}\n", rpo);
|
||||||
let trees = Trees::compute(body);
|
let trees = Trees::compute(body);
|
||||||
log::trace!("Trees:\n{:?}\n", trees);
|
log::trace!("Trees:\n{:?}\n", trees);
|
||||||
let ctrl = StackifyContext::new(body, &cfg, &rpo).compute();
|
let ctrl = StackifyContext::new(body, &cfg, &rpo)?.compute();
|
||||||
log::trace!("Ctrl:\n{:?}\n", ctrl);
|
log::trace!("Ctrl:\n{:?}\n", ctrl);
|
||||||
Ok(WasmBackend {
|
Ok(WasmBackend {
|
||||||
body,
|
body,
|
||||||
|
|
|
@ -96,17 +96,17 @@ impl CtrlEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Context<'a, 'b> {
|
impl<'a, 'b> Context<'a, 'b> {
|
||||||
pub fn new(body: &'a FunctionBody, cfg: &'b CFGInfo, rpo: &'b RPO) -> Self {
|
pub fn new(body: &'a FunctionBody, cfg: &'b CFGInfo, rpo: &'b RPO) -> anyhow::Result<Self> {
|
||||||
let (merge_nodes, loop_headers) =
|
let (merge_nodes, loop_headers) =
|
||||||
Self::compute_merge_nodes_and_loop_headers(body, cfg, rpo);
|
Self::compute_merge_nodes_and_loop_headers(body, cfg, rpo)?;
|
||||||
Self {
|
Ok(Self {
|
||||||
body,
|
body,
|
||||||
cfg,
|
cfg,
|
||||||
rpo,
|
rpo,
|
||||||
merge_nodes,
|
merge_nodes,
|
||||||
loop_headers,
|
loop_headers,
|
||||||
ctrl_stack: vec![],
|
ctrl_stack: vec![],
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute(mut self) -> Vec<WasmBlock<'a>> {
|
pub fn compute(mut self) -> Vec<WasmBlock<'a>> {
|
||||||
|
@ -119,7 +119,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
body: &FunctionBody,
|
body: &FunctionBody,
|
||||||
cfg: &CFGInfo,
|
cfg: &CFGInfo,
|
||||||
rpo: &RPO,
|
rpo: &RPO,
|
||||||
) -> (HashSet<Block>, HashSet<Block>) {
|
) -> anyhow::Result<(HashSet<Block>, HashSet<Block>)> {
|
||||||
let mut loop_headers = HashSet::new();
|
let mut loop_headers = HashSet::new();
|
||||||
let mut branched_once = HashSet::new();
|
let mut branched_once = HashSet::new();
|
||||||
let mut merge_nodes = HashSet::new();
|
let mut merge_nodes = HashSet::new();
|
||||||
|
@ -128,6 +128,9 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
for &succ in cfg.succs(block) {
|
for &succ in cfg.succs(block) {
|
||||||
let succ_rpo = rpo.rev[succ].unwrap();
|
let succ_rpo = rpo.rev[succ].unwrap();
|
||||||
if succ_rpo <= block_rpo {
|
if succ_rpo <= block_rpo {
|
||||||
|
if !cfg.dominates(succ, block) {
|
||||||
|
anyhow::bail!("Irreducible control flow: edge from {} to {}", block, succ);
|
||||||
|
}
|
||||||
// Backward branch.
|
// Backward branch.
|
||||||
loop_headers.insert(succ);
|
loop_headers.insert(succ);
|
||||||
} else {
|
} else {
|
||||||
|
@ -155,7 +158,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(merge_nodes, loop_headers)
|
Ok((merge_nodes, loop_headers))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_dom_subtree(&mut self, block: Block, into: &mut Vec<WasmBlock<'a>>) {
|
fn handle_dom_subtree(&mut self, block: Block, into: &mut Vec<WasmBlock<'a>>) {
|
||||||
|
|
6
wasm_tests/test.wat
Normal file
6
wasm_tests/test.wat
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
(module
|
||||||
|
(func (result i32)
|
||||||
|
i32.const 2
|
||||||
|
i32.const 2
|
||||||
|
i32.add
|
||||||
|
))
|
12
wasm_tests/test2.wat
Normal file
12
wasm_tests/test2.wat
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
(module
|
||||||
|
(func (param i32) (result i32)
|
||||||
|
local.get 0
|
||||||
|
if (result i32)
|
||||||
|
i32.const 1
|
||||||
|
local.get 0
|
||||||
|
i32.add
|
||||||
|
else
|
||||||
|
i32.const 2
|
||||||
|
local.get 0
|
||||||
|
i32.add
|
||||||
|
end))
|
13
wasm_tests/test3.wat
Normal file
13
wasm_tests/test3.wat
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
(module
|
||||||
|
(func (param i32) (result i32)
|
||||||
|
(local $i i32)
|
||||||
|
(local.set $i (local.get 0))
|
||||||
|
|
||||||
|
(local.get $i)
|
||||||
|
(block $loop-break (param i32) (result i32)
|
||||||
|
(loop $l (param i32) (result i32)
|
||||||
|
(if (i32.eq (local.get $i) (i32.const 100))
|
||||||
|
(br $loop-break
|
||||||
|
(local.get $i)))
|
||||||
|
(local.set $i (i32.add (i32.const 10) (local.get $i)))
|
||||||
|
(br $l (local.get $i))))))
|
Loading…
Reference in a new issue