This commit is contained in:
Chris Fallin 2021-11-13 14:23:22 -08:00
parent e6024c4ffd
commit bc245b581a
3 changed files with 38 additions and 8 deletions

View file

@ -189,7 +189,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
| Operator::Call { .. }
| Operator::LocalGet { .. }
| Operator::LocalSet { .. }
| Operator::LocalTee { .. } => self.emit(op.clone())?,
| Operator::LocalTee { .. }
| Operator::I32Eqz => self.emit(op.clone())?,
Operator::End => match self.ctrl_stack.pop() {
None => {
@ -409,7 +410,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
fn emit_branch(&mut self, target: BlockId, args: &[ValueId]) {
if let Some(block) = self.cur_block {
let args = args.iter().map(|&val| Operand::Value(val)).collect();
let args = args.iter().map(|&val| Operand::value(val)).collect();
let target = BlockTarget {
block: target,
args,
@ -429,14 +430,14 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
if let Some(block) = self.cur_block {
let if_true_args = if_true_args
.iter()
.map(|&val| Operand::Value(val))
.map(|&val| Operand::value(val))
.collect();
let if_false_args = if_false_args
.iter()
.map(|&val| Operand::Value(val))
.map(|&val| Operand::value(val))
.collect();
self.body.blocks[block].terminator = Terminator::CondBr {
cond: Operand::Value(cond),
cond: Operand::value(cond),
if_true: BlockTarget {
block: if_true,
args: if_true_args,
@ -457,7 +458,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
args: &[ValueId],
) {
if let Some(block) = self.cur_block {
let args: Vec<Operand<'a>> = args.iter().map(|&arg| Operand::Value(arg)).collect();
let args: Vec<Operand<'a>> = args.iter().map(|&arg| Operand::value(arg)).collect();
let targets = indexed_targets
.iter()
.map(|&block| BlockTarget {
@ -470,7 +471,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
args: args.clone(),
};
self.body.blocks[block].terminator = Terminator::Select {
value: Operand::Value(index),
value: Operand::value(index),
targets,
default,
};
@ -500,7 +501,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
{
let stack_top = self.op_stack.pop().unwrap();
assert_eq!(self.body.values[stack_top].ty, input);
inputs.push(Operand::Value(stack_top));
inputs.push(Operand::value(stack_top));
}
inputs.reverse();
@ -520,6 +521,13 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
outputs,
inputs,
});
} else {
let _ = self
.op_stack
.split_off(op_inputs(self.module, self.my_sig, &self.body.locals[..], &op)?.len());
for _ in 0..op_outputs(self.module, &self.body.locals[..], &op)?.len() {
self.op_stack.push(NO_VALUE);
}
}
Ok(())

View file

@ -8,6 +8,8 @@ pub type BlockId = usize;
pub type InstId = usize;
pub type ValueId = usize;
pub const NO_VALUE: ValueId = usize::MAX;
#[derive(Clone, Debug, Default)]
pub struct Module<'a> {
pub funcs: Vec<FuncDecl<'a>>,
@ -64,8 +66,23 @@ pub struct Inst<'a> {
#[derive(Clone, Debug)]
pub enum Operand<'a> {
/// An SSA value.
Value(ValueId),
/// Tree-ified instructions for Wasm emission.
Sub(Box<Inst<'a>>),
/// Undef values are produced when code is unreachable and thus
/// removed/never executed.
Undef,
}
impl<'a> Operand<'a> {
pub fn value(value: ValueId) -> Self {
if value == NO_VALUE {
Operand::Undef
} else {
Operand::Value(value)
}
}
}
#[derive(Clone, Debug)]

View file

@ -24,6 +24,9 @@ pub fn op_inputs(
}
&Operator::LocalGet { .. } => Ok(vec![]),
&Operator::I32Eqz => Ok(vec![Type::I32]),
&Operator::I32Eq => Ok(vec![Type::I32, Type::I32]),
_ => bail!("Unknown operator in op_inputs(): {:?}", op),
}
}
@ -40,6 +43,8 @@ pub fn op_outputs(module: &Module, my_locals: &[Type], op: &Operator<'_>) -> Res
&Operator::LocalSet { .. } | &Operator::LocalTee { .. } => Ok(vec![]),
&Operator::LocalGet { local_index } => Ok(vec![my_locals[local_index as usize]]),
&Operator::I32Eqz | &Operator::I32Eq => Ok(vec![Type::I32]),
_ => bail!("Unknown operator in op_outputs(): {:?}", op),
}
}