cleanup
This commit is contained in:
parent
af4d965b8c
commit
b62413046d
135
lang/src/son.rs
135
lang/src/son.rs
|
@ -93,10 +93,6 @@ impl Nodes {
|
||||||
_ => "white",
|
_ => "white",
|
||||||
};
|
};
|
||||||
|
|
||||||
let dest = i;
|
|
||||||
//let mut index_override = None;
|
|
||||||
|
|
||||||
//if !matches!(node.kind, Kind::Then | Kind::Else) {
|
|
||||||
if node.ty != ty::Id::VOID {
|
if node.ty != ty::Id::VOID {
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
|
@ -107,24 +103,14 @@ impl Nodes {
|
||||||
} else {
|
} else {
|
||||||
writeln!(out, " node{i}[label=\"{i} {}\" color={color}]", node.kind,)?;
|
writeln!(out, " node{i}[label=\"{i} {}\" color={color}]", node.kind,)?;
|
||||||
}
|
}
|
||||||
//} else {
|
|
||||||
// dest = node.inputs[0];
|
|
||||||
|
|
||||||
// index_override = if node.kind == Kind::Then { Some(0) } else { Some(1) };
|
|
||||||
//}
|
|
||||||
|
|
||||||
//if node.kind == Kind::If {
|
|
||||||
// continue;
|
|
||||||
//}
|
|
||||||
|
|
||||||
for (j, &o) in node.outputs.iter().enumerate() {
|
for (j, &o) in node.outputs.iter().enumerate() {
|
||||||
//let j = index_override.unwrap_or(j);
|
|
||||||
let color = if self.is_cfg(i) && self.is_cfg(o) { "red" } else { "lightgray" };
|
let color = if self.is_cfg(i) && self.is_cfg(o) { "red" } else { "lightgray" };
|
||||||
let index = self[o].inputs.iter().position(|&inp| i == inp).unwrap();
|
let index = self[o].inputs.iter().position(|&inp| i == inp).unwrap();
|
||||||
let style = if index == 0 && !self.is_cfg(o) { "style=dotted" } else { "" };
|
let style = if index == 0 && !self.is_cfg(o) { "style=dotted" } else { "" };
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
" node{o} -> node{dest}[color={color} taillabel={index} headlabel={j} {style}]",
|
" node{o} -> node{i}[color={color} taillabel={index} headlabel={j} {style}]",
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,19 +127,19 @@ impl Nodes {
|
||||||
log::info!("{out}");
|
log::info!("{out}");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn graphviz_in_browser(&self, _tys: &Types, _files: &[parser::Ast]) {
|
fn graphviz_in_browser(&self, tys: &Types, files: &[parser::Ast]) {
|
||||||
#[cfg(all(debug_assertions, feature = "std"))]
|
#[cfg(all(debug_assertions, feature = "std"))]
|
||||||
{
|
{
|
||||||
// let out = &mut String::new();
|
let out = &mut String::new();
|
||||||
// _ = self.graphviz_low(tys, files, out);
|
_ = self.graphviz_low(tys, files, out);
|
||||||
// if !std::process::Command::new("brave")
|
if !std::process::Command::new("brave")
|
||||||
// .arg(format!("https://dreampuf.github.io/GraphvizOnline/#{out}"))
|
.arg(format!("https://dreampuf.github.io/GraphvizOnline/#{out}"))
|
||||||
// .status()
|
.status()
|
||||||
// .unwrap()
|
.unwrap()
|
||||||
// .success()
|
.success()
|
||||||
// {
|
{
|
||||||
// log::error!("{out}");
|
log::error!("{out}");
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +276,6 @@ impl Nodes {
|
||||||
self.remove_node_lookup(target);
|
self.remove_node_lookup(target);
|
||||||
self.remove_low(target);
|
self.remove_low(target);
|
||||||
|
|
||||||
//std::println!("{target} {}", trace());
|
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -711,71 +695,14 @@ impl Nodes {
|
||||||
log::error!("outputs are empry {id} {:?}", node.kind);
|
log::error!("outputs are empry {id} {:?}", node.kind);
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// let mut allowed_cfgs = 1 + (node.kind == Kind::If) as usize;
|
|
||||||
// for &o in node.outputs.iter() {
|
|
||||||
// if self.is_cfg(i) {
|
|
||||||
// if allowed_cfgs == 0 && self.is_cfg(o) {
|
|
||||||
// log::err!(
|
|
||||||
// "multiple cfg outputs detected: {:?} -> {:?}",
|
|
||||||
// node.kind,
|
|
||||||
// self[o].kind
|
|
||||||
// );
|
|
||||||
// failed = true;
|
|
||||||
// } else {
|
|
||||||
// allowed_cfgs += self.is_cfg(o) as usize;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let other = match &self.values[o as usize] {
|
|
||||||
// Ok(other) => other,
|
|
||||||
// Err(_) => {
|
|
||||||
// log::err!("the edge points to dropped node: {i} {:?} {o}", node.kind,);
|
|
||||||
// failed = true;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// let occurs = self[o].inputs.iter().filter(|&&el| el == i).count();
|
|
||||||
// let self_occurs = self[i].outputs.iter().filter(|&&el| el == o).count();
|
|
||||||
// if occurs != self_occurs {
|
|
||||||
// log::err!(
|
|
||||||
// "the edge is not bidirectional: {i} {:?} {self_occurs} {o} {:?} {occurs}",
|
|
||||||
// node.kind,
|
|
||||||
// other.kind
|
|
||||||
// );
|
|
||||||
// failed = true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if failed {
|
if failed {
|
||||||
self.graphviz_in_browser(tys, files);
|
self.graphviz_in_browser(tys, files);
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(dead_code)]
|
|
||||||
fn climb_expr(&mut self, from: Nid, mut for_each: impl FnMut(Nid, &Node) -> bool) -> bool {
|
|
||||||
fn climb_impl(
|
|
||||||
nodes: &mut Nodes,
|
|
||||||
from: Nid,
|
|
||||||
for_each: &mut impl FnMut(Nid, &Node) -> bool,
|
|
||||||
) -> bool {
|
|
||||||
for i in 0..nodes[from].inputs.len() {
|
|
||||||
let n = nodes[from].inputs[i];
|
|
||||||
if n != Nid::MAX
|
|
||||||
&& nodes.visited.set(n)
|
|
||||||
&& !nodes.is_cfg(n)
|
|
||||||
&& (for_each(n, &nodes[n]) || climb_impl(nodes, n, for_each))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
self.visited.clear(self.values.len());
|
|
||||||
climb_impl(self, from, &mut for_each)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn late_peephole(&mut self, target: Nid) -> Nid {
|
fn late_peephole(&mut self, target: Nid) -> Nid {
|
||||||
if let Some(id) = self.peephole(target) {
|
if let Some(id) = self.peephole(target) {
|
||||||
self.replace(target, id);
|
self.replace(target, id);
|
||||||
|
@ -855,11 +782,6 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(dead_code)]
|
|
||||||
fn iter_mut(&mut self) -> impl Iterator<Item = &mut Node> {
|
|
||||||
self.values.iter_mut().flat_map(Result::as_mut)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn eliminate_stack_temporaries(&mut self) {
|
fn eliminate_stack_temporaries(&mut self) {
|
||||||
'o: for stack in self[MEM].outputs.clone() {
|
'o: for stack in self[MEM].outputs.clone() {
|
||||||
|
@ -1061,7 +983,6 @@ impl fmt::Display for Kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
//#[repr(align(64))]
|
|
||||||
pub struct Node {
|
pub struct Node {
|
||||||
kind: Kind,
|
kind: Kind,
|
||||||
inputs: Vc,
|
inputs: Vc,
|
||||||
|
@ -1267,11 +1188,16 @@ impl ItemCtx {
|
||||||
crate::emit(&mut self.code, instr);
|
crate::emit(&mut self.code, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_body_code(&mut self, sig: Sig, tys: &Types, files: &[parser::Ast]) -> usize {
|
fn emit_body_code(
|
||||||
|
&mut self,
|
||||||
|
sig: Sig,
|
||||||
|
tys: &Types,
|
||||||
|
files: &[parser::Ast],
|
||||||
|
ralloc: &mut Regalloc,
|
||||||
|
) -> usize {
|
||||||
let mut nodes = core::mem::take(&mut self.nodes);
|
let mut nodes = core::mem::take(&mut self.nodes);
|
||||||
|
|
||||||
let fuc = Function::new(&mut nodes, tys, sig);
|
let fuc = Function::new(&mut nodes, tys, sig);
|
||||||
let mut ralloc = Regalloc::default(); // TODO: reuse
|
|
||||||
log::info!("{:?}", fuc);
|
log::info!("{:?}", fuc);
|
||||||
if self.call_count != 0 {
|
if self.call_count != 0 {
|
||||||
core::mem::swap(
|
core::mem::swap(
|
||||||
|
@ -1600,7 +1526,13 @@ impl ItemCtx {
|
||||||
saved_regs.len()
|
saved_regs.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_body(&mut self, tys: &mut Types, files: &[parser::Ast], sig: Sig) {
|
fn emit_body(
|
||||||
|
&mut self,
|
||||||
|
tys: &mut Types,
|
||||||
|
files: &[parser::Ast],
|
||||||
|
sig: Sig,
|
||||||
|
ralloc: &mut Regalloc,
|
||||||
|
) {
|
||||||
self.nodes.check_final_integrity(tys, files);
|
self.nodes.check_final_integrity(tys, files);
|
||||||
self.nodes.graphviz(tys, files);
|
self.nodes.graphviz(tys, files);
|
||||||
self.nodes.gcm();
|
self.nodes.gcm();
|
||||||
|
@ -1638,7 +1570,7 @@ impl ItemCtx {
|
||||||
self.nodes[MEM].outputs = mems;
|
self.nodes[MEM].outputs = mems;
|
||||||
}
|
}
|
||||||
|
|
||||||
let saved = self.emit_body_code(sig, tys, files);
|
let saved = self.emit_body_code(sig, tys, files, ralloc);
|
||||||
|
|
||||||
if let Some(last_ret) = self.ret_relocs.last()
|
if let Some(last_ret) = self.ret_relocs.last()
|
||||||
&& last_ret.offset as usize == self.code.len() - 5
|
&& last_ret.offset as usize == self.code.len() - 5
|
||||||
|
@ -1722,8 +1654,6 @@ impl Ctx {
|
||||||
struct Pool {
|
struct Pool {
|
||||||
cis: Vec<ItemCtx>,
|
cis: Vec<ItemCtx>,
|
||||||
used_cis: usize,
|
used_cis: usize,
|
||||||
|
|
||||||
#[expect(dead_code)]
|
|
||||||
ralloc: Regalloc,
|
ralloc: Regalloc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1889,7 +1819,12 @@ impl<'a> Codegen<'a> {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.emit_body(self.tys, self.files, Sig { args: Tuple::empty(), ret });
|
self.ci.emit_body(
|
||||||
|
self.tys,
|
||||||
|
self.files,
|
||||||
|
Sig { args: Tuple::empty(), ret },
|
||||||
|
&mut self.pool.ralloc,
|
||||||
|
);
|
||||||
self.ci.code.truncate(self.ci.code.len() - instrs::jala(0, 0, 0).0);
|
self.ci.code.truncate(self.ci.code.len() - instrs::jala(0, 0, 0).0);
|
||||||
self.ci.emit(instrs::tx());
|
self.ci.emit(instrs::tx());
|
||||||
|
|
||||||
|
@ -3425,7 +3360,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.finalize();
|
self.ci.finalize();
|
||||||
|
|
||||||
if self.errors.borrow().len() == prev_err_len {
|
if self.errors.borrow().len() == prev_err_len {
|
||||||
self.ci.emit_body(self.tys, self.files, sig);
|
self.ci.emit_body(self.tys, self.files, sig, &mut self.pool.ralloc);
|
||||||
self.tys.ins.funcs[id as usize].code.append(&mut self.ci.code);
|
self.tys.ins.funcs[id as usize].code.append(&mut self.ci.code);
|
||||||
self.tys.ins.funcs[id as usize].relocs.append(&mut self.ci.relocs);
|
self.tys.ins.funcs[id as usize].relocs.append(&mut self.ci.relocs);
|
||||||
}
|
}
|
||||||
|
|
51
pointers.hb
51
pointers.hb
|
@ -1,51 +0,0 @@
|
||||||
Point := struct {
|
|
||||||
x: int,
|
|
||||||
y: int,
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect := struct {
|
|
||||||
min: Point,
|
|
||||||
max: Point,
|
|
||||||
}
|
|
||||||
|
|
||||||
main := fn(): void {
|
|
||||||
rect := Rect.(.(0, 0), .(0, 0))
|
|
||||||
// eliminates initila 0
|
|
||||||
rect.min.x = 1
|
|
||||||
// here as well
|
|
||||||
rect.min.y = 2
|
|
||||||
// eliminates previous 2 lines, intermidiate stack slot is created, and stores are
|
|
||||||
// delegated to the rect
|
|
||||||
rect.min = .(3, 4)
|
|
||||||
|
|
||||||
// encompasses the previous two loads
|
|
||||||
ptr := &rect.min
|
|
||||||
// pointer escapes to a function -> rect.min now has unknown values
|
|
||||||
clobber(ptr)
|
|
||||||
|
|
||||||
// this can not be folded but load can be reused
|
|
||||||
rect.max.x = rect.min.x * rect.min.x
|
|
||||||
|
|
||||||
// this should invalidate the previous loads
|
|
||||||
clobber(ptr)
|
|
||||||
// now all stores are clobbered
|
|
||||||
clobber(&rect.max)
|
|
||||||
|
|
||||||
// conslusion: pointers fundamentally dont do anything and are not registered anywhere,
|
|
||||||
// thay are just bound to the base memory and when you interact with them (store, load)
|
|
||||||
// they modity the memory state, they are literally a view trought which we look at the
|
|
||||||
// memory and remotely modify it, so in summary, pointers are not bound to a specific load
|
|
||||||
// or store, but they can invalidate them.
|
|
||||||
//
|
|
||||||
// The fact pointers are bound to the base memory also makes it easy to tell how aliasing works
|
|
||||||
// for the pointer, we prohibit pointer arithmetic on these pointers, instead this is delegated
|
|
||||||
// to special pointer type that can only be created when compiler can prove ist safe or explicitly
|
|
||||||
// with a directive
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clobber := fn(p: ^Point): void {
|
|
||||||
*p = .(5, 6)
|
|
||||||
return
|
|
||||||
}
|
|
Loading…
Reference in a new issue