This commit is contained in:
Chris Fallin 2021-12-24 00:28:44 -08:00
parent 726b4da33d
commit f92ea9a556
4 changed files with 87 additions and 24 deletions

View file

@ -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![],

View file

@ -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;

View file

@ -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);
} }
} }
} }

View file

@ -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, &regions); let blockorder = BlockOrder::compute(body, &cfg, &regions);
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);
} }
_ => {} _ => {}
} }