WIP.
This commit is contained in:
parent
e6024c4ffd
commit
bc245b581a
|
@ -189,7 +189,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
| Operator::Call { .. }
|
| Operator::Call { .. }
|
||||||
| Operator::LocalGet { .. }
|
| Operator::LocalGet { .. }
|
||||||
| Operator::LocalSet { .. }
|
| Operator::LocalSet { .. }
|
||||||
| Operator::LocalTee { .. } => self.emit(op.clone())?,
|
| Operator::LocalTee { .. }
|
||||||
|
| Operator::I32Eqz => self.emit(op.clone())?,
|
||||||
|
|
||||||
Operator::End => match self.ctrl_stack.pop() {
|
Operator::End => match self.ctrl_stack.pop() {
|
||||||
None => {
|
None => {
|
||||||
|
@ -409,7 +410,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
|
|
||||||
fn emit_branch(&mut self, target: BlockId, args: &[ValueId]) {
|
fn emit_branch(&mut self, target: BlockId, args: &[ValueId]) {
|
||||||
if let Some(block) = self.cur_block {
|
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 {
|
let target = BlockTarget {
|
||||||
block: target,
|
block: target,
|
||||||
args,
|
args,
|
||||||
|
@ -429,14 +430,14 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
if let Some(block) = self.cur_block {
|
if let Some(block) = self.cur_block {
|
||||||
let if_true_args = if_true_args
|
let if_true_args = if_true_args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&val| Operand::Value(val))
|
.map(|&val| Operand::value(val))
|
||||||
.collect();
|
.collect();
|
||||||
let if_false_args = if_false_args
|
let if_false_args = if_false_args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&val| Operand::Value(val))
|
.map(|&val| Operand::value(val))
|
||||||
.collect();
|
.collect();
|
||||||
self.body.blocks[block].terminator = Terminator::CondBr {
|
self.body.blocks[block].terminator = Terminator::CondBr {
|
||||||
cond: Operand::Value(cond),
|
cond: Operand::value(cond),
|
||||||
if_true: BlockTarget {
|
if_true: BlockTarget {
|
||||||
block: if_true,
|
block: if_true,
|
||||||
args: if_true_args,
|
args: if_true_args,
|
||||||
|
@ -457,7 +458,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
args: &[ValueId],
|
args: &[ValueId],
|
||||||
) {
|
) {
|
||||||
if let Some(block) = self.cur_block {
|
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
|
let targets = indexed_targets
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&block| BlockTarget {
|
.map(|&block| BlockTarget {
|
||||||
|
@ -470,7 +471,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
args: args.clone(),
|
args: args.clone(),
|
||||||
};
|
};
|
||||||
self.body.blocks[block].terminator = Terminator::Select {
|
self.body.blocks[block].terminator = Terminator::Select {
|
||||||
value: Operand::Value(index),
|
value: Operand::value(index),
|
||||||
targets,
|
targets,
|
||||||
default,
|
default,
|
||||||
};
|
};
|
||||||
|
@ -500,7 +501,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
{
|
{
|
||||||
let stack_top = self.op_stack.pop().unwrap();
|
let stack_top = self.op_stack.pop().unwrap();
|
||||||
assert_eq!(self.body.values[stack_top].ty, input);
|
assert_eq!(self.body.values[stack_top].ty, input);
|
||||||
inputs.push(Operand::Value(stack_top));
|
inputs.push(Operand::value(stack_top));
|
||||||
}
|
}
|
||||||
inputs.reverse();
|
inputs.reverse();
|
||||||
|
|
||||||
|
@ -520,6 +521,13 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
outputs,
|
outputs,
|
||||||
inputs,
|
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(())
|
Ok(())
|
||||||
|
|
17
src/ir.rs
17
src/ir.rs
|
@ -8,6 +8,8 @@ pub type BlockId = usize;
|
||||||
pub type InstId = usize;
|
pub type InstId = usize;
|
||||||
pub type ValueId = usize;
|
pub type ValueId = usize;
|
||||||
|
|
||||||
|
pub const NO_VALUE: ValueId = usize::MAX;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct Module<'a> {
|
pub struct Module<'a> {
|
||||||
pub funcs: Vec<FuncDecl<'a>>,
|
pub funcs: Vec<FuncDecl<'a>>,
|
||||||
|
@ -64,8 +66,23 @@ pub struct Inst<'a> {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Operand<'a> {
|
pub enum Operand<'a> {
|
||||||
|
/// An SSA value.
|
||||||
Value(ValueId),
|
Value(ValueId),
|
||||||
|
/// Tree-ified instructions for Wasm emission.
|
||||||
Sub(Box<Inst<'a>>),
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
|
@ -24,6 +24,9 @@ pub fn op_inputs(
|
||||||
}
|
}
|
||||||
&Operator::LocalGet { .. } => Ok(vec![]),
|
&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),
|
_ => 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::LocalSet { .. } | &Operator::LocalTee { .. } => Ok(vec![]),
|
||||||
&Operator::LocalGet { local_index } => Ok(vec![my_locals[local_index as usize]]),
|
&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),
|
_ => bail!("Unknown operator in op_outputs(): {:?}", op),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue