Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added public methods to iterate all blocks of a local function + Floating point check #235

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ macro_rules! define_get_push_index {
#[inline]
pub(crate) fn $push_name(&mut self, id: $id_ty) {
let idx = self.$member.len() as u32;
log::trace!(concat!(stringify!($push_name),": assigning index {} to {:?}"), idx, id);
//log::trace!(concat!(stringify!($push_name),": assigning index {} to {:?}"), idx, id);
self.$member.insert(id, idx);
}
)*
Expand Down
174 changes: 174 additions & 0 deletions src/ir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ impl Local {
pub fn ty(&self) -> ValType {
self.ty
}

/// Indicate if the Local is a floating point
#[inline(always)]
pub fn is_float(&self) -> bool {
self.ty.is_float()
}
}

/// The identifier for a `InstrSeq` within some `LocalFunction`.
Expand Down Expand Up @@ -630,6 +636,12 @@ impl Value {
}
}
}

/// Indicate if the Value is a floating point
#[inline(always)]
pub fn is_float(&self) -> bool {
matches!(self, Self::F32(_) | Self::F64(_))
}
}

impl fmt::Display for Value {
Expand Down Expand Up @@ -884,6 +896,73 @@ pub enum BinaryOp {
I64x2ExtMulHighI32x4U,
}

impl BinaryOp {
/// Indicate if the BinOp is a floating point
#[inline(always)]
pub fn is_float(&self) -> bool {
use BinaryOp::*;
matches!(
self,
F32Eq
| F32Ne
| F32Lt
| F32Gt
| F32Le
| F32Ge
| F64Eq
| F64Ne
| F64Lt
| F64Gt
| F64Le
| F64Ge
| F32Add
| F32Sub
| F32Mul
| F32Div
| F32Min
| F32Max
| F32Copysign
| F64Add
| F64Sub
| F64Mul
| F64Div
| F64Min
| F64Max
| F64Copysign
| F32x4ReplaceLane { .. }
| F64x2ReplaceLane { .. }
| F32x4Eq
| F32x4Ne
| F32x4Lt
| F32x4Gt
| F32x4Le
| F32x4Ge
| F64x2Eq
| F64x2Ne
| F64x2Lt
| F64x2Gt
| F64x2Le
| F64x2Ge
| F32x4Add
| F32x4Sub
| F32x4Mul
| F32x4Div
| F32x4Min
| F32x4Max
| F32x4PMin
| F32x4PMax
| F64x2Add
| F64x2Sub
| F64x2Mul
| F64x2Div
| F64x2Min
| F64x2Max
| F64x2PMin
| F64x2PMax
)
}
}

/// Possible unary operations in wasm
#[allow(missing_docs)]
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -1038,6 +1117,89 @@ pub enum UnaryOp {
I32x4WidenHighI16x8U,
}

impl UnaryOp {
/// Indicate if the UnaryOp is a floating point
#[inline(always)]
pub fn is_float(&self) -> bool {
use UnaryOp::*;
matches!(
self,
F32Abs
| F32Neg
| F32Ceil
| F32Floor
| F32Trunc
| F32Nearest
| F32Sqrt
| F64Abs
| F64Neg
| F64Ceil
| F64Floor
| F64Trunc
| F64Nearest
| F64Sqrt
| I32TruncSF32
| I32TruncUF32
| I32TruncSF64
| I32TruncUF64
| I64TruncSF32
| I64TruncUF32
| I64TruncSF64
| I64TruncUF64
| F32ConvertSI32
| F32ConvertUI32
| F32ConvertSI64
| F32ConvertUI64
| F32DemoteF64
| F64ConvertSI32
| F64ConvertUI32
| F64ConvertSI64
| F64ConvertUI64
| F64PromoteF32
| I32ReinterpretF32
| I64ReinterpretF64
| F32ReinterpretI32
| F64ReinterpretI64
| F32x4Splat
| F32x4ExtractLane { .. }
| F64x2Splat
| F64x2ExtractLane { .. }
| F32x4Abs
| F32x4Neg
| F32x4Sqrt
| F32x4Ceil
| F32x4Floor
| F32x4Trunc
| F32x4Nearest
| F64x2Abs
| F64x2Neg
| F64x2Sqrt
| F64x2Ceil
| F64x2Floor
| F64x2Trunc
| F64x2Nearest
| I32x4TruncSatF64x2SZero
| I32x4TruncSatF64x2UZero
| F64x2ConvertLowI32x4S
| F64x2ConvertLowI32x4U
| F32x4DemoteF64x2Zero
| F64x2PromoteLowF32x4
| I32x4TruncSatF32x4S
| I32x4TruncSatF32x4U
| F32x4ConvertI32x4S
| F32x4ConvertI32x4U
| I32TruncSSatF32
| I32TruncUSatF32
| I32TruncSSatF64
| I32TruncUSatF64
| I64TruncSSatF32
| I64TruncUSatF32
| I64TruncSSatF64
| I64TruncUSatF64
)
}
}

/// The different kinds of load instructions that are part of a `Load` IR node
#[derive(Debug, Copy, Clone)]
#[allow(missing_docs)]
Expand Down Expand Up @@ -1121,6 +1283,12 @@ impl LoadKind {
F32 | F64 | V128 => false,
}
}

/// Indicate if the LoadKind is a floating point
#[inline(always)]
pub fn is_float(&self) -> bool {
matches!(self, Self::F32 | Self::F64)
}
}

impl ExtendedLoad {
Expand Down Expand Up @@ -1177,6 +1345,12 @@ impl StoreKind {
F32 | F64 | V128 => false,
}
}

/// Indicate if the LoadKind is a floating point
#[inline(always)]
pub fn is_float(&self) -> bool {
matches!(self, Self::F32 | Self::F64)
}
}

/// Arguments to memory operations, containing a constant offset from a dynamic
Expand Down
4 changes: 2 additions & 2 deletions src/ir/traversals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ pub fn dfs_in_order<'instr>(

'traversing_instrs: for (index, (instr, loc)) in seq.instrs.iter().enumerate().skip(index) {
// Visit this instruction.
log::trace!("dfs_in_order: visit_instr({:?})", instr);
//log::trace!("dfs_in_order: visit_instr({:?})", instr);
visitor.visit_instr(instr, loc);

// Visit every other resource that this instruction references,
// e.g. `MemoryId`s, `FunctionId`s and all that.
log::trace!("dfs_in_order: ({:?}).visit(..)", instr);
//log::trace!("dfs_in_order: ({:?}).visit(..)", instr);
instr.visit(visitor);

match instr {
Expand Down
6 changes: 3 additions & 3 deletions src/module/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ impl Module {
/// they're actually passive or not, and that property is checked during
/// validation.
pub(crate) fn reserve_data(&mut self, count: u32, ids: &mut IndicesToIds) {
log::debug!("reserving space for {} data segments", count);
//log::debug!("reserving space for {} data segments", count);
for _ in 0..count {
ids.push_data(self.data.arena.alloc_with_id(|id| Data {
id,
Expand All @@ -186,7 +186,7 @@ impl Module {
section: wasmparser::DataSectionReader,
ids: &IndicesToIds,
) -> Result<()> {
log::debug!("parse data section");
//log::debug!("parse data section");
let preallocated = self.data.arena.len() > 0;
for (i, segment) in section.into_iter().enumerate() {
let segment = segment?;
Expand Down Expand Up @@ -244,7 +244,7 @@ impl Module {

impl Emit for ModuleData {
fn emit(&self, cx: &mut EmitContext) {
log::debug!("emit data section");
//log::debug!("emit data section");
if self.arena.len() == 0 {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/module/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl Module {
section: wasmparser::ElementSectionReader,
ids: &mut IndicesToIds,
) -> Result<()> {
log::debug!("parse element section");
//log::debug!("parse element section");
for (i, segment) in section.into_iter().enumerate() {
let segment = segment?;
let ty = ValType::parse(&segment.ty)?;
Expand Down
4 changes: 2 additions & 2 deletions src/module/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl Module {
section: wasmparser::ExportSectionReader,
ids: &IndicesToIds,
) -> Result<()> {
log::debug!("parse export section");
//log::debug!("parse export section");
use wasmparser::ExternalKind::*;

for entry in section {
Expand Down Expand Up @@ -161,7 +161,7 @@ impl Module {

impl Emit for ModuleExports {
fn emit(&self, cx: &mut EmitContext) {
log::debug!("emit export section");
//log::debug!("emit export section");
// NB: exports are always considered used. They are the roots that the
// used analysis searches out from.

Expand Down
12 changes: 11 additions & 1 deletion src/module/functions/local_function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ impl LocalFunction {
&self.builder.arena[id]
}

/// Iterate over all the blocks in the function
pub fn blocks(&self) -> impl Iterator<Item = (InstrSeqId, &InstrSeq)> {
self.builder.arena.iter()
}

/// Mutably iterate over all the blocks in the function
pub fn blocks_mut(&mut self) -> impl Iterator<Item = (InstrSeqId, &mut InstrSeq)> {
self.builder.arena.iter_mut()
}

/// Get the block associated with the given id.
pub fn block_mut(&mut self, id: InstrSeqId) -> &mut InstrSeq {
&mut self.builder.arena[id]
Expand Down Expand Up @@ -288,7 +298,7 @@ fn append_instruction<'context>(
// should succeed.
use crate::ir::ExtendedLoad::*;

log::trace!("validate instruction: {:?}", inst);
//log::trace!("validate instruction: {:?}", inst);

let const_ = |ctx: &mut ValidationContext, value| {
ctx.alloc_instr(Const { value }, loc);
Expand Down
10 changes: 5 additions & 5 deletions src/module/functions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ impl ModuleFunctions {
}

pub(crate) fn emit_func_section(&self, cx: &mut EmitContext) {
log::debug!("emit function section");
//log::debug!("emit function section");
let functions = used_local_functions(cx);
if functions.len() == 0 {
return;
Expand Down Expand Up @@ -304,7 +304,7 @@ impl Module {
section: wasmparser::FunctionSectionReader,
ids: &mut IndicesToIds,
) -> Result<()> {
log::debug!("parse function section");
//log::debug!("parse function section");
for func in section {
let ty = ids.get_type(func?)?;
let id = self
Expand All @@ -327,7 +327,7 @@ impl Module {
indices: &mut IndicesToIds,
on_instr_pos: Option<&(dyn Fn(&usize) -> InstrLocId + Sync + Send + 'static)>,
) -> Result<()> {
log::debug!("parse code section");
//log::debug!("parse code section");
let num_imports = self.funcs.arena.len() - functions.len();

// First up serially create corresponding `LocalId` instances for all
Expand Down Expand Up @@ -455,7 +455,7 @@ fn collect_non_default_code_offsets(

impl Emit for ModuleFunctions {
fn emit(&self, cx: &mut EmitContext) {
log::debug!("emit code section");
//log::debug!("emit code section");
let functions = used_local_functions(cx);
if functions.len() == 0 {
return;
Expand All @@ -471,7 +471,7 @@ impl Emit for ModuleFunctions {
// functions together.
let bytes = maybe_parallel!(functions.(into_iter | into_par_iter))
.map(|(id, func, _size)| {
log::debug!("emit function {:?} {:?}", id, cx.module.funcs.get(id).name);
//log::debug!("emit function {:?} {:?}", id, cx.module.funcs.get(id).name);
let mut wasm = Vec::new();
let mut encoder = Encoder::new(&mut wasm);
let mut map = if generate_map { Some(Vec::new()) } else { None };
Expand Down
10 changes: 8 additions & 2 deletions src/module/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ impl Global {
pub fn id(&self) -> GlobalId {
self.id
}

/// Indicate if the Global is a floating point
#[inline(always)]
pub fn is_float(&self) -> bool {
self.ty.is_float()
}
}

impl Emit for Global {
Expand Down Expand Up @@ -109,7 +115,7 @@ impl Module {
section: wasmparser::GlobalSectionReader,
ids: &mut IndicesToIds,
) -> Result<()> {
log::debug!("parse global section");
//log::debug!("parse global section");
for g in section {
let g = g?;
let id = self.globals.add_local(
Expand All @@ -125,7 +131,7 @@ impl Module {

impl Emit for ModuleGlobals {
fn emit(&self, cx: &mut EmitContext) {
log::debug!("emit global section");
//log::debug!("emit global section");
fn get_local(global: &Global) -> Option<(&Global, &InitExpr)> {
match &global.kind {
GlobalKind::Import(_) => None,
Expand Down
Loading