From 7c153403728be9d53f05152a99b9baacbd5662b1 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Sun, 19 Dec 2021 13:57:34 -0800 Subject: [PATCH] WIP. --- src/backend/mod.rs | 2 -- src/cfg/mod.rs | 1 + src/cfg/serialize.rs | 72 +++++++++++++++++++++++++++++++++++++++++++ src/cfg/structured.rs | 10 +++--- src/frontend.rs | 5 +-- src/ir.rs | 18 +++++------ 6 files changed, 86 insertions(+), 22 deletions(-) create mode 100644 src/cfg/serialize.rs diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 10d7a69..f65731e 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,6 +1,4 @@ //! Backend: IR to Wasm. -mod schedule; -pub(crate) use schedule::*; mod locations; pub(crate) use locations::*; diff --git a/src/cfg/mod.rs b/src/cfg/mod.rs index 619c438..452106a 100644 --- a/src/cfg/mod.rs +++ b/src/cfg/mod.rs @@ -8,6 +8,7 @@ use smallvec::SmallVec; pub mod domtree; pub mod postorder; +pub mod serialize; pub mod structured; #[derive(Clone, Debug)] diff --git a/src/cfg/serialize.rs b/src/cfg/serialize.rs new file mode 100644 index 0000000..4adb44d --- /dev/null +++ b/src/cfg/serialize.rs @@ -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, +} + +#[derive(Clone, Debug)] +pub enum SerializedBlockTarget { + Fallthrough(Vec), + Branch(usize, Vec), +} + +#[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, + 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, + ) { + match entry { + &BlockOrderEntry::StartBlock(header, ref param_tys) => { + todo!() + } + _ => { + todo!() + } + } + } +} diff --git a/src/cfg/structured.rs b/src/cfg/structured.rs index ce31fc7..3a2ad34 100644 --- a/src/cfg/structured.rs +++ b/src/cfg/structured.rs @@ -4,7 +4,7 @@ use fxhash::{FxHashMap, FxHashSet}; -use crate::{cfg::CFGInfo, BlockId, FunctionBody}; +use crate::{cfg::CFGInfo, BlockId, FunctionBody, Value}; #[derive(Clone, Debug)] pub enum Node { @@ -284,8 +284,8 @@ pub struct BlockOrder { #[derive(Clone, Debug)] pub enum BlockOrderEntry { - StartBlock(Vec), - StartLoop(Vec), + StartBlock(BlockId, Vec<(wasmparser::Type, Value)>), + StartLoop(BlockId, Vec<(wasmparser::Type, Value)>), End, BasicBlock(BlockId, Vec), } @@ -337,9 +337,9 @@ impl BlockOrder { } let params = f.blocks[header].params.clone(); if is_loop { - entries.push(BlockOrderEntry::StartLoop(params)); + entries.push(BlockOrderEntry::StartLoop(header, params)); } else { - entries.push(BlockOrderEntry::StartBlock(params)); + entries.push(BlockOrderEntry::StartBlock(header, params)); } for i in 0..subregions.len() { diff --git a/src/frontend.rs b/src/frontend.rs index 8a2ea5f..8b5ee23 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -1140,10 +1140,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> { ); let block = self.cur_block.unwrap(); for i in 0..num_params { - let ty = self.body.blocks[block].params[i]; - let value = self - .body - .add_value(ValueDef::BlockParam(block, i), Some(ty)); + let (ty, value) = self.body.blocks[block].params[i]; log::trace!(" -> push {:?} ty {:?}", value, ty); self.op_stack.push((ty, value)); } diff --git a/src/ir.rs b/src/ir.rs index c03333d..6798a12 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -123,15 +123,11 @@ impl FunctionBody { 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(); - self.blocks[block].params.push(ty); - index - } - - 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)) + let value = self.add_value(ValueDef::BlockParam(block, index), Some(ty)); + self.blocks[block].params.push((ty, value)); + value } pub fn add_placeholder(&mut self, ty: Type) -> Value { @@ -142,7 +138,7 @@ impl FunctionBody { assert!(self.values[value.index()] == ValueDef::Placeholder); let ty = self.types[value.index()].unwrap(); 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); } @@ -213,8 +209,8 @@ pub struct Block { pub preds: Vec, /// For each predecessor block, our index in its `succs` array. pub pos_in_pred_succ: Vec, - /// Type of each blockparam. - pub params: Vec, + /// Type and Value for each blockparam. + pub params: Vec<(Type, Value)>, } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]