more tests work now

This commit is contained in:
mlokr 2024-09-06 16:11:57 +02:00
parent 4bcab25231
commit b404e5b86d
No known key found for this signature in database
GPG key ID: DEA147DDEE644993
5 changed files with 179 additions and 34 deletions

View file

@ -452,10 +452,10 @@ main := fn(): int {
loop {
if x <= height + 1 {
set_pixel(x, y, width)
_d := set_pixel(x, y, width)
x += 1
} else {
set_pixel(x, y, width)
_d := set_pixel(x, y, width)
x = 0
y += 1
}

View file

@ -8,7 +8,7 @@ use {
parser::{self, find_symbol, idfl, CtorField, Expr, ExprRef, FileId, Pos},
HashMap,
},
std::{collections::BTreeMap, fmt::Display, ops::Range, rc::Rc, usize},
std::{collections::BTreeMap, fmt::Display, ops::Range, rc::Rc},
};
type Offset = u32;
@ -3429,6 +3429,7 @@ mod tests {
use {
super::parser,
crate::{codegen::LoggedMem, log, parser::FileId},
core::panic,
std::io,
};
@ -3536,6 +3537,10 @@ mod tests {
3 => vm.write_reg(1, 42),
unknown => unreachable!("unknown ecall: {unknown:?}"),
},
Ok(hbvm::VmRunOk::Timer) => {
writeln!(output, "timed out").unwrap();
break Ok(());
}
Ok(ev) => writeln!(output, "ev: {:?}", ev).unwrap(),
Err(e) => break Err(e),
}

View file

@ -13,7 +13,8 @@
ptr_metadata,
slice_ptr_get,
slice_take,
map_try_insert
map_try_insert,
extract_if
)]
#![allow(internal_features, clippy::format_collect)]

View file

@ -18,7 +18,6 @@ use {
mem,
ops::{self, Range},
rc::Rc,
usize,
},
};
@ -98,6 +97,10 @@ mod reg {
pub fn pushed_size(&self) -> usize {
((self.max_used as usize).saturating_sub(RET_ADDR as usize) + 1) * 8
}
pub fn mark_leaked(&mut self, reg: u8) {
self.meta.0[reg as usize].rc = u16::MAX;
}
}
}
@ -780,7 +783,13 @@ impl Nodes {
fn is_cfg(&self, o: Nid) -> bool {
matches!(
self[o].kind,
Kind::Start | Kind::End | Kind::Return | Kind::Tuple { .. } | Kind::Call { .. }
Kind::Start
| Kind::End
| Kind::Return
| Kind::Tuple { .. }
| Kind::Call { .. }
| Kind::Region
| Kind::Loop
)
}
@ -948,6 +957,7 @@ struct Variable {
struct ColorMeta {
rc: u32,
depth: u32,
loc: Loc,
}
@ -968,6 +978,7 @@ struct ItemCtx {
colors: Vec<ColorMeta>,
call_count: usize,
filled: Vec<Nid>,
delayed_frees: Vec<u32>,
loops: Vec<Loop>,
vars: Vec<Variable>,
@ -979,11 +990,21 @@ struct ItemCtx {
impl ItemCtx {
fn next_color(&mut self) -> u32 {
self.colors.push(ColorMeta { rc: 0, loc: Default::default() });
self.colors.push(ColorMeta { rc: 0, depth: self.loop_depth, loc: Default::default() });
self.colors.len() as _ // leave out 0 (sentinel)
}
fn extend_color(&mut self, color: u32) {
fn set_next_color(&mut self, node: Nid) {
let color = self.next_color();
self.set_color(node, color);
}
fn set_color(&mut self, node: Nid, color: u32) {
if self.nodes[node].color != 0 {
debug_assert_ne!(self.nodes[node].color, color);
self.colors[self.nodes[node].color as usize - 1].rc -= 1;
}
self.nodes[node].color = color;
self.colors[color as usize - 1].rc += 1;
}
@ -996,16 +1017,38 @@ impl ItemCtx {
return;
}
self.nodes[node].color = to;
// TODO:
// self.colors[to as usize - 1].rc -= 1;
// self.colors[from as usize - 1].rc -= 1;
self.set_color(node, to);
for i in 0..self.nodes[node].inputs().len() {
self.recolor(self.nodes[node].inputs[i], from, to);
}
}
fn check_color_integrity(&self) {
let node_count = self
.nodes
.values
.iter()
.filter(|v| {
matches!(
v,
PoolSlot::Value(Node {
kind: Kind::BinOp { .. }
| Kind::Call { .. }
| Kind::Phi
| Kind::ConstInt { .. },
..
})
) || matches!(
v,
PoolSlot::Value(Node { kind: Kind::Tuple { index: 1.. }, inputs: [0, ..], .. })
)
})
.count();
let color_count = self.colors.iter().map(|c| c.rc).sum::<u32>();
debug_assert_eq!(node_count, color_count as usize);
}
fn emit(&mut self, instr: (usize, [u8; instrs::MAX_SIZE])) {
emit(&mut self.code, instr);
}
@ -1728,9 +1771,11 @@ impl Codegen {
}
}
self.ci.nodes.lock(self.ci.ctrl);
for var in self.ci.vars.drain(base..) {
self.ci.nodes.unlock_remove(var.value);
}
self.ci.nodes.unlock(self.ci.ctrl);
ret
}
@ -1836,11 +1881,15 @@ impl Codegen {
'_color_args: {
for var in &orig_vars {
if var.id != u32::MAX {
self.ci.nodes[var.value].color = self.ci.next_color();
self.ci.set_next_color(var.value);
}
}
}
self.color_control(self.ci.nodes[self.ci.start].outputs[0]);
#[cfg(debug_assertions)]
{
self.ci.check_color_integrity();
}
self.ci.vars = orig_vars;
self.emit_control(self.ci.nodes[self.ci.start].outputs[0]);
@ -1892,6 +1941,7 @@ impl Codegen {
1..=8 => Loc { reg: 1 },
s => todo!("{s}"),
};
self.ci.regs.mark_leaked(1);
}
return None;
}
@ -1903,10 +1953,10 @@ impl Codegen {
Kind::Call { args, .. } => {
for &arg in args.iter() {
_ = self.color_expr_consume(arg);
self.ci.nodes[arg].color = self.ci.next_color(); // hack?
self.ci.set_next_color(arg);
}
self.ci.nodes[ctrl].color = self.ci.next_color();
self.ci.set_next_color(ctrl);
ctrl = *self.ci.nodes[ctrl]
.outputs
@ -1958,7 +2008,7 @@ impl Codegen {
_ = self.color_expr_consume(left);
self.ci.nodes[maybe_phy].depth = self.ci.loop_depth;
self.ci.nodes[maybe_phy].color = self.ci.next_color();
self.ci.set_next_color(maybe_phy);
}
self.ci.nodes[ctrl].lock_rc = self.ci.code.len() as _;
@ -2004,7 +2054,7 @@ impl Codegen {
// self.ci.recolor(right, c, self.ci.nodes[maybe_phy].color);
//}
} else {
self.ci.nodes[maybe_phy].color = match (lcolor, rcolor) {
let color = match (lcolor, rcolor) {
(None, None) => self.ci.next_color(),
(None, Some(c)) | (Some(c), None) => c,
(Some(lc), Some(rc)) => {
@ -2012,6 +2062,7 @@ impl Codegen {
lc
}
};
self.ci.set_color(maybe_phy, color);
}
}
@ -2029,17 +2080,16 @@ impl Codegen {
Kind::Start => unreachable!(),
Kind::End => unreachable!(),
Kind::Return => unreachable!(),
Kind::ConstInt { .. } => self.ci.nodes[expr].color = self.ci.next_color(),
Kind::ConstInt { .. } => self.ci.set_next_color(expr),
Kind::Tuple { index } => {
debug_assert!(index != 0);
}
Kind::BinOp { op } => {
Kind::BinOp { .. } => {
let [left, right, ..] = self.ci.nodes[expr].inputs;
let lcolor = self.color_expr_consume(left);
let rcolor = self.color_expr_consume(right);
self.ci.nodes[expr].color =
lcolor.or(rcolor).unwrap_or_else(|| self.ci.next_color());
let color = lcolor.or(rcolor).unwrap_or_else(|| self.ci.next_color());
self.ci.set_color(expr, color);
}
Kind::Call { .. } => {}
Kind::If => todo!(),
@ -2086,6 +2136,7 @@ impl Codegen {
1..=8 => Loc { reg: parama.next() },
s => todo!("{s}"),
};
self.ci.regs.mark_leaked(node_loc!(self, arg).reg);
self.emit_expr_consume(arg);
}
@ -2156,7 +2207,7 @@ impl Codegen {
let filled_base = self.ci.filled.len();
let left_unreachable = self.emit_control(self.ci.nodes[ctrl].outputs[0]);
for fld in self.ci.filled.drain(filled_base..) {
self.ci.nodes[fld].lock_rc = 1;
self.ci.nodes[fld].depth = 0;
}
let mut skip_then_offset = self.ci.code.len() as i64;
if let Some(region) = left_unreachable {
@ -2179,7 +2230,7 @@ impl Codegen {
let right_unreachable = self.emit_control(self.ci.nodes[ctrl].outputs[1]);
for fld in self.ci.filled.drain(filled_base..) {
self.ci.nodes[fld].lock_rc = 1;
self.ci.nodes[fld].depth = 0;
}
if let Some(region) = left_unreachable {
for i in 0..self.ci.nodes[region].outputs.len() {
@ -2245,6 +2296,7 @@ impl Codegen {
}
self.ci.nodes[ctrl].lock_rc = self.ci.code.len() as _;
self.ci.loop_depth += 1;
let end = self.emit_control(
*self.ci.nodes[ctrl]
@ -2280,6 +2332,15 @@ impl Codegen {
self.ci.nodes[ctrl].lock_rc as i32 - self.ci.code.len() as i32,
));
self.ci.loop_depth -= 1;
for free in self.ci.delayed_frees.extract_if(|&mut color| {
self.ci.colors[color as usize].depth == self.ci.loop_depth
}) {
let color = &self.ci.colors[free as usize];
debug_assert_ne!(color.loc, Loc::default());
self.ci.regs.free(color.loc.reg);
}
return None;
}
}
@ -2290,13 +2351,14 @@ impl Codegen {
fn emit_expr_consume(&mut self, expr: Nid) {
self.emit_expr(expr);
self.use_expr(expr)
self.use_expr(expr);
}
fn emit_expr(&mut self, expr: Nid) {
if std::mem::take(&mut self.ci.nodes[expr].lock_rc) == 0 {
if self.ci.nodes[expr].depth == u32::MAX {
return;
}
self.ci.nodes[expr].depth = u32::MAX;
self.ci.filled.push(expr);
match self.ci.nodes[expr].kind {
@ -2344,7 +2406,7 @@ impl Codegen {
if let Kind::ConstInt { value } = self.ci.nodes[right].kind
&& (node_loc!(self, right) == Loc::default()
|| self.ci.nodes[right].lock_rc != 0)
|| self.ci.nodes[right].depth != u32::MAX)
&& let Some(op) = Self::imm_math_op(op, ty.is_signed(), self.tys.size_of(ty))
{
let instr =
@ -2372,7 +2434,24 @@ impl Codegen {
}
}
fn use_expr(&mut self, _expr: Nid) {}
fn use_expr(&mut self, expr: Nid) {
let node = &mut self.ci.nodes[expr];
node.lock_rc = node.lock_rc.saturating_sub(1);
if node.lock_rc != 0 {
return;
}
let color = &mut self.ci.colors[node.color as usize - 1];
color.rc -= 1;
if color.rc == 0 {
if color.depth != self.ci.loop_depth {
self.ci.delayed_frees.push(node.color);
} else {
debug_assert_ne!(color.loc, Loc::default(), "{:?}", node);
self.ci.regs.free(color.loc.reg);
}
}
}
#[allow(clippy::type_complexity)]
fn imm_math_op(
@ -2564,13 +2643,15 @@ impl Codegen {
fn report_log(&self, pos: Pos, msg: impl std::fmt::Display) {
let str = &self.cfile().file;
let (line, col) = lexer::line_col(str.as_bytes(), pos);
let (line, mut col) = lexer::line_col(str.as_bytes(), pos);
println!("{}:{}:{}: {}", self.cfile().path, line, col, msg);
let line = str[str[..pos as usize].rfind('\n').map_or(0, |i| i + 1)
..str[pos as usize..].find('\n').unwrap_or(str.len())]
.replace("\t", " ");
println!("{line}");
let line = &str[str[..pos as usize].rfind('\n').map_or(0, |i| i + 1)
..str[pos as usize..].find('\n').unwrap_or(str.len()) + pos as usize];
col += line.matches('\t').count() * 3;
println!("{}", line.replace("\t", " "));
println!("{}^", " ".repeat(col - 1))
}
#[track_caller]
@ -2837,7 +2918,7 @@ mod tests {
comments => README;
if_statements => README;
loops => README;
//fb_driver => README;
fb_driver => README;
//pointers => README;
//structs => README;
//different_types => README;

View file

@ -0,0 +1,58 @@
main:
ADDI64 r254, r254, -96d
ST r31, r254, 0a, 96h
JAL r31, r0, :check_platform
LI64 r1, 0d
CP r32, r1
LI64 r33, 30d
CP r34, r33
LI64 r35, 100d
CP r36, r35
CP r37, r32
CP r38, r36
4: ADDI64 r39, r34, 1d
JGTS r32, r39, :0
JAL r31, r0, :set_pixel
CP r40, r4
ADDI64 r41, r3, 1d
CP r42, r3
JMP :1
0: JAL r31, r0, :set_pixel
CP r40, r4
CP r41, r1
ADDI64 r42, r3, 1d
1: JNE r42, r40, :2
JMP :3
2: CP r2, r41
CP r34, r33
CP r4, r35
CP r3, r42
CP r4, r40
JMP :4
3: LD r31, r254, 0a, 96h
ADDI64 r254, r254, 96d
JALA r0, r31, 0a
set_pixel:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r1, 0d
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
check_platform:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
JAL r31, r0, :x86_fb_ptr
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
x86_fb_ptr:
ADDI64 r254, r254, -8d
ST r31, r254, 0a, 8h
LI64 r1, 100d
LD r31, r254, 0a, 8h
ADDI64 r254, r254, 8d
JALA r0, r31, 0a
code size: 422
ret: 0
status: Ok(())