Release registers upon return

This commit is contained in:
Andrew Morris
2023-07-01 08:24:42 +10:00
parent 52f42334b3
commit f985698724
8 changed files with 61 additions and 22 deletions

View File

@@ -274,6 +274,10 @@ impl Register {
return self.name == "ignore";
}
pub fn is_special(&self) -> bool {
return self.is_return() || self.is_this() || self.is_ignore();
}
pub fn value_type(&self) -> ValueType {
if self.take {
ValueType::TakeRegister

View File

@@ -218,6 +218,14 @@ impl FunctionCompiler {
self.current.body.push(FnLine::Release(reg.clone()));
}
pub fn insert_all_releases(&mut self) {
for reg in self.reg_allocator.all_used() {
if !reg.is_special() {
self.current.body.push(FnLine::Release(reg));
}
}
}
pub fn compile(
definition_pointer: Pointer,
fn_name: Option<String>,
@@ -341,6 +349,8 @@ impl FunctionCompiler {
}
};
self.insert_all_releases();
if let Some(end_label) = self.end_label.as_ref() {
self.current.body.push(FnLine::Label(end_label.clone()));
@@ -493,6 +503,7 @@ impl FunctionCompiler {
self.push(Instruction::Mov(Value::Bool(true), is_returning.clone()));
self.push(Instruction::Jmp(finally_label.ref_()));
} else {
self.insert_all_releases();
self.push(Instruction::End);
}
}

View File

@@ -1,10 +1,10 @@
use std::collections::HashSet;
use std::collections::BTreeSet;
use crate::asm::{Pointer, Register};
#[derive(Default, Clone)]
pub struct NameAllocator {
used_names: HashSet<String>,
used_names: BTreeSet<String>,
released_names: Vec<String>,
}
@@ -149,6 +149,16 @@ impl RegAllocator {
false => panic!("Can't release non-named register"),
}
}
pub fn all_used(&self) -> Vec<Register> {
let mut res = Vec::<Register>::new();
for name in &self.alloc.used_names {
res.push(Register::named(name.clone()));
}
res
}
}
impl Default for RegAllocator {