forked from AbleOS/holey-bytes
if a phy does not depend of different phy in the same loop we can modify it in place saving a register copy
This commit is contained in:
parent
803095c0c5
commit
49387dbe16
|
@ -794,7 +794,7 @@ main := fn(): int {
|
||||||
multiple_breaks := fn(arg: int): int {
|
multiple_breaks := fn(arg: int): int {
|
||||||
loop if arg < 10 {
|
loop if arg < 10 {
|
||||||
arg += 1
|
arg += 1
|
||||||
//if arg == 3 break
|
if arg == 3 break
|
||||||
} else break
|
} else break
|
||||||
return arg
|
return arg
|
||||||
}
|
}
|
||||||
|
@ -809,7 +809,7 @@ multiple_breaks := fn(arg: int): int {
|
||||||
// } else break
|
// } else break
|
||||||
// return arg
|
// return arg
|
||||||
//}
|
//}
|
||||||
//
|
|
||||||
//continue_and_state_change := fn(arg: int): int {
|
//continue_and_state_change := fn(arg: int): int {
|
||||||
// loop if arg < 10 {
|
// loop if arg < 10 {
|
||||||
// if arg == 2 {
|
// if arg == 2 {
|
||||||
|
|
|
@ -20,6 +20,7 @@ use {
|
||||||
mem,
|
mem,
|
||||||
ops::{self, Range},
|
ops::{self, Range},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
usize,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,6 +36,37 @@ macro_rules! node_loc {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Drom(&'static str);
|
||||||
|
|
||||||
|
impl Drop for Drom {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
log::inf!("{}", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct BitSet {
|
||||||
|
data: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitSet {
|
||||||
|
const ELEM_SIZE: usize = std::mem::size_of::<usize>() * 8;
|
||||||
|
|
||||||
|
pub fn clear(&mut self, bit_size: usize) {
|
||||||
|
let new_len = (bit_size + Self::ELEM_SIZE - 1) / Self::ELEM_SIZE;
|
||||||
|
self.data.clear();
|
||||||
|
self.data.resize(new_len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, idx: usize) -> bool {
|
||||||
|
let data_idx = idx / Self::ELEM_SIZE;
|
||||||
|
let sub_idx = idx % Self::ELEM_SIZE;
|
||||||
|
let prev = self.data[data_idx] & (1 << sub_idx);
|
||||||
|
self.data[data_idx] |= 1 << sub_idx;
|
||||||
|
prev == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Nid = u32;
|
type Nid = u32;
|
||||||
|
|
||||||
mod reg {
|
mod reg {
|
||||||
|
@ -431,13 +463,19 @@ mod ty {
|
||||||
|
|
||||||
struct Nodes {
|
struct Nodes {
|
||||||
values: Vec<PoolSlot>,
|
values: Vec<PoolSlot>,
|
||||||
|
visited: BitSet,
|
||||||
free: u32,
|
free: u32,
|
||||||
lookup: HashMap<(Kind, [Nid; MAX_INPUTS], ty::Id), Nid>,
|
lookup: HashMap<(Kind, [Nid; MAX_INPUTS], ty::Id), Nid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Nodes {
|
impl Default for Nodes {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { values: Default::default(), free: u32::MAX, lookup: Default::default() }
|
Self {
|
||||||
|
values: Default::default(),
|
||||||
|
free: u32::MAX,
|
||||||
|
lookup: Default::default(),
|
||||||
|
visited: Default::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,6 +759,13 @@ impl Nodes {
|
||||||
self.remove(id)
|
self.remove(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn iter(&self) -> impl DoubleEndedIterator<Item = (Nid, &Node)> {
|
||||||
|
self.values.iter().enumerate().filter_map(|(i, s)| match s {
|
||||||
|
PoolSlot::Value(v) => Some((i as _, v)),
|
||||||
|
PoolSlot::Next(_) => None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter, node: Nid, rcs: &mut [usize]) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter, node: Nid, rcs: &mut [usize]) -> fmt::Result {
|
||||||
let mut is_ready = || {
|
let mut is_ready = || {
|
||||||
if rcs[node as usize] == 0 {
|
if rcs[node as usize] == 0 {
|
||||||
|
@ -803,6 +848,27 @@ impl Nodes {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn graphviz_low(&self, out: &mut String) -> std::fmt::Result {
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
for (i, node) in self.iter() {
|
||||||
|
let color = if self.is_cfg(i) { "yellow" } else { "white" };
|
||||||
|
writeln!(out, "node{i}[label=\"{}\" color={color}]", node.kind)?;
|
||||||
|
for &o in &node.outputs {
|
||||||
|
let color = if self.is_cfg(i) && self.is_cfg(o) { "red" } else { "black" };
|
||||||
|
writeln!(out, "node{o} -> node{i}[color={color}]",)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn graphviz(&self) {
|
||||||
|
let out = &mut String::new();
|
||||||
|
_ = self.graphviz_low(out);
|
||||||
|
log::inf!("{out}");
|
||||||
|
}
|
||||||
|
|
||||||
fn is_cfg(&self, o: Nid) -> bool {
|
fn is_cfg(&self, o: Nid) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self[o].kind,
|
self[o].kind,
|
||||||
|
@ -819,49 +885,63 @@ impl Nodes {
|
||||||
|
|
||||||
fn check_final_integrity(&self) {
|
fn check_final_integrity(&self) {
|
||||||
let mut failed = false;
|
let mut failed = false;
|
||||||
for (slot, i) in self.values.iter().zip(0u32..) {
|
for (i, node) in self.iter() {
|
||||||
match slot {
|
debug_assert_eq!(node.lock_rc, 0, "{:?}", node.kind);
|
||||||
PoolSlot::Value(node) => {
|
if !matches!(node.kind, Kind::Return | Kind::End) && node.outputs.is_empty() {
|
||||||
debug_assert_eq!(node.lock_rc, 0, "{:?}", node.kind);
|
log::err!("outputs are empry {i} {:?}", node.kind);
|
||||||
if !matches!(node.kind, Kind::Return | Kind::End) && node.outputs.is_empty() {
|
failed = true;
|
||||||
log::err!("outputs are empry {i} {:?}", node.kind);
|
}
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for &o in &node.outputs {
|
for &o in &node.outputs {
|
||||||
let mut occurs = 0;
|
let mut occurs = 0;
|
||||||
let other = match &self.values[o as usize] {
|
let other = match &self.values[o as usize] {
|
||||||
PoolSlot::Value(other) => other,
|
PoolSlot::Value(other) => other,
|
||||||
PoolSlot::Next(_) => {
|
PoolSlot::Next(_) => {
|
||||||
log::err!(
|
log::err!("the edge points to dropped node: {i} {:?} {o}", node.kind,);
|
||||||
"the edge points to dropped node: {i} {:?} {o}",
|
failed = true;
|
||||||
node.kind,
|
continue;
|
||||||
);
|
|
||||||
failed = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Kind::Call { ref args, .. } = other.kind {
|
|
||||||
occurs = args.iter().filter(|&&el| el == i).count();
|
|
||||||
}
|
|
||||||
occurs += self[o].inputs.iter().filter(|&&el| el == i).count();
|
|
||||||
if occurs == 0 {
|
|
||||||
log::err!(
|
|
||||||
"the edge is not bidirectional: {i} {:?} {o} {:?}",
|
|
||||||
node.kind,
|
|
||||||
other.kind
|
|
||||||
);
|
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if let Kind::Call { ref args, .. } = other.kind {
|
||||||
|
occurs = args.iter().filter(|&&el| el == i).count();
|
||||||
|
}
|
||||||
|
occurs += self[o].inputs.iter().filter(|&&el| el == i).count();
|
||||||
|
if occurs == 0 {
|
||||||
|
log::err!(
|
||||||
|
"the edge is not bidirectional: {i} {:?} {o} {:?}",
|
||||||
|
node.kind,
|
||||||
|
other.kind
|
||||||
|
);
|
||||||
|
failed = true;
|
||||||
}
|
}
|
||||||
PoolSlot::Next(_) => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if failed {
|
if failed {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_scope_integrity(&self, scope: &[Variable]) {
|
||||||
|
for v in scope {
|
||||||
|
debug_assert!(self[v.value].lock_rc > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn climb(&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 {
|
||||||
|
{ nodes[from].inputs }.iter().any(|&n| {
|
||||||
|
n != Nid::MAX
|
||||||
|
&& nodes.visited.set(n as usize)
|
||||||
|
&& (for_each(n, &nodes[n]) || climb_impl(nodes, n, for_each))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
self.visited.clear(self.values.len());
|
||||||
|
climb_impl(self, from, &mut for_each)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Index<u32> for Nodes {
|
impl ops::Index<u32> for Nodes {
|
||||||
|
@ -912,6 +992,18 @@ impl Kind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Kind {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Kind::ConstInt { value } => write!(f, "#{value}"),
|
||||||
|
Kind::Tuple { index } => write!(f, "tupl[{index}]"),
|
||||||
|
Kind::BinOp { op } => write!(f, "{op}"),
|
||||||
|
Kind::Call { func, .. } => write!(f, "call {func}"),
|
||||||
|
slf => write!(f, "{slf:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const MAX_INPUTS: usize = 3;
|
const MAX_INPUTS: usize = 3;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1534,6 +1626,8 @@ impl Codegen {
|
||||||
loob.scope[index].value = phy;
|
loob.scope[index].value = phy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
|
|
||||||
Some(self.ci.vars[index].value)
|
Some(self.ci.vars[index].value)
|
||||||
}
|
}
|
||||||
Expr::BinOp { left: &Expr::Ident { id, .. }, op: TokenKind::Decl, right } => {
|
Expr::BinOp { left: &Expr::Ident { id, .. }, op: TokenKind::Decl, right } => {
|
||||||
|
@ -1617,17 +1711,20 @@ impl Codegen {
|
||||||
for then_var in then_scope {
|
for then_var in then_scope {
|
||||||
self.ci.nodes.unlock_remove(then_var.value);
|
self.ci.nodes.unlock_remove(then_var.value);
|
||||||
}
|
}
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
return None;
|
return None;
|
||||||
} else if lcntrl == Nid::MAX {
|
} else if lcntrl == Nid::MAX {
|
||||||
for then_var in then_scope {
|
for then_var in then_scope {
|
||||||
self.ci.nodes.unlock_remove(then_var.value);
|
self.ci.nodes.unlock_remove(then_var.value);
|
||||||
}
|
}
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
return Some(0);
|
return Some(0);
|
||||||
} else if rcntrl == Nid::MAX {
|
} else if rcntrl == Nid::MAX {
|
||||||
for else_var in &self.ci.vars {
|
for else_var in &self.ci.vars {
|
||||||
self.ci.nodes.unlock_remove(else_var.value);
|
self.ci.nodes.unlock_remove(else_var.value);
|
||||||
}
|
}
|
||||||
self.ci.vars = then_scope;
|
self.ci.vars = then_scope;
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
self.ci.ctrl = lcntrl;
|
self.ci.ctrl = lcntrl;
|
||||||
return Some(0);
|
return Some(0);
|
||||||
}
|
}
|
||||||
|
@ -1652,6 +1749,7 @@ impl Codegen {
|
||||||
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
||||||
self.ci.nodes.lock(else_var.value);
|
self.ci.nodes.lock(else_var.value);
|
||||||
}
|
}
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
|
|
||||||
Some(0)
|
Some(0)
|
||||||
}
|
}
|
||||||
|
@ -1700,6 +1798,7 @@ impl Codegen {
|
||||||
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
||||||
self.ci.nodes.lock(else_var.value);
|
self.ci.nodes.lock(else_var.value);
|
||||||
}
|
}
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.nodes.modify_input(node, 1, self.ci.ctrl);
|
self.ci.nodes.modify_input(node, 1, self.ci.ctrl);
|
||||||
|
@ -1709,8 +1808,13 @@ impl Codegen {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.ci.nodes.lock(self.ci.ctrl);
|
||||||
|
|
||||||
std::mem::swap(&mut self.ci.vars, &mut break_scope);
|
std::mem::swap(&mut self.ci.vars, &mut break_scope);
|
||||||
|
|
||||||
|
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, scope_var), loop_var) in
|
||||||
self.ci.vars.iter_mut().zip(scope).zip(break_scope)
|
self.ci.vars.iter_mut().zip(scope).zip(break_scope)
|
||||||
{
|
{
|
||||||
|
@ -1740,6 +1844,8 @@ impl Codegen {
|
||||||
dest_var.value = phy;
|
dest_var.value = phy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.ci.nodes.unlock(self.ci.ctrl);
|
||||||
|
|
||||||
Some(0)
|
Some(0)
|
||||||
}
|
}
|
||||||
Expr::Break { pos } => {
|
Expr::Break { pos } => {
|
||||||
|
@ -1774,12 +1880,15 @@ impl Codegen {
|
||||||
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
||||||
self.ci.nodes.lock(else_var.value);
|
self.ci.nodes.lock(else_var.value);
|
||||||
}
|
}
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
|
self.ci.nodes.check_scope_integrity(&loob.break_scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.ctrl = self.ci.end;
|
self.ci.ctrl = self.ci.end;
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
Expr::Continue { pos } => {
|
Expr::Continue { pos } => {
|
||||||
|
todo!();
|
||||||
let Some(loob) = self.ci.loops.last_mut() else {
|
let Some(loob) = self.ci.loops.last_mut() else {
|
||||||
self.report(pos, "break outside a loop");
|
self.report(pos, "break outside a loop");
|
||||||
return None;
|
return None;
|
||||||
|
@ -1813,6 +1922,7 @@ impl Codegen {
|
||||||
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
else_var.value = self.ci.nodes.new_node(ty, Kind::Phi, inps);
|
||||||
self.ci.nodes.lock(else_var.value);
|
self.ci.nodes.lock(else_var.value);
|
||||||
}
|
}
|
||||||
|
self.ci.nodes.check_scope_integrity(&self.ci.vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.ctrl = self.ci.end;
|
self.ci.ctrl = self.ci.end;
|
||||||
|
@ -1883,10 +1993,14 @@ impl Codegen {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_ = self.ci.nodes[self.ci.ctrl];
|
||||||
|
_ = self.ci.nodes[self.ci.end];
|
||||||
|
_ = self.ci.nodes[value];
|
||||||
|
|
||||||
let inps = [self.ci.ctrl, self.ci.end, value];
|
let inps = [self.ci.ctrl, self.ci.end, value];
|
||||||
|
|
||||||
let out = &mut String::new();
|
let out = &mut String::new();
|
||||||
self.report_log_to(pos, "returning here", out);
|
self.report_log_to(pos, "returning here", out);
|
||||||
log::dbg!("{out}");
|
|
||||||
self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Return, inps);
|
self.ci.ctrl = self.ci.nodes.new_node(ty::VOID, Kind::Return, inps);
|
||||||
|
|
||||||
let expected = *self.ci.ret.get_or_insert(self.tof(value));
|
let expected = *self.ci.ret.get_or_insert(self.tof(value));
|
||||||
|
@ -2006,6 +2120,8 @@ impl Codegen {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.errors.borrow().is_empty() {
|
if self.errors.borrow().is_empty() {
|
||||||
|
self.ci.nodes.graphviz();
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
self.ci.nodes.check_final_integrity();
|
self.ci.nodes.check_final_integrity();
|
||||||
|
@ -2121,11 +2237,21 @@ impl Codegen {
|
||||||
let left_unreachable = self.color_control(self.ci.nodes[ctrl].outputs[0]);
|
let left_unreachable = self.color_control(self.ci.nodes[ctrl].outputs[0]);
|
||||||
let right_unreachable = self.color_control(self.ci.nodes[ctrl].outputs[1]);
|
let right_unreachable = self.color_control(self.ci.nodes[ctrl].outputs[1]);
|
||||||
|
|
||||||
let dest = left_unreachable.or(right_unreachable)?;
|
let dest = match (left_unreachable, right_unreachable) {
|
||||||
|
(None, None) => return None,
|
||||||
|
(None, Some(n)) | (Some(n), None) => n,
|
||||||
|
(Some(l), Some(r)) if l == r => l,
|
||||||
|
(Some(left), Some(right)) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if self.ci.nodes[dest].kind == Kind::Loop {
|
if self.ci.nodes[dest].kind == Kind::Loop {
|
||||||
return Some(dest);
|
return Some(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug_assert!(left_unreachable.is_none() || right_unreachable.is_none());
|
||||||
|
|
||||||
debug_assert_eq!(self.ci.nodes[dest].kind, Kind::Region);
|
debug_assert_eq!(self.ci.nodes[dest].kind, Kind::Region);
|
||||||
|
|
||||||
for i in 0..self.ci.nodes[dest].outputs.len() {
|
for i in 0..self.ci.nodes[dest].outputs.len() {
|
||||||
|
@ -2189,7 +2315,7 @@ impl Codegen {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn color_phy(&mut self, maybe_phy: Nid) {
|
fn color_phy(&mut self, maybe_phy: Nid) {
|
||||||
let Node { kind: Kind::Phi, inputs: [_, left, right], .. } = self.ci.nodes[maybe_phy]
|
let Node { kind: Kind::Phi, inputs: [region, left, right], .. } = self.ci.nodes[maybe_phy]
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -2198,12 +2324,14 @@ impl Codegen {
|
||||||
let rcolor = self.color_expr_consume(right);
|
let rcolor = self.color_expr_consume(right);
|
||||||
|
|
||||||
if self.ci.nodes[maybe_phy].color != 0 {
|
if self.ci.nodes[maybe_phy].color != 0 {
|
||||||
//if let Some(c) = lcolor {
|
// loop phy
|
||||||
// self.ci.recolor(left, c, self.ci.nodes[maybe_phy].color);
|
if let Some(c) = rcolor
|
||||||
//}
|
&& !self.ci.nodes.climb(right, |i, n| {
|
||||||
//if let Some(c) = rcolor {
|
matches!(n.kind, Kind::Phi) && n.inputs[0] == region && i != maybe_phy
|
||||||
// self.ci.recolor(right, c, self.ci.nodes[maybe_phy].color);
|
})
|
||||||
//}
|
{
|
||||||
|
self.ci.recolor(right, c, self.ci.nodes[maybe_phy].color);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let color = match (lcolor, rcolor) {
|
let color = match (lcolor, rcolor) {
|
||||||
(None, None) => self.ci.next_color(),
|
(None, None) => self.ci.next_color(),
|
||||||
|
@ -2268,19 +2396,19 @@ impl Codegen {
|
||||||
let ret = self.ci.nodes[ctrl].inputs[2];
|
let ret = self.ci.nodes[ctrl].inputs[2];
|
||||||
if ret != 0 {
|
if ret != 0 {
|
||||||
// NOTE: this is safer less efficient way, maybe it will be needed
|
// NOTE: this is safer less efficient way, maybe it will be needed
|
||||||
//self.emit_expr_consume(ret);
|
// self.emit_expr_consume(ret);
|
||||||
//if node_color!(self, ret).call_count != self.ci.call_count {
|
// if node_color!(self, ret).call_count != self.ci.call_count {
|
||||||
// let src = node_loc!(self, ret);
|
// let src = node_loc!(self, ret);
|
||||||
// let loc = match self.tys.size_of(self.ci.ret.expect("TODO")) {
|
// let loc = match self.tys.size_of(self.ci.ret.expect("TODO")) {
|
||||||
// 0 => Loc::default(),
|
// 0 => Loc::default(),
|
||||||
// 1..=8 => Loc { reg: 1 },
|
// 1..=8 => Loc { reg: 1 },
|
||||||
// s => todo!("{s}"),
|
// s => todo!("{s}"),
|
||||||
// };
|
// };
|
||||||
// if src != loc {
|
// if src != loc {
|
||||||
// let inst = instrs::cp(loc.reg, src.reg);
|
// let inst = instrs::cp(loc.reg, src.reg);
|
||||||
// self.ci.emit(inst);
|
// self.ci.emit(inst);
|
||||||
// }
|
// }
|
||||||
//}
|
// }
|
||||||
|
|
||||||
node_loc!(self, ret) = match self.tys.size_of(self.ci.ret.expect("TODO")) {
|
node_loc!(self, ret) = match self.tys.size_of(self.ci.ret.expect("TODO")) {
|
||||||
0 => Loc::default(),
|
0 => Loc::default(),
|
||||||
|
|
|
@ -7,8 +7,8 @@ main:
|
||||||
ADDI64 r254, r254, 8d
|
ADDI64 r254, r254, 8d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
fib:
|
fib:
|
||||||
ADDI64 r254, r254, -64d
|
ADDI64 r254, r254, -56d
|
||||||
ST r31, r254, 0a, 64h
|
ST r31, r254, 0a, 56h
|
||||||
CP r32, r2
|
CP r32, r2
|
||||||
CP r33, r32
|
CP r33, r32
|
||||||
LI64 r34, 0d
|
LI64 r34, 0d
|
||||||
|
@ -17,15 +17,14 @@ fib:
|
||||||
CP r36, r35
|
CP r36, r35
|
||||||
2: JNE r33, r34, :0
|
2: JNE r33, r34, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: SUB64 r37, r33, r35
|
0: SUB64 r33, r33, r35
|
||||||
ADD64 r38, r1, r36
|
ADD64 r37, r1, r36
|
||||||
CP r33, r37
|
|
||||||
CP r1, r36
|
CP r1, r36
|
||||||
CP r36, r38
|
CP r36, r37
|
||||||
JMP :2
|
JMP :2
|
||||||
1: LD r31, r254, 0a, 64h
|
1: LD r31, r254, 0a, 56h
|
||||||
ADDI64 r254, r254, 64d
|
ADDI64 r254, r254, 56d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 207
|
code size: 204
|
||||||
ret: 55
|
ret: 55
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue