saving before refactoring experiment
This commit is contained in:
parent
fb481a0600
commit
9aa5da82c9
|
@ -2,10 +2,16 @@ main := fn(): int {
|
||||||
a := 1;
|
a := 1;
|
||||||
b := &a;
|
b := &a;
|
||||||
modify(b);
|
modify(b);
|
||||||
return a - 2;
|
drop(a);
|
||||||
|
stack_reclamation_edge_case := 0;
|
||||||
|
return *b - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
modify := fn(a: *int): void {
|
modify := fn(a: *int): void {
|
||||||
*a = 2;
|
*a = 2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop := fn(a: int): void {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -388,8 +388,9 @@ struct RetReloc {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Loop {
|
struct Loop {
|
||||||
offset: u32,
|
var_count: usize,
|
||||||
relocs: Vec<RetReloc>,
|
offset: u32,
|
||||||
|
relocs: Vec<RetReloc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Struct {
|
struct Struct {
|
||||||
|
@ -637,7 +638,7 @@ impl<'a> Codegen<'a> {
|
||||||
let reg = self.gpa.allocate();
|
let reg = self.gpa.allocate();
|
||||||
self.code
|
self.code
|
||||||
.encode(instrs::ld(reg.0, dreg.0, offset, size as _));
|
.encode(instrs::ld(reg.0, dreg.0, offset, size as _));
|
||||||
self.gpa.free(dreg);
|
self.free_reg(dreg);
|
||||||
reg
|
reg
|
||||||
}
|
}
|
||||||
Loc::DerefRef(dreg, offset) => {
|
Loc::DerefRef(dreg, offset) => {
|
||||||
|
@ -814,7 +815,7 @@ impl<'a> Codegen<'a> {
|
||||||
let size = self.size_of(val.ty);
|
let size = self.size_of(val.ty);
|
||||||
let stack = self.sa.alloc(size);
|
let stack = self.sa.alloc(size);
|
||||||
self.store_stack(r.0, stack.offset, size as _);
|
self.store_stack(r.0, stack.offset, size as _);
|
||||||
self.gpa.free(r);
|
self.free_reg(r);
|
||||||
Loc::Stack(stack, 0)
|
Loc::Stack(stack, 0)
|
||||||
}
|
}
|
||||||
l => l,
|
l => l,
|
||||||
|
@ -886,11 +887,14 @@ impl<'a> Codegen<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
E::Ident { name, id, last } => {
|
E::Ident { name, id, last } => {
|
||||||
let Some(var) = self.vars.iter_mut().find(|v| v.id == id) else {
|
let Some((index, var)) = self.vars.iter_mut().enumerate().find(|(_, v)| v.id == id)
|
||||||
|
else {
|
||||||
self.report(expr.pos(), format_args!("unknown variable: {}", name))
|
self.report(expr.pos(), format_args!("unknown variable: {}", name))
|
||||||
};
|
};
|
||||||
|
|
||||||
let loc = match last.is_some_and(Cell::get) {
|
let loc = match last.is_some_and(Cell::get)
|
||||||
|
&& !self.loops.last().is_some_and(|l| l.var_count > index)
|
||||||
|
{
|
||||||
true => std::mem::replace(&mut var.value.loc, Loc::Imm(0)),
|
true => std::mem::replace(&mut var.value.loc, Loc::Imm(0)),
|
||||||
false => var.value.loc.take_ref(),
|
false => var.value.loc.take_ref(),
|
||||||
};
|
};
|
||||||
|
@ -921,7 +925,7 @@ impl<'a> Codegen<'a> {
|
||||||
E::Block { stmts, .. } => {
|
E::Block { stmts, .. } => {
|
||||||
for stmt in stmts {
|
for stmt in stmts {
|
||||||
if let Loc::Reg(reg) = self.expr(stmt)?.loc {
|
if let Loc::Reg(reg) = self.expr(stmt)?.loc {
|
||||||
self.gpa.free(reg);
|
self.free_reg(reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Value::VOID)
|
Some(Value::VOID)
|
||||||
|
@ -938,7 +942,7 @@ impl<'a> Codegen<'a> {
|
||||||
let reg = self.loc_to_reg(cond.loc, 1);
|
let reg = self.loc_to_reg(cond.loc, 1);
|
||||||
let jump_offset = self.code.code.len() as u32;
|
let jump_offset = self.code.code.len() as u32;
|
||||||
self.code.encode(instrs::jeq(reg.0, 0, 0));
|
self.code.encode(instrs::jeq(reg.0, 0, 0));
|
||||||
self.gpa.free(reg);
|
self.free_reg(reg);
|
||||||
|
|
||||||
log::dbg!("if-then");
|
log::dbg!("if-then");
|
||||||
let then_unreachable = self.expr(then).is_none();
|
let then_unreachable = self.expr(then).is_none();
|
||||||
|
@ -978,8 +982,9 @@ impl<'a> Codegen<'a> {
|
||||||
log::dbg!("loop");
|
log::dbg!("loop");
|
||||||
let loop_start = self.code.code.len() as u32;
|
let loop_start = self.code.code.len() as u32;
|
||||||
self.loops.push(Loop {
|
self.loops.push(Loop {
|
||||||
offset: loop_start,
|
var_count: self.vars.len() as _,
|
||||||
relocs: Default::default(),
|
offset: loop_start,
|
||||||
|
relocs: Default::default(),
|
||||||
});
|
});
|
||||||
let body_unreachable = self.expr(body).is_none();
|
let body_unreachable = self.expr(body).is_none();
|
||||||
|
|
||||||
|
@ -1002,6 +1007,14 @@ impl<'a> Codegen<'a> {
|
||||||
dest.copy_from_slice(&offset.to_ne_bytes());
|
dest.copy_from_slice(&offset.to_ne_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for var in self
|
||||||
|
.vars
|
||||||
|
.drain(loop_.var_count as usize..)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
{
|
||||||
|
self.free_loc(var.value.loc);
|
||||||
|
}
|
||||||
|
|
||||||
if is_unreachable {
|
if is_unreachable {
|
||||||
log::dbg!("infinite loop");
|
log::dbg!("infinite loop");
|
||||||
break 'a None;
|
break 'a None;
|
||||||
|
@ -1087,7 +1100,7 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
if let Some(op) = Self::math_op(op, signed, size) {
|
if let Some(op) = Self::math_op(op, signed, size) {
|
||||||
self.code.encode(op(lhs.0, lhs.0, rhs.0));
|
self.code.encode(op(lhs.0, lhs.0, rhs.0));
|
||||||
self.gpa.free(rhs);
|
self.free_reg(rhs);
|
||||||
|
|
||||||
break 'ops Some(Value {
|
break 'ops Some(Value {
|
||||||
ty,
|
ty,
|
||||||
|
@ -1105,7 +1118,7 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
let op_fn = if signed { i::cmps } else { i::cmpu };
|
let op_fn = if signed { i::cmps } else { i::cmpu };
|
||||||
self.code.encode(op_fn(lhs.0, lhs.0, rhs.0));
|
self.code.encode(op_fn(lhs.0, lhs.0, rhs.0));
|
||||||
self.gpa.free(rhs);
|
self.free_reg(rhs);
|
||||||
self.code.encode(instrs::cmpui(lhs.0, lhs.0, against));
|
self.code.encode(instrs::cmpui(lhs.0, lhs.0, against));
|
||||||
if matches!(op, T::Eq | T::Lt | T::Gt) {
|
if matches!(op, T::Eq | T::Lt | T::Gt) {
|
||||||
self.code.encode(instrs::not(lhs.0, lhs.0));
|
self.code.encode(instrs::not(lhs.0, lhs.0));
|
||||||
|
@ -1130,6 +1143,10 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn free_reg(&mut self, reg: LinReg) {
|
||||||
|
self.gpa.free(reg);
|
||||||
|
}
|
||||||
|
|
||||||
fn math_op(
|
fn math_op(
|
||||||
op: T,
|
op: T,
|
||||||
signed: bool,
|
signed: bool,
|
||||||
|
@ -1160,8 +1177,8 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
fn free_loc(&mut self, loc: Loc) {
|
fn free_loc(&mut self, loc: Loc) {
|
||||||
match loc {
|
match loc {
|
||||||
Loc::Reg(reg) => self.gpa.free(reg),
|
Loc::Reg(reg) => self.free_reg(reg),
|
||||||
Loc::Deref(reg, ..) => self.gpa.free(reg),
|
Loc::Deref(reg, ..) => self.free_reg(reg),
|
||||||
Loc::Stack(stack, ..) => self.sa.free(stack),
|
Loc::Stack(stack, ..) => self.sa.free(stack),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -1199,7 +1216,7 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
if let Some(op) = Self::math_op(op, signed, size) {
|
if let Some(op) = Self::math_op(op, signed, size) {
|
||||||
self.code.encode(op(lhs, lhs, rhs.0));
|
self.code.encode(op(lhs, lhs, rhs.0));
|
||||||
self.gpa.free(rhs);
|
self.free_reg(rhs);
|
||||||
return if let Ctx::Dest(dest) = ctx {
|
return if let Ctx::Dest(dest) = ctx {
|
||||||
self.assign(dest.ty, dest.loc, owned.map_or(Loc::RegRef(lhs), Loc::Reg));
|
self.assign(dest.ty, dest.loc, owned.map_or(Loc::RegRef(lhs), Loc::Reg));
|
||||||
Some(Value::VOID)
|
Some(Value::VOID)
|
||||||
|
@ -1264,7 +1281,7 @@ impl<'a> Codegen<'a> {
|
||||||
Loc::RegRef(reg) => self.code.encode(instrs::cp(reg, lhs.0)),
|
Loc::RegRef(reg) => self.code.encode(instrs::cp(reg, lhs.0)),
|
||||||
Loc::Deref(reg, off) => {
|
Loc::Deref(reg, off) => {
|
||||||
self.code.encode(instrs::st(lhs.0, reg.0, off, size as _));
|
self.code.encode(instrs::st(lhs.0, reg.0, off, size as _));
|
||||||
self.gpa.free(reg);
|
self.free_reg(reg);
|
||||||
}
|
}
|
||||||
Loc::DerefRef(reg, off) => {
|
Loc::DerefRef(reg, off) => {
|
||||||
self.code.encode(instrs::st(lhs.0, reg, off, size as _));
|
self.code.encode(instrs::st(lhs.0, reg, off, size as _));
|
||||||
|
@ -1275,7 +1292,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
l => unimplemented!("{:?}", l),
|
l => unimplemented!("{:?}", l),
|
||||||
}
|
}
|
||||||
self.gpa.free(lhs);
|
self.free_reg(lhs);
|
||||||
}
|
}
|
||||||
..=16 if matches!(right, Loc::RegRef(1)) => {
|
..=16 if matches!(right, Loc::RegRef(1)) => {
|
||||||
let (lhs, loff) = left.ref_to_ptr();
|
let (lhs, loff) = left.ref_to_ptr();
|
||||||
|
@ -1288,8 +1305,8 @@ impl<'a> Codegen<'a> {
|
||||||
self.code
|
self.code
|
||||||
.encode(instrs::bmc(lhs.0, rhs.0, size.try_into().unwrap()));
|
.encode(instrs::bmc(lhs.0, rhs.0, size.try_into().unwrap()));
|
||||||
|
|
||||||
self.gpa.free(lhs);
|
self.free_reg(lhs);
|
||||||
self.gpa.free(rhs);
|
self.free_reg(rhs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
code size: 452
|
code size: 475
|
||||||
ret: 55
|
ret: 55
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
code size: 331
|
code size: 318
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
code size: 530
|
code size: 538
|
||||||
ret: 3
|
ret: 3
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue