fixing very sneaky bug
This commit is contained in:
parent
e8f1d2af8c
commit
2e36f32ae0
|
@ -593,6 +593,59 @@ main := fn(): uint {
|
||||||
|
|
||||||
### Purely Testing Examples
|
### Purely Testing Examples
|
||||||
|
|
||||||
|
#### inlining_issues
|
||||||
|
```hb
|
||||||
|
main := fn(): void {
|
||||||
|
@use("main.hb").put_filled_rect(.(&.(0), 100, 100), .(0, 0), .(0, 0), .(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
// in module: memory.hb
|
||||||
|
|
||||||
|
SetMsg := packed struct {a: u8, count: u32, size: u32, src: ^u8, dest: ^u8}
|
||||||
|
set := fn($Expr: type, src: ^Expr, dest: ^Expr, count: uint): void {
|
||||||
|
return @eca(8, 2, &SetMsg.(5, @intcast(count), @intcast(@sizeof(Expr)), @bitcast(src), @bitcast(dest)), @sizeof(SetMsg))
|
||||||
|
}
|
||||||
|
|
||||||
|
// in module: main.hb
|
||||||
|
|
||||||
|
Color := struct {r: u8}
|
||||||
|
|
||||||
|
Vec2 := fn($Ty: type): type return struct {x: Ty, y: Ty}
|
||||||
|
|
||||||
|
memory := @use("memory.hb")
|
||||||
|
|
||||||
|
Surface := struct {
|
||||||
|
buf: ^Color,
|
||||||
|
width: uint,
|
||||||
|
height: uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
indexptr := fn(surface: Surface, x: uint, y: uint): ^Color {
|
||||||
|
return surface.buf + y * surface.width + x
|
||||||
|
}
|
||||||
|
|
||||||
|
put_filled_rect := fn(surface: Surface, pos: Vec2(uint), tr: Vec2(uint), color: Color): void {
|
||||||
|
top_start_idx := @inline(indexptr, surface, pos.x, pos.y)
|
||||||
|
bottom_start_idx := @inline(indexptr, surface, pos.x, pos.y + tr.y - 1)
|
||||||
|
rows_to_fill := tr.y
|
||||||
|
|
||||||
|
loop if rows_to_fill <= 1 break else {
|
||||||
|
@inline(memory.set, Color, &color, top_start_idx, @bitcast(tr.x))
|
||||||
|
@inline(memory.set, Color, &color, bottom_start_idx, @bitcast(tr.x))
|
||||||
|
|
||||||
|
top_start_idx += surface.width
|
||||||
|
bottom_start_idx -= surface.width
|
||||||
|
rows_to_fill -= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if rows_to_fill == 1 {
|
||||||
|
@inline(memory.set, Color, &color, top_start_idx, @bitcast(tr.x))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
#### only_break_loop
|
#### only_break_loop
|
||||||
```hb
|
```hb
|
||||||
memory := @use("memory.hb")
|
memory := @use("memory.hb")
|
||||||
|
|
121
lang/src/son.rs
121
lang/src/son.rs
|
@ -39,7 +39,7 @@ const GLOBAL_ACLASS: usize = 1;
|
||||||
pub mod hbvm;
|
pub mod hbvm;
|
||||||
|
|
||||||
type Nid = u16;
|
type Nid = u16;
|
||||||
type AClassId = u16;
|
type AClassId = i16;
|
||||||
|
|
||||||
type Lookup = crate::ctx_map::CtxMap<Nid>;
|
type Lookup = crate::ctx_map::CtxMap<Nid>;
|
||||||
|
|
||||||
|
@ -410,6 +410,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind(&mut self, from: Nid, to: Nid) {
|
fn bind(&mut self, from: Nid, to: Nid) {
|
||||||
|
debug_assert_ne!(to, 0);
|
||||||
self[from].outputs.push(to);
|
self[from].outputs.push(to);
|
||||||
self[to].inputs.push(from);
|
self[to].inputs.push(from);
|
||||||
}
|
}
|
||||||
|
@ -512,17 +513,16 @@ impl Nodes {
|
||||||
if node.ty != ty::Id::VOID {
|
if node.ty != ty::Id::VOID {
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
" node{i}[label=\"{i} {} {} {} {}\" color={color}]",
|
" node{i}[label=\"{i} {} {} {}\" color={color}]",
|
||||||
node.kind,
|
node.kind,
|
||||||
ty::Display::new(tys, files, node.ty),
|
ty::Display::new(tys, files, node.ty),
|
||||||
node.aclass,
|
node.aclass,
|
||||||
node.mem,
|
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
" node{i}[label=\"{i} {} {} {}\" color={color}]",
|
" node{i}[label=\"{i} {} {}\" color={color}]",
|
||||||
node.kind, node.aclass, node.mem,
|
node.kind, node.aclass,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,7 +763,21 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aclass_index(&self, region: Nid) -> (usize, Nid) {
|
pub fn aclass_index(&self, region: Nid) -> (usize, Nid) {
|
||||||
(self[region].aclass as _, self[region].mem)
|
if self[region].aclass >= 0 {
|
||||||
|
(self[region].aclass as _, region)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
self[self[region].aclass.unsigned_abs() - 1].aclass as _,
|
||||||
|
self[region].aclass.unsigned_abs() - 1,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pass_aclass(&mut self, from: Nid, to: Nid) {
|
||||||
|
debug_assert!(self[from].aclass >= 0);
|
||||||
|
if from != to {
|
||||||
|
self[to].aclass = -(from as AClassId + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peephole(&mut self, target: Nid) -> Option<Nid> {
|
fn peephole(&mut self, target: Nid) -> Option<Nid> {
|
||||||
|
@ -1335,7 +1349,7 @@ impl Nodes {
|
||||||
write!(out, " {node:>2}-c{:>2}: ", self[node].ralloc_backref)?;
|
write!(out, " {node:>2}-c{:>2}: ", self[node].ralloc_backref)?;
|
||||||
}
|
}
|
||||||
match self[node].kind {
|
match self[node].kind {
|
||||||
Kind::Assert { .. } | Kind::Start => unreachable!(),
|
Kind::Assert { .. } | Kind::Start => unreachable!("{} {out}", self[node].kind),
|
||||||
Kind::End => return Ok(()),
|
Kind::End => return Ok(()),
|
||||||
Kind::If => write!(out, " if: "),
|
Kind::If => write!(out, " if: "),
|
||||||
Kind::Region | Kind::Loop => writeln!(out, " goto: {node}"),
|
Kind::Region | Kind::Loop => writeln!(out, " goto: {node}"),
|
||||||
|
@ -1499,6 +1513,10 @@ impl Nodes {
|
||||||
log::error!("is unreachable but still present {id} {:?}", node.kind);
|
log::error!("is unreachable but still present {id} {:?}", node.kind);
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
if node.outputs.contains(&id) && !matches!(node.kind, Kind::Loop | Kind::End) {
|
||||||
|
log::error!("node depends on it self and its not a loop {id} {:?}", node);
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if failed {
|
if failed {
|
||||||
|
@ -1522,8 +1540,8 @@ impl Nodes {
|
||||||
let lvalue = lvar.value();
|
let lvalue = lvar.value();
|
||||||
let inps = [node, lvalue, VOID];
|
let inps = [node, lvalue, VOID];
|
||||||
lvar.set_value(self.new_node_nop(lvar.ty, Kind::Phi, inps), self);
|
lvar.set_value(self.new_node_nop(lvar.ty, Kind::Phi, inps), self);
|
||||||
self[lvar.value()].aclass = self[lvalue].aclass;
|
|
||||||
self[lvar.value()].mem = self[lvalue].mem;
|
self.pass_aclass(self.aclass_index(lvalue).1, lvar.value());
|
||||||
}
|
}
|
||||||
var.set_value(lvar.value(), self);
|
var.set_value(lvar.value(), self);
|
||||||
}
|
}
|
||||||
|
@ -1728,7 +1746,6 @@ pub struct Node {
|
||||||
lock_rc: LockRc,
|
lock_rc: LockRc,
|
||||||
loop_depth: LoopDepth,
|
loop_depth: LoopDepth,
|
||||||
aclass: AClassId,
|
aclass: AClassId,
|
||||||
mem: Nid,
|
|
||||||
antidep: Nid,
|
antidep: Nid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2254,7 +2271,6 @@ impl<'a> Codegen<'a> {
|
||||||
fn new_stack(&mut self, ty: ty::Id) -> Nid {
|
fn new_stack(&mut self, ty: ty::Id) -> Nid {
|
||||||
let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]);
|
let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]);
|
||||||
self.ci.nodes[stck].aclass = self.ci.scope.aclasses.len() as _;
|
self.ci.nodes[stck].aclass = self.ci.scope.aclasses.len() as _;
|
||||||
self.ci.nodes[stck].mem = stck;
|
|
||||||
self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes));
|
self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes));
|
||||||
stck
|
stck
|
||||||
}
|
}
|
||||||
|
@ -2271,25 +2287,46 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let (value_index, value_region) = self.ci.nodes.aclass_index(value);
|
let (value_index, value_region) = self.ci.nodes.aclass_index(value);
|
||||||
if value_index != 0 {
|
if value_index != 0 {
|
||||||
// simply switch the class to the default one
|
self.ci.nodes[value_region].aclass = 0;
|
||||||
let aclass = &mut self.ci.scope.aclasses[value_index];
|
//// simply switch the class to the default one
|
||||||
self.ci.nodes.load_loop_aclass(value_index, aclass, &mut self.ci.loops);
|
//let aclass = &mut self.ci.scope.aclasses[value_index];
|
||||||
let last_store = aclass.last_store.get();
|
//self.ci.nodes.load_loop_aclass(value_index, aclass, &mut self.ci.loops);
|
||||||
let mut cursor = last_store;
|
//let last_store = aclass.last_store.get();
|
||||||
let mut first_store = cursor;
|
//let mut cursor = last_store;
|
||||||
while cursor != MEM {
|
//let mut first_store = cursor;
|
||||||
first_store = cursor;
|
//while cursor != MEM {
|
||||||
cursor = self.ci.nodes[cursor].inputs[3];
|
// first_store = cursor;
|
||||||
}
|
// debug_assert_matches!(
|
||||||
|
// self.ci.nodes[cursor].kind,
|
||||||
|
// Kind::Stre,
|
||||||
|
// "{:?}",
|
||||||
|
// self.ci.nodes[cursor]
|
||||||
|
// );
|
||||||
|
// cursor = self.ci.nodes[cursor].inputs[3];
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if last_store != MEM {
|
||||||
|
// let base_class = self.ci.scope.aclasses[0].last_store.get();
|
||||||
|
// if base_class != MEM {
|
||||||
|
// self.ci.nodes.modify_input(first_store, 3, base_class);
|
||||||
|
// }
|
||||||
|
// self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes);
|
||||||
|
//}
|
||||||
|
|
||||||
|
self.ci.nodes.load_loop_aclass(0, &mut self.ci.scope.aclasses[0], &mut self.ci.loops);
|
||||||
|
self.ci.nodes.load_loop_aclass(
|
||||||
|
value_index,
|
||||||
|
&mut self.ci.scope.aclasses[value_index],
|
||||||
|
&mut self.ci.loops,
|
||||||
|
);
|
||||||
|
let base_class = self.ci.scope.aclasses[0].last_store.get();
|
||||||
|
let last_store = self.ci.scope.aclasses[value_index].last_store.get();
|
||||||
|
if base_class != MEM && last_store != MEM {
|
||||||
|
self.ci.nodes.bind(base_class, last_store);
|
||||||
|
}
|
||||||
if last_store != MEM {
|
if last_store != MEM {
|
||||||
let base_class = self.ci.scope.aclasses[0].last_store.get();
|
|
||||||
if base_class != MEM {
|
|
||||||
self.ci.nodes.modify_input(first_store, 3, base_class);
|
|
||||||
}
|
|
||||||
self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes);
|
self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes);
|
||||||
}
|
}
|
||||||
self.ci.nodes[value_region].aclass = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = self.ci.nodes.aclass_index(region);
|
let (index, _) = self.ci.nodes.aclass_index(region);
|
||||||
|
@ -2485,7 +2522,9 @@ impl<'a> Codegen<'a> {
|
||||||
let mut inps = Vc::from([self.ci.ctrl.get(), value.id]);
|
let mut inps = Vc::from([self.ci.ctrl.get(), value.id]);
|
||||||
for (i, aclass) in self.ci.scope.aclasses.iter_mut().enumerate() {
|
for (i, aclass) in self.ci.scope.aclasses.iter_mut().enumerate() {
|
||||||
self.ci.nodes.load_loop_aclass(i, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(i, aclass, &mut self.ci.loops);
|
||||||
inps.push(aclass.last_store.get());
|
if aclass.last_store.get() != MEM {
|
||||||
|
inps.push(aclass.last_store.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.ctrl.set(
|
self.ci.ctrl.set(
|
||||||
|
@ -2729,12 +2768,11 @@ impl<'a> Codegen<'a> {
|
||||||
let mut rhs = rhs?;
|
let mut rhs = rhs?;
|
||||||
self.strip_var(&mut rhs);
|
self.strip_var(&mut rhs);
|
||||||
self.unwrap_opt(right.pos(), &mut rhs);
|
self.unwrap_opt(right.pos(), &mut rhs);
|
||||||
let (ty, aclass, mem) = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
let (ty, aclass) = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
||||||
let inps = [VOID, lhs.id, rhs.id];
|
let inps = [VOID, lhs.id, rhs.id];
|
||||||
let bop =
|
let bop =
|
||||||
self.ci.nodes.new_node_lit(ty.bin_ret(op), Kind::BinOp { op }, inps);
|
self.ci.nodes.new_node_lit(ty.bin_ret(op), Kind::BinOp { op }, inps);
|
||||||
self.ci.nodes[bop.id].aclass = aclass as _;
|
self.ci.nodes.pass_aclass(aclass, bop.id);
|
||||||
self.ci.nodes[bop.id].mem = mem;
|
|
||||||
Some(bop)
|
Some(bop)
|
||||||
}
|
}
|
||||||
ty::Kind::Struct(s) if op.is_homogenous() => {
|
ty::Kind::Struct(s) if op.is_homogenous() => {
|
||||||
|
@ -2784,12 +2822,11 @@ impl<'a> Codegen<'a> {
|
||||||
let inps = [VOID, idx.id, size];
|
let inps = [VOID, idx.id, size];
|
||||||
let offset =
|
let offset =
|
||||||
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps);
|
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps);
|
||||||
let (aclass, mem) = self.ci.nodes.aclass_index(bs.id);
|
let aclass = self.ci.nodes.aclass_index(bs.id).1;
|
||||||
let inps = [VOID, bs.id, offset];
|
let inps = [VOID, bs.id, offset];
|
||||||
let ptr =
|
let ptr =
|
||||||
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
||||||
self.ci.nodes[ptr].aclass = aclass as _;
|
self.ci.nodes.pass_aclass(aclass, ptr);
|
||||||
self.ci.nodes[ptr].mem = mem;
|
|
||||||
|
|
||||||
Some(Value::ptr(ptr).ty(elem))
|
Some(Value::ptr(ptr).ty(elem))
|
||||||
}
|
}
|
||||||
|
@ -3896,11 +3933,10 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let off = self.ci.nodes.new_const(ty::Id::INT, off);
|
let off = self.ci.nodes.new_const(ty::Id::INT, off);
|
||||||
let (aclass, mem) = self.ci.nodes.aclass_index(val);
|
let aclass = self.ci.nodes.aclass_index(val).1;
|
||||||
let inps = [VOID, val, off];
|
let inps = [VOID, val, off];
|
||||||
let seted = self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
let seted = self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
||||||
self.ci.nodes[seted].aclass = aclass as _;
|
self.ci.nodes.pass_aclass(aclass, seted);
|
||||||
self.ci.nodes[seted].mem = mem;
|
|
||||||
seted
|
seted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4089,7 +4125,7 @@ impl<'a> Codegen<'a> {
|
||||||
lhs: &mut Value,
|
lhs: &mut Value,
|
||||||
rhs: &mut Value,
|
rhs: &mut Value,
|
||||||
op: TokenKind,
|
op: TokenKind,
|
||||||
) -> (ty::Id, usize, Nid) {
|
) -> (ty::Id, Nid) {
|
||||||
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty) {
|
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty) {
|
||||||
let to_correct = if lhs.ty != upcasted {
|
let to_correct = if lhs.ty != upcasted {
|
||||||
Some((lhs, rhs))
|
Some((lhs, rhs))
|
||||||
|
@ -4111,20 +4147,16 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes.new_node(upcasted, Kind::BinOp { op: TokenKind::Mul }, [
|
self.ci.nodes.new_node(upcasted, Kind::BinOp { op: TokenKind::Mul }, [
|
||||||
VOID, oper.id, cnst,
|
VOID, oper.id, cnst,
|
||||||
]);
|
]);
|
||||||
return (
|
return (upcasted, self.ci.nodes.aclass_index(other.id).1);
|
||||||
upcasted,
|
|
||||||
self.ci.nodes[other.id].aclass as _,
|
|
||||||
self.ci.nodes[other.id].mem,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(upcasted, DEFAULT_ACLASS, VOID)
|
(upcasted, VOID)
|
||||||
} else {
|
} else {
|
||||||
let ty = self.ty_display(lhs.ty);
|
let ty = self.ty_display(lhs.ty);
|
||||||
let expected = self.ty_display(rhs.ty);
|
let expected = self.ty_display(rhs.ty);
|
||||||
self.report(pos, fa!("'{ty} {op} {expected}' is not supported"));
|
self.report(pos, fa!("'{ty} {op} {expected}' is not supported"));
|
||||||
(ty::Id::NEVER, DEFAULT_ACLASS, VOID)
|
(ty::Id::NEVER, VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4448,6 +4480,7 @@ mod tests {
|
||||||
fb_driver;
|
fb_driver;
|
||||||
|
|
||||||
// Purely Testing Examples;
|
// Purely Testing Examples;
|
||||||
|
inlining_issues;
|
||||||
null_check_test;
|
null_check_test;
|
||||||
only_break_loop;
|
only_break_loop;
|
||||||
reading_idk;
|
reading_idk;
|
||||||
|
|
|
@ -395,6 +395,9 @@ impl ItemCtx {
|
||||||
PLoc::WideReg(rg, size) => (rg, size),
|
PLoc::WideReg(rg, size) => (rg, size),
|
||||||
PLoc::Ref(..) | PLoc::Reg(..) => continue,
|
PLoc::Ref(..) | PLoc::Reg(..) => continue,
|
||||||
};
|
};
|
||||||
|
if size > 8 {
|
||||||
|
allocs.next().unwrap();
|
||||||
|
}
|
||||||
self.emit(instrs::ld(rg, atr(arg), 0, size));
|
self.emit(instrs::ld(rg, atr(arg), 0, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,7 +949,7 @@ impl<'a> Function<'a> {
|
||||||
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
PLoc::WideReg(..) | PLoc::Reg(..) => {
|
PLoc::WideReg(r, size) | PLoc::Reg(r, size) => {
|
||||||
loop {
|
loop {
|
||||||
match self.nodes[i].kind {
|
match self.nodes[i].kind {
|
||||||
Kind::Stre { .. } => i = self.nodes[i].inputs[2],
|
Kind::Stre { .. } => i = self.nodes[i].inputs[2],
|
||||||
|
@ -956,7 +959,16 @@ impl<'a> Function<'a> {
|
||||||
debug_assert_ne!(i, 0);
|
debug_assert_ne!(i, 0);
|
||||||
}
|
}
|
||||||
debug_assert!(i != 0);
|
debug_assert!(i != 0);
|
||||||
ops.push(self.urg(i));
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
|
self.rg(i),
|
||||||
|
regalloc2::PReg::new(r as _, regalloc2::RegClass::Int),
|
||||||
|
));
|
||||||
|
if size > 8 {
|
||||||
|
ops.push(regalloc2::Operand::reg_fixed_use(
|
||||||
|
self.rg(i),
|
||||||
|
regalloc2::PReg::new((r + 1) as _, regalloc2::RegClass::Int),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PLoc::Ref(r, _) => {
|
PLoc::Ref(r, _) => {
|
||||||
loop {
|
loop {
|
||||||
|
@ -1044,6 +1056,7 @@ impl<'a> Function<'a> {
|
||||||
}
|
}
|
||||||
Kind::Stre if node.inputs[1] == VOID => self.nodes.lock(nid),
|
Kind::Stre if node.inputs[1] == VOID => self.nodes.lock(nid),
|
||||||
Kind::Stre => {
|
Kind::Stre => {
|
||||||
|
debug_assert_ne!(self.tys.size_of(node.ty), 0);
|
||||||
let mut region = node.inputs[2];
|
let mut region = node.inputs[2];
|
||||||
if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
|
if self.nodes[region].kind == (Kind::BinOp { op: TokenKind::Add })
|
||||||
&& self.nodes.is_const(self.nodes[region].inputs[2])
|
&& self.nodes.is_const(self.nodes[region].inputs[2])
|
||||||
|
@ -1597,6 +1610,7 @@ pub fn test_run_vm(out: &[u8], output: &mut String) {
|
||||||
unsafe { alloc::alloc::dealloc(ptr as *mut u8, layout) };
|
unsafe { alloc::alloc::dealloc(ptr as *mut u8, layout) };
|
||||||
}
|
}
|
||||||
3 => vm.write_reg(1, 42),
|
3 => vm.write_reg(1, 42),
|
||||||
|
8 => {}
|
||||||
unknown => unreachable!("unknown ecall: {unknown:?}"),
|
unknown => unreachable!("unknown ecall: {unknown:?}"),
|
||||||
},
|
},
|
||||||
Ok(hbvm::VmRunOk::Timer) => {
|
Ok(hbvm::VmRunOk::Timer) => {
|
||||||
|
|
|
@ -8,12 +8,13 @@ main:
|
||||||
LI64 r6, 6d
|
LI64 r6, 6d
|
||||||
LI64 r5, 5d
|
LI64 r5, 5d
|
||||||
LI64 r2, 1d
|
LI64 r2, 1d
|
||||||
LD r3, r4, 0a, 16h
|
CP r3, r4
|
||||||
|
LD r3, r3, 0a, 16h
|
||||||
ECA
|
ECA
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
ev: Ecall
|
ev: Ecall
|
||||||
code size: 152
|
code size: 155
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -24,14 +24,14 @@ scalar_values:
|
||||||
structs:
|
structs:
|
||||||
ADDI64 r254, r254, -32d
|
ADDI64 r254, r254, -32d
|
||||||
LI64 r1, 5d
|
LI64 r1, 5d
|
||||||
ST r1, r254, 0a, 8h
|
ST r1, r254, 16a, 8h
|
||||||
ST r1, r254, 8a, 8h
|
ST r1, r254, 24a, 8h
|
||||||
LD r5, r254, 0a, 8h
|
LD r5, r254, 16a, 8h
|
||||||
ADDI64 r7, r5, 15d
|
ADDI64 r7, r5, 15d
|
||||||
ST r7, r254, 16a, 8h
|
ST r7, r254, 0a, 8h
|
||||||
LI64 r10, 20d
|
LI64 r10, 20d
|
||||||
ST r10, r254, 24a, 8h
|
ST r10, r254, 8a, 8h
|
||||||
LD r1, r254, 16a, 8h
|
LD r1, r254, 0a, 8h
|
||||||
SUB64 r1, r1, r10
|
SUB64 r1, r1, r10
|
||||||
ADDI64 r254, r254, 32d
|
ADDI64 r254, r254, 32d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
109
lang/tests/son_tests_inlining_issues.txt
Normal file
109
lang/tests/son_tests_inlining_issues.txt
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -66d
|
||||||
|
ST r31, r254, 58a, 8h
|
||||||
|
ADDI64 r3, r254, 33d
|
||||||
|
ADDI64 r2, r254, 34d
|
||||||
|
ADDI64 r6, r254, 1d
|
||||||
|
LI64 r9, 0d
|
||||||
|
ADDI64 r4, r254, 17d
|
||||||
|
ST r3, r254, 34a, 8h
|
||||||
|
LI64 r10, 100d
|
||||||
|
ADDI64 r7, r254, 0d
|
||||||
|
LI8 r5, 1b
|
||||||
|
ST r9, r254, 1a, 8h
|
||||||
|
ST r9, r254, 17a, 8h
|
||||||
|
ST r10, r254, 42a, 8h
|
||||||
|
LI8 r3, 0b
|
||||||
|
ST r5, r254, 0a, 1h
|
||||||
|
ST r9, r254, 9a, 8h
|
||||||
|
ST r9, r254, 25a, 8h
|
||||||
|
ST r10, r254, 50a, 8h
|
||||||
|
ST r3, r254, 33a, 1h
|
||||||
|
CP r3, r4
|
||||||
|
CP r5, r6
|
||||||
|
LD r3, r3, 0a, 16h
|
||||||
|
LD r5, r5, 0a, 16h
|
||||||
|
LD r7, r7, 0a, 1h
|
||||||
|
JAL r31, r0, :put_filled_rect
|
||||||
|
LD r31, r254, 58a, 8h
|
||||||
|
ADDI64 r254, r254, 66d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
put_filled_rect:
|
||||||
|
ADDI64 r254, r254, -212d
|
||||||
|
ST r32, r254, 108a, 104h
|
||||||
|
ST r3, r254, 92a, 16h
|
||||||
|
ADDI64 r3, r254, 92d
|
||||||
|
ST r5, r254, 76a, 16h
|
||||||
|
ADDI64 r5, r254, 76d
|
||||||
|
ST r7, r254, 75a, 1h
|
||||||
|
ADDI64 r7, r254, 75d
|
||||||
|
LI64 r8, 25d
|
||||||
|
LI64 r32, 2d
|
||||||
|
LI64 r6, 8d
|
||||||
|
ADDI64 r33, r254, 25d
|
||||||
|
ADDI64 r34, r254, 50d
|
||||||
|
LI8 r35, 5b
|
||||||
|
ST r35, r254, 25a, 1h
|
||||||
|
LD r36, r5, 0a, 8h
|
||||||
|
ST r36, r254, 26a, 4h
|
||||||
|
LI64 r37, 1d
|
||||||
|
ST r37, r254, 30a, 4h
|
||||||
|
ST r7, r254, 34a, 8h
|
||||||
|
ST r35, r254, 50a, 1h
|
||||||
|
ST r36, r254, 51a, 4h
|
||||||
|
ST r37, r254, 55a, 4h
|
||||||
|
ST r7, r254, 59a, 8h
|
||||||
|
CP r38, r7
|
||||||
|
LD r7, r3, 8a, 8h
|
||||||
|
LD r39, r5, 8a, 8h
|
||||||
|
ADD64 r11, r39, r7
|
||||||
|
SUB64 r4, r11, r37
|
||||||
|
LD r40, r2, 8a, 8h
|
||||||
|
MUL64 r5, r40, r4
|
||||||
|
LD r9, r2, 0a, 8h
|
||||||
|
ADD64 r10, r9, r5
|
||||||
|
LD r2, r3, 0a, 8h
|
||||||
|
ADD64 r41, r2, r10
|
||||||
|
MUL64 r3, r40, r7
|
||||||
|
ADD64 r4, r9, r3
|
||||||
|
ADD64 r42, r2, r4
|
||||||
|
3: JGTU r39, r37, :0
|
||||||
|
JNE r39, r37, :1
|
||||||
|
ADDI64 r4, r254, 0d
|
||||||
|
ST r35, r254, 0a, 1h
|
||||||
|
ST r36, r254, 1a, 4h
|
||||||
|
ST r37, r254, 5a, 4h
|
||||||
|
ST r38, r254, 9a, 8h
|
||||||
|
ST r42, r254, 17a, 8h
|
||||||
|
CP r2, r6
|
||||||
|
CP r3, r32
|
||||||
|
CP r5, r8
|
||||||
|
ECA
|
||||||
|
JMP :1
|
||||||
|
1: JMP :2
|
||||||
|
0: CP r3, r32
|
||||||
|
CP r43, r6
|
||||||
|
CP r44, r8
|
||||||
|
ST r42, r254, 67a, 8h
|
||||||
|
CP r2, r43
|
||||||
|
CP r4, r34
|
||||||
|
CP r5, r44
|
||||||
|
ECA
|
||||||
|
ST r41, r254, 42a, 8h
|
||||||
|
CP r2, r43
|
||||||
|
CP r3, r32
|
||||||
|
CP r4, r33
|
||||||
|
CP r5, r44
|
||||||
|
ECA
|
||||||
|
ADD64 r42, r40, r42
|
||||||
|
SUB64 r41, r41, r40
|
||||||
|
SUB64 r39, r39, r32
|
||||||
|
CP r6, r43
|
||||||
|
CP r8, r44
|
||||||
|
JMP :3
|
||||||
|
2: LD r32, r254, 108a, 104h
|
||||||
|
ADDI64 r254, r254, 212d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 917
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -20,12 +20,12 @@ main:
|
||||||
LI8 r35, 1b
|
LI8 r35, 1b
|
||||||
ANDI r1, r1, 255d
|
ANDI r1, r1, 255d
|
||||||
JNE r1, r0, :4
|
JNE r1, r0, :4
|
||||||
ST r35, r254, 56a, 1h
|
ST r35, r254, 40a, 1h
|
||||||
LD r9, r33, 0a, 8h
|
LD r9, r33, 0a, 8h
|
||||||
ST r9, r254, 64a, 8h
|
ST r9, r254, 48a, 8h
|
||||||
JMP :5
|
JMP :5
|
||||||
4: ST r34, r254, 56a, 1h
|
4: ST r34, r254, 40a, 1h
|
||||||
5: LD r6, r254, 56a, 1h
|
5: LD r6, r254, 40a, 1h
|
||||||
ANDI r6, r6, 255d
|
ANDI r6, r6, 255d
|
||||||
ANDI r34, r34, 255d
|
ANDI r34, r34, 255d
|
||||||
JEQ r6, r34, :6
|
JEQ r6, r34, :6
|
||||||
|
@ -48,34 +48,34 @@ main:
|
||||||
LI64 r37, 1d
|
LI64 r37, 1d
|
||||||
ANDI r1, r1, 255d
|
ANDI r1, r1, 255d
|
||||||
JNE r1, r0, :10
|
JNE r1, r0, :10
|
||||||
ST r3, r254, 16a, 8h
|
ST r3, r254, 0a, 8h
|
||||||
JMP :11
|
JMP :11
|
||||||
10: ST r32, r254, 16a, 8h
|
10: ST r32, r254, 0a, 8h
|
||||||
ST r37, r254, 24a, 8h
|
ST r37, r254, 8a, 8h
|
||||||
ST r37, r254, 72a, 8h
|
ST r37, r254, 72a, 8h
|
||||||
11: LD r2, r254, 16a, 8h
|
11: LD r2, r254, 0a, 8h
|
||||||
JNE r2, r3, :12
|
JNE r2, r3, :12
|
||||||
LI64 r1, 34d
|
LI64 r1, 34d
|
||||||
JMP :3
|
JMP :3
|
||||||
12: JAL r31, r0, :decide
|
12: JAL r31, r0, :decide
|
||||||
ADDI64 r10, r254, 32d
|
ADDI64 r10, r254, 16d
|
||||||
ANDI r1, r1, 255d
|
ANDI r1, r1, 255d
|
||||||
JNE r1, r0, :13
|
JNE r1, r0, :13
|
||||||
ADDI64 r11, r254, 0d
|
ADDI64 r11, r254, 56d
|
||||||
ST r32, r254, 0a, 8h
|
ST r32, r254, 56a, 8h
|
||||||
ST r37, r254, 8a, 8h
|
ST r37, r254, 64a, 8h
|
||||||
ST r35, r254, 32a, 1h
|
ST r35, r254, 16a, 1h
|
||||||
ADDI64 r12, r10, 8d
|
ADDI64 r12, r10, 8d
|
||||||
BMC r11, r12, 16h
|
BMC r11, r12, 16h
|
||||||
JMP :14
|
JMP :14
|
||||||
13: ST r34, r254, 32a, 1h
|
13: ST r34, r254, 16a, 1h
|
||||||
14: LD r11, r254, 32a, 1h
|
14: LD r11, r254, 16a, 1h
|
||||||
ANDI r11, r11, 255d
|
ANDI r11, r11, 255d
|
||||||
ANDI r34, r34, 255d
|
ANDI r34, r34, 255d
|
||||||
JEQ r11, r34, :15
|
JEQ r11, r34, :15
|
||||||
LI64 r1, 420d
|
LI64 r1, 420d
|
||||||
JMP :3
|
JMP :3
|
||||||
15: LD r5, r254, 16a, 8h
|
15: LD r5, r254, 0a, 8h
|
||||||
LD r7, r5, 0a, 8h
|
LD r7, r5, 0a, 8h
|
||||||
ANDI r9, r36, 65535d
|
ANDI r9, r36, 65535d
|
||||||
SUB64 r1, r9, r7
|
SUB64 r1, r9, r7
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -56d
|
ADDI64 r254, r254, -56d
|
||||||
ST r31, r254, 32a, 24h
|
ST r31, r254, 32a, 24h
|
||||||
LI64 r3, 4d
|
LI64 r2, 4d
|
||||||
ADDI64 r2, r254, 16d
|
ADDI64 r4, r254, 16d
|
||||||
ST r3, r254, 16a, 8h
|
ST r2, r254, 16a, 8h
|
||||||
LI64 r32, 3d
|
LI64 r32, 3d
|
||||||
ST r32, r254, 24a, 8h
|
ST r32, r254, 24a, 8h
|
||||||
ADDI64 r33, r254, 0d
|
ADDI64 r33, r254, 0d
|
||||||
LD r3, r2, 0a, 16h
|
CP r3, r4
|
||||||
|
LD r3, r3, 0a, 16h
|
||||||
JAL r31, r0, :odher_pass
|
JAL r31, r0, :odher_pass
|
||||||
ST r1, r254, 0a, 16h
|
ST r1, r254, 0a, 16h
|
||||||
LD r2, r254, 8a, 8h
|
LD r2, r254, 8a, 8h
|
||||||
|
@ -29,6 +30,6 @@ odher_pass:
|
||||||
pass:
|
pass:
|
||||||
LD r1, r2, 0a, 8h
|
LD r1, r2, 0a, 8h
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 305
|
code size: 308
|
||||||
ret: 4
|
ret: 4
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue