This commit is contained in:
Chris Fallin 2021-12-19 13:57:34 -08:00
parent 3e67394ab1
commit 7c15340372
6 changed files with 86 additions and 22 deletions

View file

@ -1,6 +1,4 @@
//! Backend: IR to Wasm. //! Backend: IR to Wasm.
mod schedule;
pub(crate) use schedule::*;
mod locations; mod locations;
pub(crate) use locations::*; pub(crate) use locations::*;

View file

@ -8,6 +8,7 @@ use smallvec::SmallVec;
pub mod domtree; pub mod domtree;
pub mod postorder; pub mod postorder;
pub mod serialize;
pub mod structured; pub mod structured;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

72
src/cfg/serialize.rs Normal file
View file

@ -0,0 +1,72 @@
//! Serialization of the sea-of-nodes IR using a BlockOrder
//! Wasm-structured-control-flow result into actual order of operators
//! in Wasm function body. Contains everything needed to emit Wasm
//! except for value locations (and corresponding local spill/reloads).
use super::{
structured::{BlockOrder, BlockOrderEntry, BlockOrderTarget},
CFGInfo,
};
use crate::{BlockId, FunctionBody, Value};
#[derive(Clone, Debug)]
pub struct SerializedBody {
pub(crate) operators: Vec<SerializedOperator>,
}
#[derive(Clone, Debug)]
pub enum SerializedBlockTarget {
Fallthrough(Vec<Value>),
Branch(usize, Vec<Value>),
}
#[derive(Clone, Debug)]
pub enum SerializedOperator {
StartBlock {
header: BlockId,
params: Vec<(Value, wasmparser::Type)>,
},
StartLoop {
header: BlockId,
param: Vec<(Value, wasmparser::Type)>,
},
Br(SerializedBlockTarget),
BrIf {
cond: Value,
if_true: SerializedBlockTarget,
if_false: SerializedBlockTarget,
},
BrTable {
index: Value,
targets: Vec<SerializedBlockTarget>,
default: SerializedBlockTarget,
},
Operator(Value),
End,
}
impl SerializedBody {
pub fn compute(f: &FunctionBody, cfg: &CFGInfo, order: &BlockOrder) -> SerializedBody {
let mut operators = vec![];
for entry in &order.entries {
Self::compute_entry(f, cfg, entry, &mut operators);
}
SerializedBody { operators }
}
fn compute_entry(
f: &FunctionBody,
cfg: &CFGInfo,
entry: &BlockOrderEntry,
operators: &mut Vec<SerializedOperator>,
) {
match entry {
&BlockOrderEntry::StartBlock(header, ref param_tys) => {
todo!()
}
_ => {
todo!()
}
}
}
}

View file

@ -4,7 +4,7 @@
use fxhash::{FxHashMap, FxHashSet}; use fxhash::{FxHashMap, FxHashSet};
use crate::{cfg::CFGInfo, BlockId, FunctionBody}; use crate::{cfg::CFGInfo, BlockId, FunctionBody, Value};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Node { pub enum Node {
@ -284,8 +284,8 @@ pub struct BlockOrder {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum BlockOrderEntry { pub enum BlockOrderEntry {
StartBlock(Vec<wasmparser::Type>), StartBlock(BlockId, Vec<(wasmparser::Type, Value)>),
StartLoop(Vec<wasmparser::Type>), StartLoop(BlockId, Vec<(wasmparser::Type, Value)>),
End, End,
BasicBlock(BlockId, Vec<BlockOrderTarget>), BasicBlock(BlockId, Vec<BlockOrderTarget>),
} }
@ -337,9 +337,9 @@ impl BlockOrder {
} }
let params = f.blocks[header].params.clone(); let params = f.blocks[header].params.clone();
if is_loop { if is_loop {
entries.push(BlockOrderEntry::StartLoop(params)); entries.push(BlockOrderEntry::StartLoop(header, params));
} else { } else {
entries.push(BlockOrderEntry::StartBlock(params)); entries.push(BlockOrderEntry::StartBlock(header, params));
} }
for i in 0..subregions.len() { for i in 0..subregions.len() {

View file

@ -1140,10 +1140,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
); );
let block = self.cur_block.unwrap(); let block = self.cur_block.unwrap();
for i in 0..num_params { for i in 0..num_params {
let ty = self.body.blocks[block].params[i]; let (ty, value) = self.body.blocks[block].params[i];
let value = self
.body
.add_value(ValueDef::BlockParam(block, i), Some(ty));
log::trace!(" -> push {:?} ty {:?}", value, ty); log::trace!(" -> push {:?} ty {:?}", value, ty);
self.op_stack.push((ty, value)); self.op_stack.push((ty, value));
} }

View file

@ -123,15 +123,11 @@ impl FunctionBody {
value value
} }
pub fn add_blockparam(&mut self, block: BlockId, ty: Type) -> usize { pub fn add_blockparam(&mut self, block: BlockId, ty: Type) -> Value {
let index = self.blocks[block].params.len(); let index = self.blocks[block].params.len();
self.blocks[block].params.push(ty); let value = self.add_value(ValueDef::BlockParam(block, index), Some(ty));
index self.blocks[block].params.push((ty, value));
} value
pub fn add_blockparam_value(&mut self, block: BlockId, ty: Type) -> Value {
let index = self.add_blockparam(block, ty);
self.add_value(ValueDef::BlockParam(block, index), Some(ty))
} }
pub fn add_placeholder(&mut self, ty: Type) -> Value { pub fn add_placeholder(&mut self, ty: Type) -> Value {
@ -142,7 +138,7 @@ impl FunctionBody {
assert!(self.values[value.index()] == ValueDef::Placeholder); assert!(self.values[value.index()] == ValueDef::Placeholder);
let ty = self.types[value.index()].unwrap(); let ty = self.types[value.index()].unwrap();
let index = self.blocks[block].params.len(); let index = self.blocks[block].params.len();
self.blocks[block].params.push(ty); self.blocks[block].params.push((ty, value));
self.values[value.index()] = ValueDef::BlockParam(block, index); self.values[value.index()] = ValueDef::BlockParam(block, index);
} }
@ -213,8 +209,8 @@ pub struct Block {
pub preds: Vec<BlockId>, pub preds: Vec<BlockId>,
/// For each predecessor block, our index in its `succs` array. /// For each predecessor block, our index in its `succs` array.
pub pos_in_pred_succ: Vec<usize>, pub pos_in_pred_succ: Vec<usize>,
/// Type of each blockparam. /// Type and Value for each blockparam.
pub params: Vec<Type>, pub params: Vec<(Type, Value)>,
} }
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]