adding global mutatuon to the test
This commit is contained in:
parent
ee30069195
commit
bb41da484f
|
@ -217,6 +217,7 @@ fib := fn(n: int): int {
|
|||
}
|
||||
|
||||
main := fn(): int {
|
||||
complex_global_var += 5
|
||||
return complex_global_var
|
||||
}
|
||||
```
|
||||
|
|
|
@ -2106,7 +2106,7 @@ impl Codegen {
|
|||
}
|
||||
E::BinOp { left, op, right } if op != T::Decl => 'ops: {
|
||||
let left = self.expr_ctx(left, Ctx {
|
||||
ty: ctx.ty.filter(|_| dbg!(dbg!(op).is_homogenous())),
|
||||
ty: ctx.ty.filter(|_| op.is_homogenous()),
|
||||
..Default::default()
|
||||
})?;
|
||||
|
||||
|
|
|
@ -13,16 +13,17 @@ use {
|
|||
HashMap,
|
||||
},
|
||||
core::fmt,
|
||||
hbvm::mem::softpaging::lookup,
|
||||
std::{
|
||||
cell::RefCell,
|
||||
collections::{hash_map, BTreeMap},
|
||||
default,
|
||||
fmt::Display,
|
||||
hash::{Hash as _, Hasher},
|
||||
intrinsics::unreachable,
|
||||
mem,
|
||||
ops::{self, Range},
|
||||
rc::Rc,
|
||||
usize,
|
||||
u32, usize,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -463,11 +464,43 @@ mod ty {
|
|||
}
|
||||
}
|
||||
|
||||
struct LookupEntry {
|
||||
nid: u32,
|
||||
hash: u64,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct IdentityHash(u64);
|
||||
|
||||
impl std::hash::Hasher for IdentityHash {
|
||||
fn finish(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
fn write(&mut self, _: &[u8]) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn write_u64(&mut self, i: u64) {
|
||||
self.0 = i;
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for LookupEntry {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
state.write_u64(self.hash);
|
||||
}
|
||||
}
|
||||
|
||||
struct Nodes {
|
||||
values: Vec<Result<Node, u32>>,
|
||||
visited: BitSet,
|
||||
free: u32,
|
||||
lookup: HashMap<Nid, ()>,
|
||||
lookup: std::collections::hash_map::HashMap<
|
||||
LookupEntry,
|
||||
(),
|
||||
std::hash::BuildHasherDefault<IdentityHash>,
|
||||
>,
|
||||
}
|
||||
|
||||
impl Default for Nodes {
|
||||
|
@ -504,7 +537,7 @@ impl Nodes {
|
|||
|
||||
let node = Node {
|
||||
inputs: inps.into(),
|
||||
kind: kind.clone(),
|
||||
kind,
|
||||
color: 0,
|
||||
depth: u32::MAX,
|
||||
lock_rc: 0,
|
||||
|
@ -512,15 +545,17 @@ impl Nodes {
|
|||
outputs: vec![],
|
||||
};
|
||||
|
||||
let mut hasher = crate::FnvHasher::default();
|
||||
node.key().hash(&mut hasher);
|
||||
let mut lookup_meta = None;
|
||||
if node.kind != Kind::Phi || node.inputs[2] != 0 {
|
||||
let (raw_entry, hash) = Self::find_node(&mut self.lookup, &self.values, &node);
|
||||
|
||||
let (raw_entry, _) = Self::find_node(&mut self.lookup, &self.values, &node);
|
||||
let entry = match raw_entry {
|
||||
hash_map::RawEntryMut::Occupied(mut o) => return o.get_key_value().0.nid,
|
||||
hash_map::RawEntryMut::Vacant(v) => v,
|
||||
};
|
||||
|
||||
let entry = match raw_entry {
|
||||
hash_map::RawEntryMut::Occupied(mut o) => return *o.get_key_value().0,
|
||||
hash_map::RawEntryMut::Vacant(v) => v,
|
||||
};
|
||||
lookup_meta = Some((entry, hash));
|
||||
}
|
||||
|
||||
if self.free == u32::MAX {
|
||||
self.free = self.values.len() as _;
|
||||
|
@ -532,40 +567,48 @@ impl Nodes {
|
|||
debug_assert_ne!(d, free);
|
||||
self.values[d as usize].as_mut().unwrap().outputs.push(free);
|
||||
}
|
||||
|
||||
self.free = mem::replace(&mut self.values[free as usize], Ok(node)).unwrap_err();
|
||||
*entry.insert(free, ()).0
|
||||
|
||||
if let Some((entry, hash)) = lookup_meta {
|
||||
entry.insert(LookupEntry { nid: free, hash }, ());
|
||||
}
|
||||
free
|
||||
}
|
||||
|
||||
fn find_node<'a>(
|
||||
lookup: &'a mut HashMap<Nid, ()>,
|
||||
lookup: &'a mut std::collections::hash_map::HashMap<
|
||||
LookupEntry,
|
||||
(),
|
||||
std::hash::BuildHasherDefault<IdentityHash>,
|
||||
>,
|
||||
values: &[Result<Node, u32>],
|
||||
node: &Node,
|
||||
) -> (hash_map::RawEntryMut<'a, u32, (), std::hash::BuildHasherDefault<crate::FnvHasher>>, u64)
|
||||
{
|
||||
) -> (
|
||||
hash_map::RawEntryMut<'a, LookupEntry, (), std::hash::BuildHasherDefault<IdentityHash>>,
|
||||
u64,
|
||||
) {
|
||||
let mut hasher = crate::FnvHasher::default();
|
||||
node.key().hash(&mut hasher);
|
||||
let hash = hasher.finish();
|
||||
|
||||
(
|
||||
lookup
|
||||
.raw_entry_mut()
|
||||
.from_hash(hash, |&n| values[n as usize].as_ref().unwrap().key() == node.key()),
|
||||
hash,
|
||||
)
|
||||
let entry = lookup
|
||||
.raw_entry_mut()
|
||||
.from_hash(hash, |n| values[n.nid as usize].as_ref().unwrap().key() == node.key());
|
||||
(entry, hash)
|
||||
}
|
||||
|
||||
fn remove_node_lookup(&mut self, target: Nid) {
|
||||
match Self::find_node(
|
||||
&mut self.lookup,
|
||||
&self.values,
|
||||
&self.values[target as usize].as_ref().unwrap(),
|
||||
)
|
||||
.0
|
||||
{
|
||||
hash_map::RawEntryMut::Occupied(o) => o.remove(),
|
||||
hash_map::RawEntryMut::Vacant(_) => unreachable!(),
|
||||
};
|
||||
if self[target].kind != Kind::Phi || self[target].inputs[2] != 0 {
|
||||
match Self::find_node(
|
||||
&mut self.lookup,
|
||||
&self.values,
|
||||
self.values[target as usize].as_ref().unwrap(),
|
||||
)
|
||||
.0
|
||||
{
|
||||
hash_map::RawEntryMut::Occupied(o) => o.remove(),
|
||||
hash_map::RawEntryMut::Vacant(_) => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn new_node(&mut self, ty: impl Into<ty::Id>, kind: Kind, inps: impl Into<Vec<u32>>) -> Nid {
|
||||
|
@ -619,12 +662,20 @@ impl Nodes {
|
|||
Kind::Call { .. } => {}
|
||||
Kind::If => return self.peephole_if(target),
|
||||
Kind::Region => {}
|
||||
Kind::Phi => {}
|
||||
Kind::Phi => return self.peephole_phi(target),
|
||||
Kind::Loop => {}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn peephole_phi(&mut self, target: Nid) -> Option<Nid> {
|
||||
if self[target].inputs[1] == self[target].inputs[2] {
|
||||
return Some(self[target].inputs[1]);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn peephole_if(&mut self, target: Nid) -> Option<Nid> {
|
||||
let cond = self[target].inputs[1];
|
||||
if let Kind::ConstInt { value } = self[cond].kind {
|
||||
|
@ -720,7 +771,7 @@ impl Nodes {
|
|||
}
|
||||
|
||||
if changed {
|
||||
return Some(self.new_node(self[target].ty, self[target].kind.clone(), [lhs, rhs]));
|
||||
return Some(self.new_node(self[target].ty, self[target].kind, [lhs, rhs]));
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -731,11 +782,13 @@ impl Nodes {
|
|||
}
|
||||
|
||||
fn replace(&mut self, target: Nid, with: Nid) {
|
||||
let mut back_press = 0;
|
||||
for i in 0..self[target].outputs.len() {
|
||||
let out = self[target].outputs[i];
|
||||
let out = self[target].outputs[i - back_press];
|
||||
let index = self[out].inputs.iter().position(|&p| p == target).unwrap();
|
||||
let rpl = self.modify_input(out, index, with);
|
||||
self[with].outputs.push(rpl);
|
||||
let prev_len = self[target].outputs.len();
|
||||
self.modify_input(out, index, with);
|
||||
back_press += (self[target].outputs.len() != prev_len) as usize;
|
||||
}
|
||||
|
||||
self.remove(target);
|
||||
|
@ -750,17 +803,19 @@ impl Nodes {
|
|||
let (entry, hash) = Self::find_node(
|
||||
&mut self.lookup,
|
||||
&self.values,
|
||||
&self.values[target as usize].as_ref().unwrap(),
|
||||
self.values[target as usize].as_ref().unwrap(),
|
||||
);
|
||||
match entry {
|
||||
hash_map::RawEntryMut::Occupied(mut other) => {
|
||||
let rpl = *other.get_key_value().0;
|
||||
log::dbg!("rplc");
|
||||
let rpl = other.get_key_value().0.nid;
|
||||
self[target].inputs[inp_index] = prev;
|
||||
self.replace(target, rpl);
|
||||
rpl
|
||||
}
|
||||
hash_map::RawEntryMut::Vacant(slot) => {
|
||||
slot.insert_hashed_nocheck(hash, target, ());
|
||||
log::dbg!("mod");
|
||||
slot.insert(LookupEntry { nid: target, hash }, ());
|
||||
let index = self[prev].outputs.iter().position(|&o| o == target).unwrap();
|
||||
self[prev].outputs.swap_remove(index);
|
||||
self[with].outputs.push(target);
|
||||
|
@ -913,8 +968,28 @@ impl Nodes {
|
|||
failed = true;
|
||||
}
|
||||
|
||||
let mut allowed_cfgs = 1 + (node.kind == Kind::If) as usize;
|
||||
for &o in &node.outputs {
|
||||
let mut occurs = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
if matches!(node.kind, Kind::Region | Kind::Loop)
|
||||
&& !self.is_cfg(o)
|
||||
&& self[o].kind != Kind::Phi
|
||||
{
|
||||
log::err!("unexpected output node on region: {:?}", self[o].kind);
|
||||
failed = true;
|
||||
}
|
||||
|
||||
let other = match &self.values[o as usize] {
|
||||
Ok(other) => other,
|
||||
Err(_) => {
|
||||
|
@ -923,10 +998,11 @@ impl Nodes {
|
|||
continue;
|
||||
}
|
||||
};
|
||||
occurs += self[o].inputs.iter().filter(|&&el| el == i).count();
|
||||
if occurs == 0 {
|
||||
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} {:?} {o} {:?}",
|
||||
"the edge is not bidirectional: {i} {:?} {self_occurs} {o} {:?} {occurs}",
|
||||
node.kind,
|
||||
other.kind
|
||||
);
|
||||
|
@ -961,11 +1037,19 @@ impl Nodes {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
false
|
||||
}
|
||||
self.visited.clear(self.values.len());
|
||||
climb_impl(self, from, &mut for_each)
|
||||
}
|
||||
|
||||
fn late_peephole(&mut self, target: Nid) -> Nid {
|
||||
if let Some(id) = self.peephole(target) {
|
||||
self.replace(target, id);
|
||||
return id;
|
||||
}
|
||||
target
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Index<u32> for Nodes {
|
||||
|
@ -1625,16 +1709,23 @@ impl Codegen {
|
|||
};
|
||||
|
||||
if self.ci.vars[index].value == 0 {
|
||||
self.ci.nodes.unlock(self.ci.vars[index].value);
|
||||
let loob = self.ci.loops.last_mut().unwrap();
|
||||
let inps = [loob.node, loob.scope[index].value, loob.scope[index].value];
|
||||
self.ci.nodes.unlock(inps[1]);
|
||||
let ty = self.ci.nodes[inps[1]].ty;
|
||||
// TODO: dont apply peepholes here
|
||||
let phy = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
||||
self.ci.nodes[phy].lock_rc += 2;
|
||||
self.ci.vars[index].value = phy;
|
||||
loob.scope[index].value = phy;
|
||||
if self.ci.nodes[loob.scope[index].value].kind != Kind::Phi
|
||||
|| self.ci.nodes[loob.scope[index].value].inputs[0] != loob.node
|
||||
{
|
||||
self.ci.nodes.unlock(self.ci.vars[index].value);
|
||||
let inps = [loob.node, loob.scope[index].value, 0];
|
||||
self.ci.nodes.unlock(inps[1]);
|
||||
let ty = self.ci.nodes[inps[1]].ty;
|
||||
let phi = self.ci.nodes.new_node_nop(ty, Kind::Phi, inps);
|
||||
self.ci.nodes[phi].lock_rc += 2;
|
||||
self.ci.vars[index].value = phi;
|
||||
loob.scope[index].value = phi;
|
||||
} else {
|
||||
self.ci.nodes.unlock_remove(self.ci.vars[index].value);
|
||||
self.ci.vars[index].value = loob.scope[index].value;
|
||||
self.ci.nodes.lock(self.ci.vars[index].value);
|
||||
}
|
||||
}
|
||||
|
||||
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||
|
@ -1751,8 +1842,12 @@ impl Codegen {
|
|||
|
||||
let ty = self.ci.nodes[else_var.value].ty;
|
||||
debug_assert_eq!(
|
||||
ty, self.ci.nodes[then_var.value].ty,
|
||||
"TODO: typecheck properly"
|
||||
ty,
|
||||
self.ci.nodes[then_var.value].ty,
|
||||
"TODO: typecheck properly: {} != {}\n{}",
|
||||
self.ty_display(ty),
|
||||
self.ty_display(self.ci.nodes[then_var.value].ty),
|
||||
self.errors.borrow()
|
||||
);
|
||||
|
||||
let inps = [self.ci.ctrl, then_var.value, else_var.value];
|
||||
|
@ -1826,33 +1921,35 @@ impl Codegen {
|
|||
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||
self.ci.nodes.check_scope_integrity(&break_scope);
|
||||
self.ci.nodes.check_scope_integrity(&scope);
|
||||
for ((dest_var, scope_var), loop_var) in
|
||||
for ((dest_var, mut scope_var), loop_var) in
|
||||
self.ci.vars.iter_mut().zip(scope).zip(break_scope)
|
||||
{
|
||||
if loop_var.value == 0 {
|
||||
self.ci.nodes.unlock(loop_var.value);
|
||||
debug_assert!(loop_var.value == dest_var.value);
|
||||
self.ci.nodes.unlock(dest_var.value);
|
||||
dest_var.value = scope_var.value;
|
||||
continue;
|
||||
}
|
||||
|
||||
debug_assert_eq!(self.ci.nodes[scope_var.value].kind, Kind::Phi);
|
||||
|
||||
if scope_var.value == loop_var.value {
|
||||
let orig = self.ci.nodes[scope_var.value].inputs[1];
|
||||
self.ci.nodes.lock(orig);
|
||||
self.ci.nodes.unlock(loop_var.value);
|
||||
self.ci.nodes.unlock_remove(scope_var.value);
|
||||
self.ci.nodes.unlock_remove(dest_var.value);
|
||||
dest_var.value = orig;
|
||||
continue;
|
||||
}
|
||||
|
||||
self.ci.nodes.unlock(loop_var.value);
|
||||
let phy = self.ci.nodes.modify_input(scope_var.value, 2, loop_var.value);
|
||||
self.ci.nodes.unlock_remove(dest_var.value);
|
||||
dest_var.value = phy;
|
||||
|
||||
if loop_var.value != 0 {
|
||||
self.ci.nodes.unlock(scope_var.value);
|
||||
if loop_var.value != scope_var.value {
|
||||
scope_var.value =
|
||||
self.ci.nodes.modify_input(scope_var.value, 2, loop_var.value);
|
||||
self.ci.nodes.lock(scope_var.value);
|
||||
} else {
|
||||
let phi = &self.ci.nodes[scope_var.value];
|
||||
debug_assert_eq!(phi.kind, Kind::Phi);
|
||||
debug_assert_eq!(phi.inputs[2], 0);
|
||||
let prev = phi.inputs[1];
|
||||
self.ci.nodes.replace(scope_var.value, prev);
|
||||
scope_var.value = prev;
|
||||
self.ci.nodes.lock(prev);
|
||||
}
|
||||
}
|
||||
|
||||
if dest_var.value == 0 {
|
||||
self.ci.nodes.unlock_remove(dest_var.value);
|
||||
dest_var.value = scope_var.value;
|
||||
self.ci.nodes.lock(dest_var.value);
|
||||
}
|
||||
|
||||
self.ci.nodes.unlock_remove(scope_var.value);
|
||||
}
|
||||
|
||||
self.ci.nodes.unlock(self.ci.ctrl);
|
||||
|
@ -2198,7 +2295,7 @@ impl Codegen {
|
|||
|
||||
fn color_control(&mut self, mut ctrl: Nid) -> Option<Nid> {
|
||||
for _ in 0..30 {
|
||||
match self.ci.nodes[ctrl].kind.clone() {
|
||||
match self.ci.nodes[ctrl].kind {
|
||||
Kind::Start => unreachable!(),
|
||||
Kind::End => unreachable!(),
|
||||
Kind::Return => {
|
||||
|
@ -2250,7 +2347,7 @@ impl Codegen {
|
|||
(None, Some(n)) | (Some(n), None) => n,
|
||||
(Some(l), Some(r)) if l == r => l,
|
||||
(Some(left), Some(right)) => {
|
||||
todo!()
|
||||
todo!("{:?} {:?}", self.ci.nodes[left], self.ci.nodes[right]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2258,14 +2355,12 @@ impl Codegen {
|
|||
return Some(dest);
|
||||
}
|
||||
|
||||
debug_assert!(left_unreachable.is_none() || right_unreachable.is_none());
|
||||
|
||||
debug_assert_eq!(self.ci.nodes[dest].kind, Kind::Region);
|
||||
|
||||
for i in 0..self.ci.nodes[dest].outputs.len() {
|
||||
let o = self.ci.nodes[dest].outputs[i];
|
||||
if self.ci.nodes[o].kind == Kind::Phi {
|
||||
self.color_phy(o);
|
||||
self.color_phi(o);
|
||||
self.ci.nodes[o].depth = self.ci.loop_depth;
|
||||
}
|
||||
}
|
||||
|
@ -2284,15 +2379,15 @@ impl Codegen {
|
|||
}
|
||||
|
||||
for i in 0..self.ci.nodes[ctrl].outputs.len() {
|
||||
let maybe_phy = self.ci.nodes[ctrl].outputs[i];
|
||||
let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phy]
|
||||
let maybe_phi = self.ci.nodes[ctrl].outputs[i];
|
||||
let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phi]
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
_ = self.color_expr_consume(inputs[1]);
|
||||
self.ci.nodes[maybe_phy].depth = self.ci.loop_depth;
|
||||
self.ci.set_next_color(maybe_phy);
|
||||
self.ci.nodes[maybe_phi].depth = self.ci.loop_depth;
|
||||
self.ci.set_next_color(maybe_phi);
|
||||
}
|
||||
|
||||
self.ci.nodes[ctrl].lock_rc = self.ci.code.len() as _;
|
||||
|
@ -2307,7 +2402,7 @@ impl Codegen {
|
|||
);
|
||||
|
||||
for i in 0..self.ci.nodes[ctrl].outputs.len() {
|
||||
self.color_phy(self.ci.nodes[ctrl].outputs[i]);
|
||||
self.color_phi(self.ci.nodes[ctrl].outputs[i]);
|
||||
}
|
||||
|
||||
self.ci.loop_depth -= 1;
|
||||
|
@ -2321,8 +2416,8 @@ impl Codegen {
|
|||
unreachable!()
|
||||
}
|
||||
|
||||
fn color_phy(&mut self, maybe_phy: Nid) {
|
||||
let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phy] else {
|
||||
fn color_phi(&mut self, maybe_phi: Nid) {
|
||||
let Node { kind: Kind::Phi, ref inputs, .. } = self.ci.nodes[maybe_phi] else {
|
||||
return;
|
||||
};
|
||||
let &[region, left, right] = inputs.as_slice() else { unreachable!() };
|
||||
|
@ -2330,14 +2425,14 @@ impl Codegen {
|
|||
let lcolor = self.color_expr_consume(left);
|
||||
let rcolor = self.color_expr_consume(right);
|
||||
|
||||
if self.ci.nodes[maybe_phy].color != 0 {
|
||||
// loop phy
|
||||
if self.ci.nodes[maybe_phi].color != 0 {
|
||||
// loop phi
|
||||
if let Some(c) = rcolor
|
||||
&& !self.ci.nodes.climb_expr(right, |i, n| {
|
||||
matches!(n.kind, Kind::Phi) && n.inputs[0] == region && i != maybe_phy
|
||||
matches!(n.kind, Kind::Phi) && n.inputs[0] == region && i != maybe_phi
|
||||
})
|
||||
{
|
||||
self.ci.recolor(right, c, self.ci.nodes[maybe_phy].color);
|
||||
self.ci.recolor(right, c, self.ci.nodes[maybe_phi].color);
|
||||
}
|
||||
} else {
|
||||
let color = match (lcolor, rcolor) {
|
||||
|
@ -2348,7 +2443,7 @@ impl Codegen {
|
|||
lc
|
||||
}
|
||||
};
|
||||
self.ci.set_color(maybe_phy, color);
|
||||
self.ci.set_color(maybe_phi, color);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2396,7 +2491,7 @@ impl Codegen {
|
|||
|
||||
fn emit_control(&mut self, mut ctrl: Nid) -> Option<Nid> {
|
||||
for _ in 0..30 {
|
||||
match self.ci.nodes[ctrl].kind.clone() {
|
||||
match self.ci.nodes[ctrl].kind {
|
||||
Kind::Start => unreachable!(),
|
||||
Kind::End => unreachable!(),
|
||||
Kind::Return => {
|
||||
|
@ -2439,14 +2534,14 @@ impl Codegen {
|
|||
let mut parama = self.tys.parama(ret);
|
||||
for i in 1..self.ci.nodes[ctrl].inputs.len() {
|
||||
let arg = self.ci.nodes[ctrl].inputs[i];
|
||||
node_loc!(self, arg) = match self.tys.size_of(self.tof(arg)) {
|
||||
|
||||
let dst = match self.tys.size_of(self.tof(arg)) {
|
||||
0 => continue,
|
||||
1..=8 => Loc { reg: parama.next() },
|
||||
s => todo!("{s}"),
|
||||
};
|
||||
self.ci.regs.mark_leaked(node_loc!(self, arg).reg);
|
||||
self.emit_expr_consume(arg);
|
||||
self.ci.nodes[arg].depth = 0;
|
||||
self.ci.emit(instrs::cp(dst.reg, node_loc!(self, arg).reg));
|
||||
}
|
||||
|
||||
let reloc = Reloc::new(self.ci.code.len(), 3, 4);
|
||||
|
@ -2770,8 +2865,7 @@ impl Codegen {
|
|||
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);
|
||||
} else if color.loc != Loc::default() {
|
||||
self.ci.regs.free(color.loc.reg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -64d
|
||||
ST r31, r254, 0a, 64h
|
||||
ADDI64 r254, r254, -80d
|
||||
ST r31, r254, 0a, 80h
|
||||
JAL r31, r0, :check_platform
|
||||
CP r32, r1
|
||||
LI64 r33, 100d
|
||||
|
@ -17,29 +17,31 @@ main:
|
|||
CP r3, r36
|
||||
CP r4, r33
|
||||
JAL r31, r0, :set_pixel
|
||||
CP r37, r35
|
||||
ADDI64 r37, r37, 1d
|
||||
CP r35, r37
|
||||
CP r37, r1
|
||||
CP r38, r35
|
||||
ADDI64 r38, r38, 1d
|
||||
CP r35, r38
|
||||
JMP :1
|
||||
0: CP r2, r35
|
||||
CP r3, r36
|
||||
CP r4, r33
|
||||
JAL r31, r0, :set_pixel
|
||||
CP r38, r1
|
||||
LI64 r35, 0d
|
||||
CP r37, r36
|
||||
ADDI64 r37, r37, 1d
|
||||
CP r36, r37
|
||||
1: CP r37, r36
|
||||
CP r38, r33
|
||||
CMPS r37, r37, r38
|
||||
CMPUI r37, r37, 0d
|
||||
NOT r37, r37
|
||||
JEQ r37, r0, :2
|
||||
CP r39, r36
|
||||
ADDI64 r39, r39, 1d
|
||||
CP r36, r39
|
||||
1: CP r39, r36
|
||||
CP r40, r33
|
||||
CMPS r39, r39, r40
|
||||
CMPUI r39, r39, 0d
|
||||
NOT r39, r39
|
||||
JEQ r39, r0, :2
|
||||
JMP :3
|
||||
2: JMP :4
|
||||
3: LI64 r1, 0d
|
||||
LD r31, r254, 0a, 64h
|
||||
ADDI64 r254, r254, 64d
|
||||
LD r31, r254, 0a, 80h
|
||||
ADDI64 r254, r254, 80d
|
||||
JALA r0, r31, 0a
|
||||
set_pixel:
|
||||
ADDI64 r254, r254, -32d
|
||||
|
@ -67,6 +69,6 @@ x86_fb_ptr:
|
|||
LD r31, r254, 0a, 8h
|
||||
ADDI64 r254, r254, 8d
|
||||
JALA r0, r31, 0a
|
||||
code size: 505
|
||||
code size: 511
|
||||
ret: 0
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -16d
|
||||
ST r31, r254, 0a, 16h
|
||||
ADDI64 r254, r254, -32d
|
||||
ST r31, r254, 0a, 32h
|
||||
LRA r32, r0, :complex_global_var
|
||||
LRA r33, r0, :complex_global_var
|
||||
LD r34, r33, 0a, 8h
|
||||
ADDI64 r34, r34, 5d
|
||||
ST r34, r32, 0a, 8h
|
||||
LRA r32, r0, :complex_global_var
|
||||
LD r1, r32, 0a, 8h
|
||||
LD r31, r254, 0a, 16h
|
||||
ADDI64 r254, r254, 16d
|
||||
LD r31, r254, 0a, 32h
|
||||
ADDI64 r254, r254, 32d
|
||||
JALA r0, r31, 0a
|
||||
code size: 267
|
||||
ret: 50
|
||||
code size: 318
|
||||
ret: 55
|
||||
status: Ok(())
|
||||
|
|
|
@ -27,12 +27,11 @@ fib:
|
|||
CP r35, r32
|
||||
ADDI64 r35, r35, -1d
|
||||
CP r32, r35
|
||||
LI64 r35, 0d
|
||||
JMP :2
|
||||
1: CP r1, r33
|
||||
LD r31, r254, 0a, 48h
|
||||
ADDI64 r254, r254, 48d
|
||||
JALA r0, r31, 0a
|
||||
code size: 258
|
||||
code size: 248
|
||||
ret: 55
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -104d
|
||||
ST r31, r254, 0a, 104h
|
||||
ADDI64 r254, r254, -96d
|
||||
ST r31, r254, 0a, 96h
|
||||
JAL r31, r0, :check_platform
|
||||
LI64 r32, 0d
|
||||
CP r33, r32
|
||||
|
@ -12,25 +12,30 @@ main:
|
|||
CP r39, r37
|
||||
4: ADDI64 r40, r35, 1d
|
||||
JGTS r33, r40, :0
|
||||
CP r2, r33
|
||||
CP r3, r33
|
||||
CP r4, r37
|
||||
JAL r31, r0, :set_pixel
|
||||
CP r41, r4
|
||||
ADDI64 r42, r3, 1d
|
||||
CP r43, r3
|
||||
CP r41, r37
|
||||
ADDI64 r33, r33, 1d
|
||||
CP r42, r33
|
||||
JMP :1
|
||||
0: JAL r31, r0, :set_pixel
|
||||
CP r41, r4
|
||||
CP r42, r32
|
||||
ADDI64 r43, r3, 1d
|
||||
1: JNE r43, r41, :2
|
||||
0: CP r2, r33
|
||||
CP r3, r38
|
||||
CP r4, r39
|
||||
JAL r31, r0, :set_pixel
|
||||
CP r41, r39
|
||||
CP r33, r32
|
||||
ADDI64 r42, r38, 1d
|
||||
1: JNE r42, r41, :2
|
||||
JMP :3
|
||||
2: CP r2, r42
|
||||
CP r35, r34
|
||||
CP r4, r36
|
||||
CP r3, r43
|
||||
CP r4, r41
|
||||
2: CP r35, r34
|
||||
CP r37, r36
|
||||
CP r38, r42
|
||||
CP r39, r41
|
||||
JMP :4
|
||||
3: LD r31, r254, 0a, 104h
|
||||
ADDI64 r254, r254, 104d
|
||||
3: LD r31, r254, 0a, 96h
|
||||
ADDI64 r254, r254, 96d
|
||||
JALA r0, r31, 0a
|
||||
set_pixel:
|
||||
ADDI64 r254, r254, -8d
|
||||
|
@ -53,6 +58,7 @@ x86_fb_ptr:
|
|||
LD r31, r254, 0a, 8h
|
||||
ADDI64 r254, r254, 8d
|
||||
JALA r0, r31, 0a
|
||||
code size: 422
|
||||
timed out
|
||||
code size: 437
|
||||
ret: 0
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -16d
|
||||
ST r31, r254, 0a, 16h
|
||||
LI64 r2, 10d
|
||||
ADDI64 r254, r254, -24d
|
||||
ST r31, r254, 0a, 24h
|
||||
LI64 r32, 10d
|
||||
CP r2, r32
|
||||
JAL r31, r0, :add_one
|
||||
CP r32, r1
|
||||
LI64 r2, 20d
|
||||
LI64 r33, 20d
|
||||
CP r2, r33
|
||||
JAL r31, r0, :add_two
|
||||
ADD64 r1, r1, r32
|
||||
LD r31, r254, 0a, 16h
|
||||
ADDI64 r254, r254, 16d
|
||||
LD r31, r254, 0a, 24h
|
||||
ADDI64 r254, r254, 24d
|
||||
JALA r0, r31, 0a
|
||||
add_two:
|
||||
ADDI64 r254, r254, -8d
|
||||
|
@ -26,6 +28,6 @@ add_one:
|
|||
LD r31, r254, 0a, 8h
|
||||
ADDI64 r254, r254, 8d
|
||||
JALA r0, r31, 0a
|
||||
code size: 254
|
||||
code size: 260
|
||||
ret: 33
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,28 +1,31 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -8d
|
||||
ST r31, r254, 0a, 8h
|
||||
LI64 r2, 10d
|
||||
ADDI64 r254, r254, -16d
|
||||
ST r31, r254, 0a, 16h
|
||||
LI64 r32, 10d
|
||||
CP r2, r32
|
||||
JAL r31, r0, :fib
|
||||
LD r31, r254, 0a, 8h
|
||||
ADDI64 r254, r254, 8d
|
||||
LD r31, r254, 0a, 16h
|
||||
ADDI64 r254, r254, 16d
|
||||
JALA r0, r31, 0a
|
||||
fib:
|
||||
ADDI64 r254, r254, -32d
|
||||
ST r31, r254, 0a, 32h
|
||||
ADDI64 r254, r254, -40d
|
||||
ST r31, r254, 0a, 40h
|
||||
CP r32, r2
|
||||
LI64 r33, 2d
|
||||
JGTS r32, r33, :0
|
||||
LI64 r1, 1d
|
||||
JMP :1
|
||||
0: ADDI64 r2, r32, -1d
|
||||
0: ADDI64 r34, r32, -1d
|
||||
CP r2, r34
|
||||
JAL r31, r0, :fib
|
||||
CP r34, r1
|
||||
SUB64 r2, r32, r33
|
||||
SUB64 r35, r32, r33
|
||||
CP r2, r35
|
||||
JAL r31, r0, :fib
|
||||
ADD64 r1, r1, r34
|
||||
1: LD r31, r254, 0a, 32h
|
||||
ADDI64 r254, r254, 32d
|
||||
ADD64 r1, r34, r1
|
||||
1: LD r31, r254, 0a, 40h
|
||||
ADDI64 r254, r254, 40d
|
||||
JALA r0, r31, 0a
|
||||
code size: 212
|
||||
code size: 221
|
||||
ret: 55
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -8d
|
||||
ST r31, r254, 0a, 8h
|
||||
LI64 r2, 10d
|
||||
ADDI64 r254, r254, -16d
|
||||
ST r31, r254, 0a, 16h
|
||||
LI64 r32, 10d
|
||||
CP r2, r32
|
||||
JAL r31, r0, :fib
|
||||
LD r31, r254, 0a, 8h
|
||||
ADDI64 r254, r254, 8d
|
||||
LD r31, r254, 0a, 16h
|
||||
ADDI64 r254, r254, 16d
|
||||
JALA r0, r31, 0a
|
||||
fib:
|
||||
ADDI64 r254, r254, -56d
|
||||
|
@ -25,6 +26,6 @@ fib:
|
|||
1: LD r31, r254, 0a, 56h
|
||||
ADDI64 r254, r254, 56d
|
||||
JALA r0, r31, 0a
|
||||
code size: 204
|
||||
code size: 207
|
||||
ret: 55
|
||||
status: Ok(())
|
||||
|
|
Loading…
Reference in a new issue