WIP.
This commit is contained in:
parent
726b4da33d
commit
f92ea9a556
|
@ -1,11 +1,10 @@
|
||||||
//! Final Wasm operator sequence production.
|
//! Final Wasm operator sequence production.
|
||||||
|
|
||||||
|
use super::{Locations, SerializedBlockTarget, SerializedBody, SerializedOperator};
|
||||||
|
use crate::{ops::ty_to_valty, FunctionBody};
|
||||||
|
use std::borrow::Cow;
|
||||||
use wasm_encoder::BlockType;
|
use wasm_encoder::BlockType;
|
||||||
|
|
||||||
use crate::{ops::ty_to_valty, FunctionBody, Operator};
|
|
||||||
|
|
||||||
use super::{Locations, SerializedBody, SerializedOperator};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Wasm {
|
pub struct Wasm {
|
||||||
operators: Vec<wasm_encoder::Instruction<'static>>,
|
operators: Vec<wasm_encoder::Instruction<'static>>,
|
||||||
|
@ -62,36 +61,96 @@ impl Wasm {
|
||||||
self.operators.push(op.clone().into());
|
self.operators.push(op.clone().into());
|
||||||
}
|
}
|
||||||
SerializedOperator::Br(ref target) => {
|
SerializedOperator::Br(ref target) => {
|
||||||
todo!()
|
self.translate_target(0, target, locations);
|
||||||
}
|
}
|
||||||
SerializedOperator::BrIf {
|
SerializedOperator::BrIf {
|
||||||
cond,
|
cond,
|
||||||
ref if_true,
|
ref if_true,
|
||||||
ref if_false,
|
ref if_false,
|
||||||
} => {
|
} => {
|
||||||
todo!()
|
let loc = *locations.locations.get(&(*cond, 0)).unwrap();
|
||||||
|
self.operators
|
||||||
|
.push(wasm_encoder::Instruction::LocalGet(loc));
|
||||||
|
self.operators.push(wasm_encoder::Instruction::If(
|
||||||
|
wasm_encoder::BlockType::Empty,
|
||||||
|
));
|
||||||
|
self.translate_target(1, if_true, locations);
|
||||||
|
self.operators.push(wasm_encoder::Instruction::Else);
|
||||||
|
self.translate_target(1, if_false, locations);
|
||||||
|
self.operators.push(wasm_encoder::Instruction::End);
|
||||||
}
|
}
|
||||||
SerializedOperator::BrTable {
|
SerializedOperator::BrTable {
|
||||||
index,
|
index,
|
||||||
ref targets,
|
ref targets,
|
||||||
ref default,
|
ref default,
|
||||||
} => {
|
} => {
|
||||||
todo!()
|
for _ in 0..(targets.len() + 2) {
|
||||||
|
self.operators.push(wasm_encoder::Instruction::Block(
|
||||||
|
wasm_encoder::BlockType::Empty,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let loc = *locations.locations.get(&(*index, 0)).unwrap();
|
||||||
|
self.operators
|
||||||
|
.push(wasm_encoder::Instruction::LocalGet(loc));
|
||||||
|
let br_table_targets = (1..=targets.len()).map(|i| i as u32).collect::<Vec<_>>();
|
||||||
|
self.operators.push(wasm_encoder::Instruction::BrTable(
|
||||||
|
Cow::Owned(br_table_targets),
|
||||||
|
0,
|
||||||
|
));
|
||||||
|
self.operators.push(wasm_encoder::Instruction::End);
|
||||||
|
|
||||||
|
self.translate_target(targets.len() + 1, default, locations);
|
||||||
|
self.operators.push(wasm_encoder::Instruction::End);
|
||||||
|
|
||||||
|
for i in 0..targets.len() {
|
||||||
|
self.translate_target(targets.len() - i, &targets[i], locations);
|
||||||
|
self.operators.push(wasm_encoder::Instruction::End);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SerializedOperator::Get(v, i) => {
|
SerializedOperator::Get(v, i) => {
|
||||||
todo!()
|
let loc = *locations.locations.get(&(*v, *i)).unwrap();
|
||||||
|
self.operators
|
||||||
|
.push(wasm_encoder::Instruction::LocalGet(loc));
|
||||||
}
|
}
|
||||||
SerializedOperator::Set(v, i) => {
|
SerializedOperator::Set(v, i) => {
|
||||||
todo!()
|
let loc = *locations.locations.get(&(*v, *i)).unwrap();
|
||||||
|
self.operators
|
||||||
|
.push(wasm_encoder::Instruction::LocalSet(loc));
|
||||||
}
|
}
|
||||||
SerializedOperator::Tee(v, i) => {
|
SerializedOperator::Tee(v, i) => {
|
||||||
todo!()
|
let loc = *locations.locations.get(&(*v, *i)).unwrap();
|
||||||
|
self.operators
|
||||||
|
.push(wasm_encoder::Instruction::LocalTee(loc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn translate_target(
|
||||||
|
&mut self,
|
||||||
|
extra_blocks: usize,
|
||||||
|
target: &SerializedBlockTarget,
|
||||||
|
locations: &Locations,
|
||||||
|
) {
|
||||||
|
match target {
|
||||||
|
&SerializedBlockTarget::Fallthrough(ref ops) => {
|
||||||
|
for op in ops {
|
||||||
|
self.translate(op, locations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&SerializedBlockTarget::Branch(branch, ref ops) => {
|
||||||
|
for op in ops {
|
||||||
|
self.translate(op, locations);
|
||||||
|
}
|
||||||
|
self.operators.push(wasm_encoder::Instruction::Br(
|
||||||
|
(branch + extra_blocks) as u32,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn produce_wasm(f: &FunctionBody, body: &SerializedBody, locations: &Locations) -> Wasm {
|
pub fn produce_func_wasm(f: &FunctionBody, body: &SerializedBody, locations: &Locations) -> Wasm {
|
||||||
let mut wasm = Wasm {
|
let mut wasm = Wasm {
|
||||||
operators: vec![],
|
operators: vec![],
|
||||||
locals: vec![],
|
locals: vec![],
|
||||||
|
|
|
@ -65,10 +65,10 @@ impl<'a> Allocator<'a> {
|
||||||
let mut reads = vec![];
|
let mut reads = vec![];
|
||||||
let mut writes = vec![];
|
let mut writes = vec![];
|
||||||
op.visit_value_locals(
|
op.visit_value_locals(
|
||||||
|value, index| {
|
&mut |value, index| {
|
||||||
reads.push((value, index));
|
reads.push((value, index));
|
||||||
},
|
},
|
||||||
|value, index| {
|
&mut |value, index| {
|
||||||
writes.push((value, index));
|
writes.push((value, index));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -77,7 +77,7 @@ impl<'a> Allocator<'a> {
|
||||||
let span = match self.spans.get_mut(&(value, index)) {
|
let span = match self.spans.get_mut(&(value, index)) {
|
||||||
Some(span) => span,
|
Some(span) => span,
|
||||||
None => {
|
None => {
|
||||||
panic!("Read before any write to local (v{},{})", value, index);
|
panic!("Read before any write to local ({},{})", value, index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
span.end = location + 1;
|
span.end = location + 1;
|
||||||
|
|
|
@ -72,12 +72,12 @@ pub enum SerializedOperator {
|
||||||
impl SerializedOperator {
|
impl SerializedOperator {
|
||||||
pub fn visit_value_locals<R: FnMut(Value, usize), W: FnMut(Value, usize)>(
|
pub fn visit_value_locals<R: FnMut(Value, usize), W: FnMut(Value, usize)>(
|
||||||
&self,
|
&self,
|
||||||
mut r: R,
|
r: &mut R,
|
||||||
mut w: W,
|
w: &mut W,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
&SerializedOperator::Br(ref target) => {
|
&SerializedOperator::Br(ref target) => {
|
||||||
target.visit_value_locals(&mut r, &mut w);
|
target.visit_value_locals(r, w);
|
||||||
}
|
}
|
||||||
&SerializedOperator::BrIf {
|
&SerializedOperator::BrIf {
|
||||||
cond,
|
cond,
|
||||||
|
@ -85,8 +85,8 @@ impl SerializedOperator {
|
||||||
ref if_false,
|
ref if_false,
|
||||||
} => {
|
} => {
|
||||||
r(cond, 0);
|
r(cond, 0);
|
||||||
if_true.visit_value_locals(&mut r, &mut w);
|
if_true.visit_value_locals(r, w);
|
||||||
if_false.visit_value_locals(&mut r, &mut w);
|
if_false.visit_value_locals(r, w);
|
||||||
}
|
}
|
||||||
&SerializedOperator::BrTable {
|
&SerializedOperator::BrTable {
|
||||||
index,
|
index,
|
||||||
|
@ -94,9 +94,9 @@ impl SerializedOperator {
|
||||||
ref targets,
|
ref targets,
|
||||||
} => {
|
} => {
|
||||||
r(index, 0);
|
r(index, 0);
|
||||||
default.visit_value_locals(&mut r, &mut w);
|
default.visit_value_locals(r, w);
|
||||||
for target in targets {
|
for target in targets {
|
||||||
target.visit_value_locals(&mut r, &mut w);
|
target.visit_value_locals(r, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&SerializedOperator::Get(v, i) => {
|
&SerializedOperator::Get(v, i) => {
|
||||||
|
@ -128,7 +128,7 @@ impl SerializedBlockTarget {
|
||||||
&SerializedBlockTarget::Branch(_, ref ops)
|
&SerializedBlockTarget::Branch(_, ref ops)
|
||||||
| &SerializedBlockTarget::Fallthrough(ref ops) => {
|
| &SerializedBlockTarget::Fallthrough(ref ops) => {
|
||||||
for op in ops {
|
for op in ops {
|
||||||
op.visit_value_locals(|value, i| r(value, i), |value, i| w(value, i));
|
op.visit_value_locals(r, w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{BlockOrder, LoopNest, SerializedBody, WasmRegion},
|
backend::{produce_func_wasm, BlockOrder, Locations, LoopNest, SerializedBody, WasmRegion},
|
||||||
cfg::CFGInfo,
|
cfg::CFGInfo,
|
||||||
frontend, Operator,
|
frontend, Operator,
|
||||||
};
|
};
|
||||||
|
@ -492,7 +492,11 @@ impl<'a> Module<'a> {
|
||||||
let regions = WasmRegion::compute(&cfg, &loopnest);
|
let regions = WasmRegion::compute(&cfg, &loopnest);
|
||||||
let blockorder = BlockOrder::compute(body, &cfg, ®ions);
|
let blockorder = BlockOrder::compute(body, &cfg, ®ions);
|
||||||
let serialized = SerializedBody::compute(body, &cfg, &blockorder);
|
let serialized = SerializedBody::compute(body, &cfg, &blockorder);
|
||||||
log::trace!("serialized:{:?}", serialized);
|
log::trace!("serialized: {:?}", serialized);
|
||||||
|
let locations = Locations::compute(body, &serialized);
|
||||||
|
log::trace!("locations: {:?}", locations);
|
||||||
|
let func_body = produce_func_wasm(body, &serialized, &locations);
|
||||||
|
log::trace!("body: {:?}", func_body);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue