refactoring truncation
This commit is contained in:
parent
80fd0e89b4
commit
f1e715e9bd
|
@ -268,6 +268,21 @@ main := fn(): uint {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### wrong_dead_code_elimination
|
||||||
|
```hb
|
||||||
|
Color := struct {b: u8}
|
||||||
|
main := fn(): void {
|
||||||
|
color := Color.(0)
|
||||||
|
n := @as(u8, 1)
|
||||||
|
loop {
|
||||||
|
if color.b == 255 | color.b == 0 {
|
||||||
|
n = -n
|
||||||
|
}
|
||||||
|
color.b += n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### struct_operators
|
#### struct_operators
|
||||||
```hb
|
```hb
|
||||||
Point := struct {
|
Point := struct {
|
||||||
|
|
|
@ -266,10 +266,8 @@ impl TokenKind {
|
||||||
Self::Not => (value == 0) as _,
|
Self::Not => (value == 0) as _,
|
||||||
Self::Float if float => value,
|
Self::Float if float => value,
|
||||||
Self::Float => (value as f64).to_bits() as _,
|
Self::Float => (value as f64).to_bits() as _,
|
||||||
Self::Number => {
|
Self::Number if float => f64::from_bits(value as _) as _,
|
||||||
debug_assert!(float);
|
Self::Number => value,
|
||||||
f64::from_bits(value as _) as _
|
|
||||||
}
|
|
||||||
s => todo!("{s}"),
|
s => todo!("{s}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ pub mod ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Id {
|
impl Id {
|
||||||
pub const DEFAULT_INT: Self = Self::UINT;
|
pub const DINT: Self = Self::UINT;
|
||||||
|
|
||||||
pub fn bin_ret(self, op: TokenKind) -> Id {
|
pub fn bin_ret(self, op: TokenKind) -> Id {
|
||||||
use TokenKind as T;
|
use TokenKind as T;
|
||||||
|
@ -787,7 +787,7 @@ pub struct Sig {
|
||||||
ret: ty::Id,
|
ret: ty::Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone, Copy)]
|
||||||
struct Func {
|
struct Func {
|
||||||
file: Module,
|
file: Module,
|
||||||
name: Ident,
|
name: Ident,
|
||||||
|
@ -798,7 +798,7 @@ struct Func {
|
||||||
comp_state: [CompState; 2],
|
comp_state: [CompState; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, PartialEq, Eq)]
|
#[derive(Default, PartialEq, Eq, Clone, Copy)]
|
||||||
enum CompState {
|
enum CompState {
|
||||||
#[default]
|
#[default]
|
||||||
Dead,
|
Dead,
|
||||||
|
|
136
lang/src/son.rs
136
lang/src/son.rs
|
@ -231,7 +231,7 @@ impl Nodes {
|
||||||
let mut deepest = self[node].inputs[0];
|
let mut deepest = self[node].inputs[0];
|
||||||
for &inp in self[node].inputs[1..].iter() {
|
for &inp in self[node].inputs[1..].iter() {
|
||||||
if self.idepth(inp) > self.idepth(deepest) {
|
if self.idepth(inp) > self.idepth(deepest) {
|
||||||
if matches!(self[inp].kind, Kind::Call { .. }) {
|
if self[inp].kind.is_call() {
|
||||||
deepest = inp;
|
deepest = inp;
|
||||||
} else {
|
} else {
|
||||||
debug_assert!(!self.is_cfg(inp));
|
debug_assert!(!self.is_cfg(inp));
|
||||||
|
@ -250,8 +250,7 @@ impl Nodes {
|
||||||
self[current].outputs.remove(index);
|
self[current].outputs.remove(index);
|
||||||
self[node].inputs[0] = deepest;
|
self[node].inputs[0] = deepest;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
!self[deepest].outputs.contains(&node)
|
!self[deepest].outputs.contains(&node) || self[deepest].kind.is_call(),
|
||||||
|| matches!(self[deepest].kind, Kind::Call { .. }),
|
|
||||||
"{node} {:?} {deepest} {:?}",
|
"{node} {:?} {deepest} {:?}",
|
||||||
self[node],
|
self[node],
|
||||||
self[deepest]
|
self[deepest]
|
||||||
|
@ -937,9 +936,12 @@ impl Nodes {
|
||||||
let &[_, oper] = self[target].inputs.as_slice() else { unreachable!() };
|
let &[_, oper] = self[target].inputs.as_slice() else { unreachable!() };
|
||||||
let ty = self[target].ty;
|
let ty = self[target].ty;
|
||||||
|
|
||||||
let is_float = self[oper].ty.is_float();
|
if matches!(op, TokenKind::Number | TokenKind::Float) && ty == self[oper].ty {
|
||||||
|
return Some(oper);
|
||||||
|
}
|
||||||
|
|
||||||
if let K::CInt { value } = self[oper].kind {
|
if let K::CInt { value } = self[oper].kind {
|
||||||
|
let is_float = self[oper].ty.is_float();
|
||||||
return Some(self.new_const(ty, op.apply_unop(value, is_float)));
|
return Some(self.new_const(ty, op.apply_unop(value, is_float)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1089,7 +1091,7 @@ impl Nodes {
|
||||||
mem::swap(&mut a, &mut b);
|
mem::swap(&mut a, &mut b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(self[a].kind, Kind::Call { .. })
|
if self[a].kind.is_call()
|
||||||
&& self[a].inputs.last() == Some(&target)
|
&& self[a].inputs.last() == Some(&target)
|
||||||
&& self[b].kind == Kind::Load
|
&& self[b].kind == Kind::Load
|
||||||
&& let &[store] = self[b].outputs.as_slice()
|
&& let &[store] = self[b].outputs.as_slice()
|
||||||
|
@ -1851,6 +1853,14 @@ pub enum Kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Kind {
|
impl Kind {
|
||||||
|
fn is_call(&self) -> bool {
|
||||||
|
matches!(self, Kind::Call { .. })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_eca(&self) -> bool {
|
||||||
|
matches!(self, Kind::Call { func: ty::Func::ECA, .. })
|
||||||
|
}
|
||||||
|
|
||||||
fn is_pinned(&self) -> bool {
|
fn is_pinned(&self) -> bool {
|
||||||
self.is_cfg() || matches!(self, Self::Phi | Self::Arg | Self::Mem | Self::Loops)
|
self.is_cfg() || matches!(self, Self::Phi | Self::Arg | Self::Mem | Self::Loops)
|
||||||
}
|
}
|
||||||
|
@ -2580,24 +2590,12 @@ impl<'a> Codegen<'a> {
|
||||||
{
|
{
|
||||||
Some(self.ci.nodes.new_const_lit(ty, (value as f64).to_bits() as i64))
|
Some(self.ci.nodes.new_const_lit(ty, (value as f64).to_bits() as i64))
|
||||||
}
|
}
|
||||||
Expr::Number { value, .. } => Some(
|
Expr::Number { value, .. } => {
|
||||||
self.ci.nodes.new_const_lit(
|
self.gen_inferred_const(ctx, ty::Id::DINT, value, ty::Id::is_integer)
|
||||||
ctx.ty
|
}
|
||||||
.map(|ty| self.tys.inner_of(ty).unwrap_or(ty))
|
Expr::Float { value, .. } => {
|
||||||
.filter(|ty| ty.is_integer())
|
self.gen_inferred_const(ctx, ty::Id::F32, value as i64, ty::Id::is_float)
|
||||||
.unwrap_or(ty::Id::DEFAULT_INT),
|
}
|
||||||
value,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expr::Float { value, .. } => Some(
|
|
||||||
self.ci.nodes.new_const_lit(
|
|
||||||
ctx.ty
|
|
||||||
.map(|ty| self.tys.inner_of(ty).unwrap_or(ty))
|
|
||||||
.filter(|ty| ty.is_float())
|
|
||||||
.unwrap_or(ty::Id::F32),
|
|
||||||
value as i64,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expr::Ident { id, .. }
|
Expr::Ident { id, .. }
|
||||||
if let Some(index) = self.ci.scope.vars.iter().rposition(|v| v.id == id) =>
|
if let Some(index) = self.ci.scope.vars.iter().rposition(|v| v.id == id) =>
|
||||||
{
|
{
|
||||||
|
@ -2937,13 +2935,25 @@ impl<'a> Codegen<'a> {
|
||||||
self.strip_var(&mut rhs);
|
self.strip_var(&mut rhs);
|
||||||
self.implicit_unwrap(right.pos(), &mut rhs);
|
self.implicit_unwrap(right.pos(), &mut rhs);
|
||||||
let (ty, aclass) = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
let (ty, aclass) = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
||||||
|
let fty = ty.bin_ret(op);
|
||||||
|
if fty == ty::Id::BOOL {
|
||||||
|
if lhs.ty.is_float() {
|
||||||
|
} else {
|
||||||
|
self.ci.nodes.lock(rhs.id);
|
||||||
|
let lty = lhs.ty.extend();
|
||||||
|
if lty != lhs.ty {
|
||||||
|
self.extend(&mut lhs, lty);
|
||||||
|
}
|
||||||
|
self.ci.nodes.unlock(rhs.id);
|
||||||
|
let rty = rhs.ty.extend();
|
||||||
|
if rty != rhs.ty {
|
||||||
|
self.extend(&mut rhs, rty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let inps = [VOID, lhs.id, rhs.id];
|
let inps = [VOID, lhs.id, rhs.id];
|
||||||
let bop = self.ci.nodes.new_node_lit(
|
let bop =
|
||||||
ty.bin_ret(op),
|
self.ci.nodes.new_node_lit(fty, Kind::BinOp { op }, inps, self.tys);
|
||||||
Kind::BinOp { op },
|
|
||||||
inps,
|
|
||||||
self.tys,
|
|
||||||
);
|
|
||||||
self.ci.nodes.pass_aclass(aclass, bop.id);
|
self.ci.nodes.pass_aclass(aclass, bop.id);
|
||||||
Some(bop)
|
Some(bop)
|
||||||
}
|
}
|
||||||
|
@ -2988,8 +2998,8 @@ impl<'a> Codegen<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let elem = self.tys.ins.slices[s].elem;
|
let elem = self.tys.ins.slices[s].elem;
|
||||||
let mut idx = self.expr_ctx(index, Ctx::default().with_ty(ty::Id::DEFAULT_INT))?;
|
let mut idx = self.expr_ctx(index, Ctx::default().with_ty(ty::Id::DINT))?;
|
||||||
self.assert_ty(index.pos(), &mut idx, ty::Id::DEFAULT_INT, "subscript");
|
self.assert_ty(index.pos(), &mut idx, ty::Id::DINT, "subscript");
|
||||||
let size = self.ci.nodes.new_const(ty::Id::INT, self.tys.size_of(elem));
|
let size = self.ci.nodes.new_const(ty::Id::INT, self.tys.size_of(elem));
|
||||||
let inps = [VOID, idx.id, size];
|
let inps = [VOID, idx.id, size];
|
||||||
let offset = self.ci.nodes.new_node(
|
let offset = self.ci.nodes.new_node(
|
||||||
|
@ -3018,27 +3028,12 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
Expr::Directive { name: "sizeof", args: [ty], .. } => {
|
Expr::Directive { name: "sizeof", args: [ty], .. } => {
|
||||||
let ty = self.ty(ty);
|
let ty = self.ty(ty);
|
||||||
Some(
|
self.gen_inferred_const(ctx, ty::Id::DINT, self.tys.size_of(ty), ty::Id::is_integer)
|
||||||
self.ci.nodes.new_const_lit(
|
|
||||||
ctx.ty
|
|
||||||
.map(|ty| self.tys.inner_of(ty).unwrap_or(ty))
|
|
||||||
.filter(|ty| ty.is_integer())
|
|
||||||
.unwrap_or(ty::Id::DEFAULT_INT),
|
|
||||||
self.tys.size_of(ty),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Expr::Directive { name: "alignof", args: [ty], .. } => {
|
Expr::Directive { name: "alignof", args: [ty], .. } => {
|
||||||
let ty = self.ty(ty);
|
let ty = self.ty(ty);
|
||||||
Some(
|
let align = self.tys.align_of(ty);
|
||||||
self.ci.nodes.new_const_lit(
|
self.gen_inferred_const(ctx, ty::Id::DINT, align, ty::Id::is_integer)
|
||||||
ctx.ty
|
|
||||||
.map(|ty| self.tys.inner_of(ty).unwrap_or(ty))
|
|
||||||
.filter(|ty| ty.is_integer())
|
|
||||||
.unwrap_or(ty::Id::DEFAULT_INT),
|
|
||||||
self.tys.align_of(ty),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Expr::Directive { name: "bitcast", args: [val], pos } => {
|
Expr::Directive { name: "bitcast", args: [val], pos } => {
|
||||||
let mut val = self.raw_expr(val)?;
|
let mut val = self.raw_expr(val)?;
|
||||||
|
@ -3744,6 +3739,24 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_inferred_const(
|
||||||
|
&mut self,
|
||||||
|
ctx: Ctx,
|
||||||
|
fallback: ty::Id,
|
||||||
|
value: impl Into<i64>,
|
||||||
|
filter: impl Fn(ty::Id) -> bool,
|
||||||
|
) -> Option<Value> {
|
||||||
|
Some(
|
||||||
|
self.ci.nodes.new_const_lit(
|
||||||
|
ctx.ty
|
||||||
|
.map(|ty| self.tys.inner_of(ty).unwrap_or(ty))
|
||||||
|
.filter(|&ty| filter(ty))
|
||||||
|
.unwrap_or(fallback),
|
||||||
|
value,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn gen_call(&mut self, func: &Expr, args: &[Expr], inline: bool) -> Option<Value> {
|
fn gen_call(&mut self, func: &Expr, args: &[Expr], inline: bool) -> Option<Value> {
|
||||||
let ty = self.ty(func);
|
let ty = self.ty(func);
|
||||||
let ty::Kind::Func(mut fu) = ty.expand() else {
|
let ty::Kind::Func(mut fu) = ty.expand() else {
|
||||||
|
@ -3851,10 +3864,8 @@ impl<'a> Codegen<'a> {
|
||||||
let (v, ctrl, scope) = mem::replace(&mut self.ci.inline_ret, prev_inline_ret)?;
|
let (v, ctrl, scope) = mem::replace(&mut self.ci.inline_ret, prev_inline_ret)?;
|
||||||
if is_inline
|
if is_inline
|
||||||
&& ctrl.get() != prev_ctrl
|
&& ctrl.get() != prev_ctrl
|
||||||
&& (!matches!(self.ci.nodes[ctrl.get()].kind, Kind::Call {
|
&& (!self.ci.nodes[ctrl.get()].kind.is_eca()
|
||||||
func: ty::Func::ECA,
|
|| self.ci.nodes[ctrl.get()].inputs[0] != prev_ctrl)
|
||||||
..
|
|
||||||
}) || self.ci.nodes[ctrl.get()].inputs[0] != prev_ctrl)
|
|
||||||
{
|
{
|
||||||
self.report(body.pos(), "function is makred inline but it contains controlflow");
|
self.report(body.pos(), "function is makred inline but it contains controlflow");
|
||||||
}
|
}
|
||||||
|
@ -4067,17 +4078,10 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let sym = SymKey::FuncInst(*func, args);
|
let sym = SymKey::FuncInst(*func, args);
|
||||||
let ct = |ins: &mut crate::TypeIns| {
|
let ct = |ins: &mut crate::TypeIns| {
|
||||||
let fuc = &ins.funcs[*func];
|
let fuc = ins.funcs[*func];
|
||||||
|
debug_assert!(fuc.comp_state.iter().all(|&s| s == CompState::default()));
|
||||||
ins.funcs
|
ins.funcs
|
||||||
.push(Func {
|
.push(Func { base: Some(*func), sig: Some(Sig { args, ret }), ..fuc })
|
||||||
file: fuc.file,
|
|
||||||
name: fuc.name,
|
|
||||||
base: Some(*func),
|
|
||||||
sig: Some(Sig { args, ret }),
|
|
||||||
expr: fuc.expr,
|
|
||||||
is_inline: fuc.is_inline,
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.into()
|
.into()
|
||||||
};
|
};
|
||||||
let ty::Kind::Func(f) =
|
let ty::Kind::Func(f) =
|
||||||
|
@ -4628,10 +4632,9 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
fn extend(&mut self, value: &mut Value, to: ty::Id) {
|
fn extend(&mut self, value: &mut Value, to: ty::Id) {
|
||||||
self.strip_ptr(value);
|
self.strip_ptr(value);
|
||||||
let mask = self.ci.nodes.new_const(to, (1i64 << (self.tys.size_of(value.ty) * 8)) - 1);
|
let inps = [VOID, value.id];
|
||||||
let inps = [VOID, value.id, mask];
|
|
||||||
*value =
|
*value =
|
||||||
self.ci.nodes.new_node_lit(to, Kind::BinOp { op: TokenKind::Band }, inps, self.tys);
|
self.ci.nodes.new_node_lit(to, Kind::UnOp { op: TokenKind::Number }, inps, self.tys);
|
||||||
value.ty = to;
|
value.ty = to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4810,6 +4813,7 @@ mod tests {
|
||||||
fb_driver;
|
fb_driver;
|
||||||
|
|
||||||
// Purely Testing Examples;
|
// Purely Testing Examples;
|
||||||
|
wrong_dead_code_elimination;
|
||||||
memory_swap;
|
memory_swap;
|
||||||
very_nested_loops;
|
very_nested_loops;
|
||||||
generic_type_mishap;
|
generic_type_mishap;
|
||||||
|
|
|
@ -564,7 +564,8 @@ impl TokenKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unop(&self, dst: ty::Id, src: ty::Id) -> Option<fn(u8, u8) -> EncodedInstr> {
|
fn unop(&self, dst: ty::Id, src: ty::Id) -> Option<fn(u8, u8) -> EncodedInstr> {
|
||||||
let src_idx = src.simple_size().unwrap().ilog2() as usize;
|
let src_idx =
|
||||||
|
src.simple_size().unwrap_or_else(|| panic!("{:?}", src.expand())).ilog2() as usize;
|
||||||
Some(match self {
|
Some(match self {
|
||||||
Self::Sub => [
|
Self::Sub => [
|
||||||
|a, b| sub8(a, reg::ZERO, b),
|
|a, b| sub8(a, reg::ZERO, b),
|
||||||
|
@ -583,6 +584,14 @@ impl TokenKind {
|
||||||
Self::Number if src.is_float() && dst.is_integer() => {
|
Self::Number if src.is_float() && dst.is_integer() => {
|
||||||
[|a, b| instrs::fti32(a, b, 1), |a, b| instrs::fti64(a, b, 1)][src_idx - 2]
|
[|a, b| instrs::fti32(a, b, 1), |a, b| instrs::fti64(a, b, 1)][src_idx - 2]
|
||||||
}
|
}
|
||||||
|
Self::Number if src.is_signed() && dst.is_integer() => {
|
||||||
|
[instrs::sxt8, instrs::sxt16, instrs::sxt32][src_idx]
|
||||||
|
}
|
||||||
|
Self::Number if (src.is_unsigned() || src == ty::Id::BOOL) && dst.is_integer() => [
|
||||||
|
|a, b| instrs::andi(a, b, 0xff),
|
||||||
|
|a, b| instrs::andi(a, b, 0xffff),
|
||||||
|
|a, b| instrs::andi(a, b, 0xffffffff),
|
||||||
|
][src_idx],
|
||||||
Self::Float if dst.is_float() && src.is_float() => {
|
Self::Float if dst.is_float() && src.is_float() => {
|
||||||
[instrs::fc32t64, |a, b| instrs::fc64t32(a, b, 1)][src_idx - 2]
|
[instrs::fc32t64, |a, b| instrs::fc64t32(a, b, 1)][src_idx - 2]
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,8 +241,23 @@ impl HbvmBackend {
|
||||||
}),
|
}),
|
||||||
Kind::UnOp { op } => {
|
Kind::UnOp { op } => {
|
||||||
let op = op
|
let op = op
|
||||||
.unop(node.ty, fuc.nodes[node.inputs[1]].ty)
|
.unop(
|
||||||
.expect("TODO: unary operator not supported");
|
node.ty,
|
||||||
|
tys.inner_of(fuc.nodes[node.inputs[1]].ty)
|
||||||
|
.unwrap_or(fuc.nodes[node.inputs[1]].ty),
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"TODO: unary operator not supported: {op} {} {}",
|
||||||
|
ty::Display::new(tys, files, node.ty),
|
||||||
|
ty::Display::new(
|
||||||
|
tys,
|
||||||
|
files,
|
||||||
|
tys.inner_of(fuc.nodes[node.inputs[1]].ty)
|
||||||
|
.unwrap_or(fuc.nodes[node.inputs[1]].ty)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
});
|
||||||
let &[dst, oper] = allocs else { unreachable!() };
|
let &[dst, oper] = allocs else { unreachable!() };
|
||||||
self.emit(op(atr(dst), atr(oper)));
|
self.emit(op(atr(dst), atr(oper)));
|
||||||
}
|
}
|
||||||
|
@ -264,8 +279,8 @@ impl HbvmBackend {
|
||||||
} else if let Some(against) = op.cmp_against() {
|
} else if let Some(against) = op.cmp_against() {
|
||||||
let op_ty = fuc.nodes[rh].ty;
|
let op_ty = fuc.nodes[rh].ty;
|
||||||
|
|
||||||
self.emit(extend(fuc.nodes[lh].ty, fuc.nodes[lh].ty.extend(), 1, 1));
|
//self.emit(extend(fuc.nodes[lh].ty, fuc.nodes[lh].ty.extend(), 1, 1));
|
||||||
self.emit(extend(fuc.nodes[rh].ty, fuc.nodes[rh].ty.extend(), 2, 2));
|
//self.emit(extend(fuc.nodes[rh].ty, fuc.nodes[rh].ty.extend(), 2, 2));
|
||||||
let &[dst, lhs, rhs] = allocs else { unreachable!() };
|
let &[dst, lhs, rhs] = allocs else { unreachable!() };
|
||||||
|
|
||||||
if op_ty.is_float() && matches!(op, TokenKind::Le | TokenKind::Ge) {
|
if op_ty.is_float() && matches!(op, TokenKind::Le | TokenKind::Ge) {
|
||||||
|
|
|
@ -11,17 +11,16 @@ main:
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
str_len:
|
str_len:
|
||||||
LI8 r6, 0b
|
LI64 r3, 0d
|
||||||
LI64 r1, 0d
|
CP r1, r3
|
||||||
2: LD r8, r2, 0a, 1h
|
2: LD r7, r2, 0a, 1h
|
||||||
ANDI r8, r8, 255d
|
ANDI r9, r7, 255d
|
||||||
ANDI r6, r6, 255d
|
JNE r9, r3, :0
|
||||||
JNE r8, r6, :0
|
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r2, r2, 1d
|
0: ADDI64 r2, r2, 1d
|
||||||
ADDI64 r1, r1, 1d
|
ADDI64 r1, r1, 1d
|
||||||
JMP :2
|
JMP :2
|
||||||
1: JALA r0, r31, 0a
|
1: JALA r0, r31, 0a
|
||||||
code size: 216
|
code size: 205
|
||||||
ret: 16
|
ret: 16
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,30 +1,29 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -12d
|
ADDI64 r254, r254, -12d
|
||||||
LI8 r1, 255b
|
|
||||||
ST r1, r254, 0a, 1h
|
|
||||||
LI8 r4, 0b
|
|
||||||
ST r4, r254, 1a, 1h
|
|
||||||
ST r4, r254, 2a, 1h
|
|
||||||
ST r1, r254, 3a, 1h
|
|
||||||
LI32 r9, 0w
|
|
||||||
ST r9, r254, 4a, 4h
|
|
||||||
LD r4, r254, 4a, 4h
|
|
||||||
LI32 r1, 2w
|
|
||||||
ST r1, r254, 8a, 4h
|
|
||||||
LD r5, r254, 8a, 4h
|
|
||||||
ANDI r5, r5, 4294967295d
|
|
||||||
ANDI r1, r1, 4294967295d
|
|
||||||
JEQ r5, r1, :0
|
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
|
LI8 r2, 255b
|
||||||
|
ST r2, r254, 0a, 1h
|
||||||
|
LI8 r5, 0b
|
||||||
|
ST r5, r254, 1a, 1h
|
||||||
|
ST r5, r254, 2a, 1h
|
||||||
|
ST r2, r254, 3a, 1h
|
||||||
|
LI32 r10, 0w
|
||||||
|
ST r10, r254, 4a, 4h
|
||||||
|
LD r8, r254, 4a, 4h
|
||||||
|
LI32 r2, 2w
|
||||||
|
ST r2, r254, 8a, 4h
|
||||||
|
LD r5, r254, 8a, 4h
|
||||||
|
LI64 r9, 2d
|
||||||
|
ANDI r10, r5, 4294967295d
|
||||||
|
JEQ r10, r9, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ANDI r4, r4, 4294967295d
|
0: ANDI r2, r8, 4294967295d
|
||||||
ANDI r9, r9, 4294967295d
|
JEQ r2, r1, :2
|
||||||
JEQ r4, r9, :2
|
|
||||||
LI64 r1, 64d
|
LI64 r1, 64d
|
||||||
JMP :1
|
JMP :1
|
||||||
2: LI64 r1, 512d
|
2: LI64 r1, 512d
|
||||||
1: ADDI64 r254, r254, 12d
|
1: ADDI64 r254, r254, 12d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 257
|
code size: 245
|
||||||
ret: 512
|
ret: 512
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
main:
|
main:
|
||||||
LI64 r2, 8d
|
LI64 r2, 8d
|
||||||
ECA
|
ECA
|
||||||
LI64 r10, 6d
|
LI64 r11, 6d
|
||||||
LRA r6, r0, :gb
|
LRA r6, r0, :gb
|
||||||
LI64 r9, 0d
|
LI64 r9, 0d
|
||||||
LD r11, r6, 0a, 8h
|
LD r10, r6, 0a, 8h
|
||||||
CMPU r12, r11, r9
|
CMPU r12, r10, r9
|
||||||
CMPUI r12, r12, 0d
|
CMPUI r12, r12, 0d
|
||||||
ORI r2, r12, 0d
|
ANDI r2, r12, 255d
|
||||||
ANDI r2, r2, 255d
|
OR r4, r2, r9
|
||||||
JNE r2, r0, :0
|
ANDI r4, r4, 255d
|
||||||
CP r7, r10
|
JNE r4, r0, :0
|
||||||
|
CP r9, r11
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r7, 1d
|
0: LI64 r9, 1d
|
||||||
1: SUB64 r1, r7, r10
|
1: SUB64 r1, r9, r11
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 142
|
code size: 146
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -122d
|
ADDI64 r254, r254, -138d
|
||||||
ST r31, r254, 26a, 96h
|
ST r31, r254, 26a, 112h
|
||||||
JAL r31, r0, :returner_fn
|
JAL r31, r0, :returner_fn
|
||||||
CP r32, r1
|
CP r32, r1
|
||||||
ADDI64 r1, r254, 2d
|
ADDI64 r1, r254, 2d
|
||||||
|
@ -9,31 +9,28 @@ main:
|
||||||
JAL r31, r0, :returner_cn
|
JAL r31, r0, :returner_cn
|
||||||
ST r1, r254, 0a, 2h
|
ST r1, r254, 0a, 2h
|
||||||
LI8 r34, 0b
|
LI8 r34, 0b
|
||||||
LI8 r35, 0b
|
|
||||||
LD r36, r254, 2a, 1h
|
|
||||||
CP r1, r32
|
CP r1, r32
|
||||||
ANDI r1, r1, 255d
|
CMPU r35, r1, r34
|
||||||
ANDI r34, r34, 255d
|
CMPUI r35, r35, 0d
|
||||||
CMPU r37, r1, r34
|
LI8 r36, 0b
|
||||||
CMPUI r37, r37, 0d
|
LD r37, r254, 2a, 1h
|
||||||
ANDI r36, r36, 255d
|
ANDI r38, r35, 255d
|
||||||
ANDI r35, r35, 255d
|
CMPU r32, r37, r36
|
||||||
CMPU r38, r36, r35
|
CMPUI r32, r32, 0d
|
||||||
CMPUI r38, r38, 0d
|
AND r39, r32, r38
|
||||||
LD r39, r254, 0a, 1h
|
LD r40, r254, 0a, 1h
|
||||||
AND r40, r38, r37
|
ANDI r41, r39, 255d
|
||||||
ANDI r39, r39, 255d
|
CMPU r42, r40, r36
|
||||||
ANDI r35, r35, 255d
|
CMPUI r42, r42, 0d
|
||||||
CMPU r41, r39, r35
|
AND r43, r42, r41
|
||||||
CMPUI r41, r41, 0d
|
ANDI r44, r43, 255d
|
||||||
AND r42, r41, r40
|
ANDI r44, r44, 255d
|
||||||
ANDI r42, r42, 255d
|
JNE r44, r0, :0
|
||||||
JNE r42, r0, :0
|
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r1, 1d
|
0: LI64 r1, 1d
|
||||||
1: LD r31, r254, 26a, 96h
|
1: LD r31, r254, 26a, 112h
|
||||||
ADDI64 r254, r254, 122d
|
ADDI64 r254, r254, 138d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
returner_bn:
|
returner_bn:
|
||||||
ADDI64 r254, r254, -24d
|
ADDI64 r254, r254, -24d
|
||||||
|
@ -60,6 +57,6 @@ returner_fn:
|
||||||
LD r1, r254, 0a, 0h
|
LD r1, r254, 0a, 0h
|
||||||
ORI r1, r1, 128d
|
ORI r1, r1, 128d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 546
|
code size: 513
|
||||||
ret: 1
|
ret: 1
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
31
lang/tests/son_tests_wrong_dead_code_elimination.txt
Normal file
31
lang/tests/son_tests_wrong_dead_code_elimination.txt
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -1d
|
||||||
|
LI64 r7, 0d
|
||||||
|
LI64 r5, 255d
|
||||||
|
LI8 r4, 1b
|
||||||
|
LI8 r6, 0b
|
||||||
|
ST r6, r254, 0a, 1h
|
||||||
|
2: LD r9, r254, 0a, 1h
|
||||||
|
AND r12, r9, r5
|
||||||
|
CMPU r2, r12, r5
|
||||||
|
CMPUI r2, r2, 0d
|
||||||
|
NOT r2, r2
|
||||||
|
CMPU r6, r12, r7
|
||||||
|
CMPUI r6, r6, 0d
|
||||||
|
NOT r6, r6
|
||||||
|
AND r8, r2, r5
|
||||||
|
AND r10, r6, r5
|
||||||
|
OR r11, r10, r8
|
||||||
|
ANDI r11, r11, 255d
|
||||||
|
JNE r11, r0, :0
|
||||||
|
JMP :1
|
||||||
|
0: SUB8 r4, r0, r4
|
||||||
|
1: ADD8 r8, r9, r4
|
||||||
|
ST r8, r254, 0a, 1h
|
||||||
|
JMP :2
|
||||||
|
ADDI64 r254, r254, 1d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
timed out
|
||||||
|
code size: 192
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
Loading…
Reference in a new issue