changing the gcm to not mutate nodes in recursive functions
This commit is contained in:
parent
86ca959ea3
commit
5df4fb8882
|
@ -25,6 +25,7 @@
|
||||||
pointer_is_aligned_to,
|
pointer_is_aligned_to,
|
||||||
maybe_uninit_fill
|
maybe_uninit_fill
|
||||||
)]
|
)]
|
||||||
|
#![feature(array_chunks)]
|
||||||
#![warn(clippy::dbg_macro)]
|
#![warn(clippy::dbg_macro)]
|
||||||
#![expect(internal_features)]
|
#![expect(internal_features)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
276
lang/src/son.rs
276
lang/src/son.rs
|
@ -124,24 +124,26 @@ impl Default for Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Nodes {
|
impl Nodes {
|
||||||
fn loop_depth(&self, target: Nid) -> LoopDepth {
|
fn loop_depth(&self, target: Nid, scheds: Option<&[Nid]>) -> LoopDepth {
|
||||||
self[target].loop_depth.set(match self[target].kind {
|
self[target].loop_depth.set(match self[target].kind {
|
||||||
Kind::Region | Kind::Entry | Kind::Then | Kind::Else | Kind::Call { .. } | Kind::If => {
|
Kind::Region | Kind::Entry | Kind::Then | Kind::Else | Kind::Call { .. } | Kind::If => {
|
||||||
if self[target].loop_depth.get() != 0 {
|
if self[target].loop_depth.get() != 0 {
|
||||||
return self[target].loop_depth.get();
|
return self[target].loop_depth.get();
|
||||||
}
|
}
|
||||||
self.loop_depth(self[target].inputs[0])
|
self.loop_depth(self[target].inputs[0], scheds)
|
||||||
}
|
}
|
||||||
Kind::Loop => {
|
Kind::Loop => {
|
||||||
if self[target].loop_depth.get() == self.loop_depth(self[target].inputs[0]) + 1 {
|
if self[target].loop_depth.get()
|
||||||
|
== self.loop_depth(self[target].inputs[0], scheds) + 1
|
||||||
|
{
|
||||||
return self[target].loop_depth.get();
|
return self[target].loop_depth.get();
|
||||||
}
|
}
|
||||||
let depth = self.loop_depth(self[target].inputs[0]) + 1;
|
let depth = self.loop_depth(self[target].inputs[0], scheds) + 1;
|
||||||
self[target].loop_depth.set(depth);
|
self[target].loop_depth.set(depth);
|
||||||
let mut cursor = self[target].inputs[1];
|
let mut cursor = self[target].inputs[1];
|
||||||
while cursor != target {
|
while cursor != target {
|
||||||
self[cursor].loop_depth.set(depth);
|
self[cursor].loop_depth.set(depth);
|
||||||
let next = self.idom(cursor);
|
let next = self.idom(cursor, scheds);
|
||||||
debug_assert_ne!(next, 0);
|
debug_assert_ne!(next, 0);
|
||||||
if matches!(self[cursor].kind, Kind::Then | Kind::Else) {
|
if matches!(self[cursor].kind, Kind::Then | Kind::Else) {
|
||||||
debug_assert_eq!(self[next].kind, Kind::If);
|
debug_assert_eq!(self[next].kind, Kind::If);
|
||||||
|
@ -159,17 +161,21 @@ impl Nodes {
|
||||||
self[target].loop_depth.get()
|
self[target].loop_depth.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn idepth(&self, target: Nid) -> IDomDepth {
|
fn idepth(&self, target: Nid, scheds: Option<&[Nid]>) -> IDomDepth {
|
||||||
if target == VOID {
|
if target == VOID {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if self[target].depth.get() == 0 {
|
if self[target].depth.get() == 0 {
|
||||||
let depth = match self[target].kind {
|
let depth = match self[target].kind {
|
||||||
Kind::End | Kind::Start => unreachable!("{:?}", self[target].kind),
|
Kind::End | Kind::Start => unreachable!("{:?}", self[target].kind),
|
||||||
Kind::Region => {
|
Kind::Region => self
|
||||||
self.idepth(self[target].inputs[0]).max(self.idepth(self[target].inputs[1]))
|
.idepth(self[target].inputs[0], scheds)
|
||||||
|
.max(self.idepth(self[target].inputs[1], scheds)),
|
||||||
|
_ if self[target].kind.is_pinned() => self.idepth(self[target].inputs[0], scheds),
|
||||||
|
_ if let Some(scheds) = scheds => {
|
||||||
|
self.idepth(scheds[target as usize], Some(scheds))
|
||||||
}
|
}
|
||||||
_ => self.idepth(self[target].inputs[0]),
|
_ => self.idepth(self[target].inputs[0], scheds),
|
||||||
} + 1;
|
} + 1;
|
||||||
self[target].depth.set(depth);
|
self[target].depth.set(depth);
|
||||||
}
|
}
|
||||||
|
@ -195,15 +201,14 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_up_impl(&mut self, node: Nid, visited: &mut BitSet) {
|
fn push_up_impl(&self, node: Nid, visited: &mut BitSet, scheds: &mut [Nid]) {
|
||||||
if !visited.set(node) {
|
if !visited.set(node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 1..self[node].inputs.len() {
|
for &inp in &self[node].inputs[1..] {
|
||||||
let inp = self[node].inputs[i];
|
|
||||||
if !self[inp].kind.is_pinned() {
|
if !self[inp].kind.is_pinned() {
|
||||||
self.push_up_impl(inp, visited);
|
self.push_up_impl(inp, visited, scheds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,32 +218,17 @@ impl Nodes {
|
||||||
|
|
||||||
let mut deepest = self[node].inputs[0];
|
let mut deepest = self[node].inputs[0];
|
||||||
for &inp in self[node].inputs[1..].iter() {
|
for &inp in self[node].inputs[1..].iter() {
|
||||||
if self.idepth(inp) > self.idepth(deepest) {
|
if self.idepth(inp, Some(scheds)) > self.idepth(deepest, Some(scheds)) {
|
||||||
if self[inp].kind.is_call() {
|
if self[inp].kind.is_call() {
|
||||||
deepest = inp;
|
deepest = inp;
|
||||||
} else {
|
} else {
|
||||||
debug_assert!(!self.is_cfg(inp));
|
debug_assert!(!self.is_cfg(inp));
|
||||||
deepest = self.idom(inp);
|
deepest = self.idom(inp, Some(scheds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if deepest == self[node].inputs[0] {
|
scheds[node as usize] = deepest;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let current = self[node].inputs[0];
|
|
||||||
|
|
||||||
let index = self[current].outputs.iter().position(|&p| p == node).unwrap();
|
|
||||||
self[current].outputs.remove(index);
|
|
||||||
self[node].inputs[0] = deepest;
|
|
||||||
debug_assert!(
|
|
||||||
!self[deepest].outputs.contains(&node) || self[deepest].kind.is_call(),
|
|
||||||
"{node} {:?} {deepest} {:?}",
|
|
||||||
self[node],
|
|
||||||
self[deepest]
|
|
||||||
);
|
|
||||||
self[deepest].outputs.push(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_rpo(&self, node: Nid, rpo: &mut Vec<Nid>, visited: &mut BitSet) {
|
fn collect_rpo(&self, node: Nid, rpo: &mut Vec<Nid>, visited: &mut BitSet) {
|
||||||
|
@ -253,21 +243,21 @@ impl Nodes {
|
||||||
rpo.push(node);
|
rpo.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_up(&mut self, rpo: &mut Vec<Nid>, visited: &mut BitSet) {
|
fn push_up(&self, rpo: &mut Vec<Nid>, visited: &mut BitSet, scheds: &mut [Nid]) {
|
||||||
debug_assert!(rpo.is_empty());
|
debug_assert!(rpo.is_empty());
|
||||||
self.collect_rpo(VOID, rpo, visited);
|
self.collect_rpo(VOID, rpo, visited);
|
||||||
|
|
||||||
for &node in rpo.iter().rev() {
|
for &node in rpo.iter().rev() {
|
||||||
self.loop_depth(node);
|
self.loop_depth(node, Some(scheds));
|
||||||
for i in 0..self[node].inputs.len() {
|
for i in 0..self[node].inputs.len() {
|
||||||
self.push_up_impl(self[node].inputs[i], visited);
|
self.push_up_impl(self[node].inputs[i], visited, scheds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(self[node].kind, Kind::Loop | Kind::Region) {
|
if matches!(self[node].kind, Kind::Loop | Kind::Region) {
|
||||||
for i in 0..self[node].outputs.len() {
|
for i in 0..self[node].outputs.len() {
|
||||||
let usage = self[node].outputs[i];
|
let usage = self[node].outputs[i];
|
||||||
if self[usage].kind == Kind::Phi {
|
if self[usage].kind == Kind::Phi {
|
||||||
self.push_up_impl(usage, visited);
|
self.push_up_impl(usage, visited, scheds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,14 +280,14 @@ impl Nodes {
|
||||||
rpo.clear();
|
rpo.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn better(&mut self, is: Nid, then: Nid) -> bool {
|
fn better(&self, is: Nid, then: Nid, scheds: Option<&[Nid]>) -> bool {
|
||||||
debug_assert_ne!(self.idepth(is), self.idepth(then), "{is} {then}");
|
debug_assert_ne!(self.idepth(is, scheds), self.idepth(then, scheds), "{is} {then}");
|
||||||
self.loop_depth(is) < self.loop_depth(then)
|
self.loop_depth(is, scheds) < self.loop_depth(then, scheds)
|
||||||
|| self.idepth(is) > self.idepth(then)
|
|| self.idepth(is, scheds) > self.idepth(then, scheds)
|
||||||
|| self[then].kind == Kind::If
|
|| self[then].kind == Kind::If
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_forward_edge(&mut self, usage: Nid, def: Nid) -> bool {
|
fn is_forward_edge(&self, usage: Nid, def: Nid) -> bool {
|
||||||
match self[usage].kind {
|
match self[usage].kind {
|
||||||
Kind::Phi => {
|
Kind::Phi => {
|
||||||
self[usage].inputs[2] != def || self[self[usage].inputs[0]].kind != Kind::Loop
|
self[usage].inputs[2] != def || self[self[usage].inputs[0]].kind != Kind::Loop
|
||||||
|
@ -307,20 +297,27 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_down(&mut self, node: Nid, visited: &mut BitSet, antideps: &mut [Nid]) {
|
fn push_down(
|
||||||
|
&self,
|
||||||
|
node: Nid,
|
||||||
|
visited: &mut BitSet,
|
||||||
|
antideps: &mut [Nid],
|
||||||
|
scheds: &mut [Nid],
|
||||||
|
antidep_bounds: &mut Vec<Nid>,
|
||||||
|
) {
|
||||||
if !visited.set(node) {
|
if !visited.set(node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for usage in self[node].outputs.clone() {
|
for usage in self[node].outputs.clone() {
|
||||||
if self.is_forward_edge(usage, node) && self[node].kind == Kind::Stre {
|
if self.is_forward_edge(usage, node) && self[node].kind == Kind::Stre {
|
||||||
self.push_down(usage, visited, antideps);
|
self.push_down(usage, visited, antideps, scheds, antidep_bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for usage in self[node].outputs.clone() {
|
for usage in self[node].outputs.clone() {
|
||||||
if self.is_forward_edge(usage, node) {
|
if self.is_forward_edge(usage, node) {
|
||||||
self.push_down(usage, visited, antideps);
|
self.push_down(usage, visited, antideps, scheds, antidep_bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,56 +328,60 @@ impl Nodes {
|
||||||
let mut min = None::<Nid>;
|
let mut min = None::<Nid>;
|
||||||
for i in 0..self[node].outputs.len() {
|
for i in 0..self[node].outputs.len() {
|
||||||
let usage = self[node].outputs[i];
|
let usage = self[node].outputs[i];
|
||||||
let ub = self.use_block(node, usage);
|
let ub = self.use_block(node, usage, Some(scheds));
|
||||||
min = min.map(|m| self.common_dom(ub, m)).or(Some(ub));
|
min = min.map(|m| self.common_dom(ub, m, Some(scheds))).or(Some(ub));
|
||||||
}
|
}
|
||||||
let mut min = min.unwrap();
|
let mut min = min.unwrap();
|
||||||
|
|
||||||
debug_assert!(self.dominates(self[node].inputs[0], min));
|
debug_assert!(self.dominates(scheds[node as usize], min, Some(scheds)));
|
||||||
|
|
||||||
let mut cursor = min;
|
let mut cursor = min;
|
||||||
while cursor != self[node].inputs[0] {
|
let mut fuel = self.values.len();
|
||||||
cursor = self.idom(cursor);
|
while cursor != scheds[node as usize] {
|
||||||
if self.better(cursor, min) {
|
debug_assert!(fuel != 0);
|
||||||
|
fuel -= 1;
|
||||||
|
cursor = self.idom(cursor, Some(scheds));
|
||||||
|
if self.better(cursor, min, Some(scheds)) {
|
||||||
min = cursor;
|
min = cursor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self[node].kind == Kind::Load {
|
if self[node].kind == Kind::Load {
|
||||||
min = self.find_antideps(node, min, antideps);
|
min = self.find_antideps(node, min, antideps, scheds, antidep_bounds);
|
||||||
}
|
|
||||||
|
|
||||||
if self[node].kind == Kind::Stre {
|
|
||||||
antideps[node as usize] = self[node].inputs[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self[min].kind.ends_basic_block() {
|
if self[min].kind.ends_basic_block() {
|
||||||
min = self.idom(min);
|
min = self.idom(min, Some(scheds));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.assert_dominance(node, min, true);
|
self.assert_dominance(node, min, true, Some(scheds));
|
||||||
|
|
||||||
let prev = self[node].inputs[0];
|
debug_assert!(
|
||||||
debug_assert!(self.idepth(min) >= self.idepth(prev));
|
self.idepth(min, Some(scheds)) >= self.idepth(scheds[node as usize], Some(scheds))
|
||||||
let index = self[prev].outputs.iter().position(|&p| p == node).unwrap();
|
);
|
||||||
self[prev].outputs.remove(index);
|
scheds[node as usize] = min;
|
||||||
self[node].inputs[0] = min;
|
|
||||||
self[min].outputs.push(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_antideps(&mut self, load: Nid, mut min: Nid, antideps: &mut [Nid]) -> Nid {
|
fn find_antideps(
|
||||||
|
&self,
|
||||||
|
load: Nid,
|
||||||
|
mut min: Nid,
|
||||||
|
antideps: &mut [Nid],
|
||||||
|
scheds: &[Nid],
|
||||||
|
antidep_bounds: &mut Vec<Nid>,
|
||||||
|
) -> Nid {
|
||||||
debug_assert!(self[load].kind == Kind::Load);
|
debug_assert!(self[load].kind == Kind::Load);
|
||||||
|
|
||||||
let (aclass, _) = self.aclass_index(self[load].inputs[1]);
|
let (aclass, _) = self.aclass_index(self[load].inputs[1]);
|
||||||
|
|
||||||
let mut cursor = min;
|
let mut cursor = min;
|
||||||
while cursor != self[load].inputs[0] {
|
while cursor != scheds[load as usize] {
|
||||||
antideps[cursor as usize] = load;
|
antideps[cursor as usize] = load;
|
||||||
if self[cursor].clobbers.get(aclass as _) {
|
if self[cursor].clobbers.get(aclass as _) {
|
||||||
min = self[cursor].inputs[0];
|
min = self[cursor].inputs[0];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cursor = self.idom(cursor);
|
cursor = self.idom(cursor, Some(scheds));
|
||||||
}
|
}
|
||||||
|
|
||||||
if self[load].inputs[2] == MEM {
|
if self[load].inputs[2] == MEM {
|
||||||
|
@ -390,16 +391,19 @@ impl Nodes {
|
||||||
for out in self[self[load].inputs[2]].outputs.clone() {
|
for out in self[self[load].inputs[2]].outputs.clone() {
|
||||||
match self[out].kind {
|
match self[out].kind {
|
||||||
Kind::Stre => {
|
Kind::Stre => {
|
||||||
let mut cursor = self[out].inputs[0];
|
let mut cursor = scheds[out as usize];
|
||||||
while cursor != antideps[out as usize] {
|
while cursor != scheds[load as usize]
|
||||||
|
&& self.idepth(cursor, Some(scheds))
|
||||||
|
> self.idepth(scheds[load as usize], Some(scheds))
|
||||||
|
{
|
||||||
if antideps[cursor as usize] == load {
|
if antideps[cursor as usize] == load {
|
||||||
min = self.common_dom(min, cursor);
|
min = self.common_dom(min, cursor, Some(scheds));
|
||||||
if min == cursor {
|
if min == cursor {
|
||||||
self.bind(load, out);
|
antidep_bounds.extend([load, out]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cursor = self.idom(cursor);
|
cursor = self.idom(cursor, Some(scheds));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -409,12 +413,15 @@ impl Nodes {
|
||||||
.position(|&n| n == self[load].inputs[2])
|
.position(|&n| n == self[load].inputs[2])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut cursor = self[self[out].inputs[0]].inputs[n];
|
let mut cursor = self[self[out].inputs[0]].inputs[n];
|
||||||
while cursor != antideps[out as usize] {
|
while cursor != scheds[load as usize]
|
||||||
|
&& self.idepth(cursor, Some(scheds))
|
||||||
|
> self.idepth(scheds[load as usize], Some(scheds))
|
||||||
|
{
|
||||||
if antideps[cursor as usize] == load {
|
if antideps[cursor as usize] == load {
|
||||||
min = self.common_dom(min, cursor);
|
min = self.common_dom(min, cursor, Some(scheds));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cursor = self.idom(cursor);
|
cursor = self.idom(cursor, Some(scheds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -431,9 +438,9 @@ impl Nodes {
|
||||||
self[to].inputs.push(from);
|
self[to].inputs.push(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn use_block(&self, target: Nid, from: Nid) -> Nid {
|
fn use_block(&self, target: Nid, from: Nid, scheds: Option<&[Nid]>) -> Nid {
|
||||||
if self[from].kind != Kind::Phi {
|
if self[from].kind != Kind::Phi {
|
||||||
return self.idom(from);
|
return self.idom(from, scheds);
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = self[from].inputs.iter().position(|&n| n == target).unwrap_or_else(|| {
|
let index = self[from].inputs.iter().position(|&n| n == target).unwrap_or_else(|| {
|
||||||
|
@ -442,26 +449,28 @@ impl Nodes {
|
||||||
self[self[from].inputs[0]].inputs[index - 1]
|
self[self[from].inputs[0]].inputs[index - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn idom(&self, target: Nid) -> Nid {
|
fn idom(&self, target: Nid, scheds: Option<&[Nid]>) -> Nid {
|
||||||
match self[target].kind {
|
match self[target].kind {
|
||||||
Kind::Start => VOID,
|
Kind::Start => unreachable!(),
|
||||||
Kind::End => unreachable!(),
|
Kind::End => unreachable!(),
|
||||||
Kind::Region => {
|
Kind::Region => {
|
||||||
let &[lcfg, rcfg] = self[target].inputs.as_slice() else { unreachable!() };
|
let &[lcfg, rcfg] = self[target].inputs.as_slice() else { unreachable!() };
|
||||||
self.common_dom(lcfg, rcfg)
|
self.common_dom(lcfg, rcfg, scheds)
|
||||||
}
|
}
|
||||||
|
_ if self[target].kind.is_pinned() => self[target].inputs[0],
|
||||||
|
_ if let Some(scheds) = scheds => scheds[target as usize],
|
||||||
_ => self[target].inputs[0],
|
_ => self[target].inputs[0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn common_dom(&self, mut a: Nid, mut b: Nid) -> Nid {
|
fn common_dom(&self, mut a: Nid, mut b: Nid, scheds: Option<&[Nid]>) -> Nid {
|
||||||
while a != b {
|
while a != b {
|
||||||
let [ldepth, rdepth] = [self.idepth(a), self.idepth(b)];
|
let [ldepth, rdepth] = [self.idepth(a, scheds), self.idepth(b, scheds)];
|
||||||
if ldepth >= rdepth {
|
if ldepth >= rdepth {
|
||||||
a = self.idom(a);
|
a = self.idom(a, scheds);
|
||||||
}
|
}
|
||||||
if ldepth <= rdepth {
|
if ldepth <= rdepth {
|
||||||
b = self.idom(b);
|
b = self.idom(b, scheds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a
|
a
|
||||||
|
@ -581,16 +590,40 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gcm(&mut self, rpo: &mut Vec<Nid>, visited: &mut BitSet) {
|
fn gcm(&mut self, scratch: &mut Vec<Nid>, bind_buf: &mut Vec<Nid>, visited: &mut BitSet) {
|
||||||
visited.clear(self.values.len());
|
visited.clear(self.values.len());
|
||||||
self.fix_loops(rpo, visited);
|
self.fix_loops(bind_buf, visited);
|
||||||
|
debug_assert!(bind_buf.is_empty());
|
||||||
|
debug_assert!(scratch.is_empty());
|
||||||
|
scratch.resize(self.values.len() * 2, Nid::MAX);
|
||||||
|
let (antideps, scheds) = scratch.split_at_mut(self.values.len());
|
||||||
visited.clear(self.values.len());
|
visited.clear(self.values.len());
|
||||||
self.push_up(rpo, visited);
|
self.push_up(bind_buf, visited, scheds);
|
||||||
visited.clear(self.values.len());
|
visited.clear(self.values.len());
|
||||||
debug_assert!(rpo.is_empty());
|
self.push_down(VOID, visited, antideps, scheds, bind_buf);
|
||||||
rpo.resize(self.values.len(), VOID);
|
|
||||||
self.push_down(VOID, visited, rpo);
|
for &[from, to] in bind_buf.array_chunks() {
|
||||||
rpo.clear();
|
self.bind(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
bind_buf.clear();
|
||||||
|
self[VOID].outputs =
|
||||||
|
self[VOID].outputs.iter().filter(|&&n| self[n].kind.is_at_start()).copied().collect();
|
||||||
|
|
||||||
|
for (&shed, n) in scheds.iter().zip(0u16..) {
|
||||||
|
if shed == Nid::MAX {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let prev = mem::replace(&mut self[n].inputs[0], shed);
|
||||||
|
if prev != VOID {
|
||||||
|
let index = self[prev].outputs.iter().position(|&o| o == n).unwrap();
|
||||||
|
self[prev].outputs.swap_remove(index);
|
||||||
|
}
|
||||||
|
self[shed].outputs.push(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
scratch.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear(&mut self) {
|
fn clear(&mut self) {
|
||||||
|
@ -1429,9 +1462,9 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
return Some(self[target].inputs[2]);
|
return Some(self[target].inputs[2]);
|
||||||
}
|
}
|
||||||
_ if self.is_cfg(target) && self.idom(target) == NEVER => panic!(),
|
K::Start => {}
|
||||||
K::Start
|
_ if self.is_cfg(target) && self.idom(target, None) == NEVER => panic!(),
|
||||||
| K::Entry
|
K::Entry
|
||||||
| K::Mem
|
| K::Mem
|
||||||
| K::Loops
|
| K::Loops
|
||||||
| K::End
|
| K::End
|
||||||
|
@ -1468,7 +1501,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor = self.idom(cursor);
|
cursor = self.idom(cursor, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
CondOptRes::Unknown
|
CondOptRes::Unknown
|
||||||
|
@ -1563,7 +1596,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::format_in_format_args)]
|
#[expect(clippy::format_in_format_args)]
|
||||||
fn basic_blocks_instr(&mut self, out: &mut String, node: Nid) -> core::fmt::Result {
|
fn basic_blocks_instr(&self, out: &mut String, node: Nid) -> core::fmt::Result {
|
||||||
match self[node].kind {
|
match self[node].kind {
|
||||||
Kind::Assert { .. } | Kind::Start => unreachable!("{} {out}", self[node].kind),
|
Kind::Assert { .. } | Kind::Start => unreachable!("{} {out}", self[node].kind),
|
||||||
Kind::End => return Ok(()),
|
Kind::End => return Ok(()),
|
||||||
|
@ -1599,7 +1632,8 @@ impl Nodes {
|
||||||
if self[node].kind != Kind::Loop && self[node].kind != Kind::Region {
|
if self[node].kind != Kind::Loop && self[node].kind != Kind::Region {
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
" {:<14} {}",
|
" {:<3} {:<14} {}",
|
||||||
|
node,
|
||||||
format!("{:?}", self[node].inputs),
|
format!("{:?}", self[node].inputs),
|
||||||
format!("{:?}", self[node].outputs)
|
format!("{:?}", self[node].outputs)
|
||||||
)?;
|
)?;
|
||||||
|
@ -1609,7 +1643,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn basic_blocks_low(
|
fn basic_blocks_low(
|
||||||
&mut self,
|
&self,
|
||||||
out: &mut String,
|
out: &mut String,
|
||||||
mut node: Nid,
|
mut node: Nid,
|
||||||
visited: &mut BitSet,
|
visited: &mut BitSet,
|
||||||
|
@ -1709,7 +1743,7 @@ impl Nodes {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn basic_blocks(&mut self) {
|
fn basic_blocks(&self) {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
let mut visited = BitSet::default();
|
let mut visited = BitSet::default();
|
||||||
self.basic_blocks_low(&mut out, VOID, &mut visited).unwrap();
|
self.basic_blocks_low(&mut out, VOID, &mut visited).unwrap();
|
||||||
|
@ -1763,12 +1797,12 @@ impl Nodes {
|
||||||
let mut stack = vec![self[loob].inputs[1]];
|
let mut stack = vec![self[loob].inputs[1]];
|
||||||
let mut seen = BitSet::default();
|
let mut seen = BitSet::default();
|
||||||
seen.set(loob);
|
seen.set(loob);
|
||||||
let depth = self.loop_depth(loob);
|
let depth = self.loop_depth(loob, None);
|
||||||
while let Some(nid) = stack.pop() {
|
while let Some(nid) = stack.pop() {
|
||||||
if seen.set(nid) {
|
if seen.set(nid) {
|
||||||
if depth > self.loop_depth(nid) {
|
if depth > self.loop_depth(nid, None) {
|
||||||
failed = true;
|
failed = true;
|
||||||
log::error!("{depth} {} {nid} {:?}", self.loop_depth(nid), self[nid]);
|
log::error!("{depth} {} {nid} {:?}", self.loop_depth(nid, None), self[nid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self[nid].kind {
|
match self[nid].kind {
|
||||||
|
@ -1830,25 +1864,25 @@ impl Nodes {
|
||||||
aclass.last_store.set(lvar.last_store.get(), self);
|
aclass.last_store.set(lvar.last_store.get(), self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_dominance(&mut self, nd: Nid, min: Nid, check_outputs: bool) {
|
fn assert_dominance(&self, nd: Nid, min: Nid, check_outputs: bool, scheds: Option<&[Nid]>) {
|
||||||
if !cfg!(debug_assertions) {
|
if !cfg!(debug_assertions) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let node = self[nd].clone();
|
let node = self[nd].clone();
|
||||||
for &i in node.inputs.iter() {
|
for &i in &node.inputs[1..] {
|
||||||
let dom = self.idom(i);
|
let dom = self.idom(i, scheds);
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.dominates(dom, min),
|
self.dominates(dom, min, scheds),
|
||||||
"{dom} {min} {node:?} {:?}",
|
"{dom} {min} {node:?} {:?}",
|
||||||
self.basic_blocks()
|
self.basic_blocks()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if check_outputs {
|
if check_outputs {
|
||||||
for &o in node.outputs.iter() {
|
for &o in node.outputs.iter() {
|
||||||
let dom = self.use_block(nd, o);
|
let dom = self.use_block(nd, o, scheds);
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.dominates(min, dom),
|
self.dominates(min, dom, scheds),
|
||||||
"{min} {dom} {node:?} {:?}",
|
"{min} {dom} {node:?} {:?}",
|
||||||
self.basic_blocks()
|
self.basic_blocks()
|
||||||
);
|
);
|
||||||
|
@ -1856,17 +1890,19 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dominates(&self, dominator: Nid, mut dominated: Nid) -> bool {
|
fn dominates(&self, dominator: Nid, mut dominated: Nid, scheds: Option<&[Nid]>) -> bool {
|
||||||
loop {
|
loop {
|
||||||
if dominator == dominated {
|
if dominator == dominated {
|
||||||
break true;
|
break true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.idepth(dominator) > self.idepth(dominated) {
|
debug_assert!(dominated != VOID);
|
||||||
|
|
||||||
|
if self.idepth(dominator, scheds) > self.idepth(dominated, scheds) {
|
||||||
break false;
|
break false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dominated = self.idom(dominated);
|
dominated = self.idom(dominated, scheds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2018,8 +2054,11 @@ impl Kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_pinned(&self) -> bool {
|
fn is_pinned(&self) -> bool {
|
||||||
self.is_cfg()
|
self.is_cfg() || self.is_at_start() || matches!(self, Self::Phi | Kind::Assert { .. })
|
||||||
|| matches!(self, Self::Phi | Self::Arg | Self::Mem | Self::Loops | Kind::Assert { .. })
|
}
|
||||||
|
|
||||||
|
fn is_at_start(&self) -> bool {
|
||||||
|
matches!(self, Self::Arg | Self::Mem | Self::Loops | Self::Entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_cfg(&self) -> bool {
|
fn is_cfg(&self) -> bool {
|
||||||
|
@ -2384,7 +2423,8 @@ impl Ctx {
|
||||||
pub struct Pool {
|
pub struct Pool {
|
||||||
cis: Vec<ItemCtx>,
|
cis: Vec<ItemCtx>,
|
||||||
used_cis: usize,
|
used_cis: usize,
|
||||||
nid_stack: Vec<Nid>,
|
scratch1: Vec<Nid>,
|
||||||
|
scratch2: Vec<Nid>,
|
||||||
nid_set: BitSet,
|
nid_set: BitSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2652,8 +2692,8 @@ impl<'a> Codegen<'a> {
|
||||||
if self.ci.nodes[value].kind == Kind::Load {
|
if self.ci.nodes[value].kind == Kind::Load {
|
||||||
let (lindex, ..) = self.ci.nodes.aclass_index(self.ci.nodes[value].inputs[1]);
|
let (lindex, ..) = self.ci.nodes.aclass_index(self.ci.nodes[value].inputs[1]);
|
||||||
let clobber = self.ci.scope.aclasses[lindex].clobber.get();
|
let clobber = self.ci.scope.aclasses[lindex].clobber.get();
|
||||||
if self.ci.nodes.idepth(clobber)
|
if self.ci.nodes.idepth(clobber, None)
|
||||||
> self.ci.nodes.idepth(self.ci.scope.aclasses[index].clobber.get())
|
> self.ci.nodes.idepth(self.ci.scope.aclasses[index].clobber.get(), None)
|
||||||
{
|
{
|
||||||
self.ci.scope.aclasses[index].clobber.set(clobber, &mut self.ci.nodes);
|
self.ci.scope.aclasses[index].clobber.set(clobber, &mut self.ci.nodes);
|
||||||
}
|
}
|
||||||
|
@ -4732,7 +4772,7 @@ impl<'a> Codegen<'a> {
|
||||||
fn finalize(&mut self, prev_err_len: usize) -> bool {
|
fn finalize(&mut self, prev_err_len: usize) -> bool {
|
||||||
use {AssertKind as AK, CondOptRes as CR};
|
use {AssertKind as AK, CondOptRes as CR};
|
||||||
|
|
||||||
self.ci.finalize(&mut self.pool.nid_stack, self.tys, self.files);
|
self.ci.finalize(&mut self.pool.scratch1, self.tys, self.files);
|
||||||
|
|
||||||
//let mut to_remove = vec![];
|
//let mut to_remove = vec![];
|
||||||
for (id, node) in self.ci.nodes.iter() {
|
for (id, node) in self.ci.nodes.iter() {
|
||||||
|
@ -4787,7 +4827,11 @@ impl<'a> Codegen<'a> {
|
||||||
if self.errors.borrow().len() == prev_err_len {
|
if self.errors.borrow().len() == prev_err_len {
|
||||||
self.ci.nodes.check_final_integrity(self.ty_display(ty::Id::VOID));
|
self.ci.nodes.check_final_integrity(self.ty_display(ty::Id::VOID));
|
||||||
self.ci.nodes.graphviz(self.ty_display(ty::Id::VOID));
|
self.ci.nodes.graphviz(self.ty_display(ty::Id::VOID));
|
||||||
self.ci.nodes.gcm(&mut self.pool.nid_stack, &mut self.pool.nid_set);
|
self.ci.nodes.gcm(
|
||||||
|
&mut self.pool.scratch1,
|
||||||
|
&mut self.pool.scratch2,
|
||||||
|
&mut self.pool.nid_set,
|
||||||
|
);
|
||||||
self.ci.nodes.check_loop_depth_integrity(self.ty_display(ty::Id::VOID));
|
self.ci.nodes.check_loop_depth_integrity(self.ty_display(ty::Id::VOID));
|
||||||
self.ci.nodes.basic_blocks();
|
self.ci.nodes.basic_blocks();
|
||||||
self.ci.nodes.graphviz(self.ty_display(ty::Id::VOID));
|
self.ci.nodes.graphviz(self.ty_display(ty::Id::VOID));
|
||||||
|
|
|
@ -362,6 +362,9 @@ impl Nodes {
|
||||||
let mut seen = BitSet::default();
|
let mut seen = BitSet::default();
|
||||||
seen.clear(self.values.len());
|
seen.clear(self.values.len());
|
||||||
|
|
||||||
|
let cfg_idx = outputs.iter().position(|&n| self.is_cfg(n)).unwrap();
|
||||||
|
outputs.swap(cfg_idx, 0);
|
||||||
|
|
||||||
for &o in outputs.iter() {
|
for &o in outputs.iter() {
|
||||||
if (!self.is_cfg(o)
|
if (!self.is_cfg(o)
|
||||||
&& self[o].outputs.iter().any(|&oi| {
|
&& self[o].outputs.iter().any(|&oi| {
|
||||||
|
@ -407,6 +410,28 @@ impl Nodes {
|
||||||
self[from]
|
self[from]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let bf = &buf;
|
||||||
|
debug_assert_eq!(
|
||||||
|
bf.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, &b)| !self[b].kind.is_pinned())
|
||||||
|
.flat_map(|(i, &b)| self[b]
|
||||||
|
.inputs
|
||||||
|
.iter()
|
||||||
|
.filter(|&&b| !self[b].kind.is_pinned())
|
||||||
|
.filter_map(move |&inp| bf
|
||||||
|
.iter()
|
||||||
|
.position(|&n| inp == n)
|
||||||
|
.filter(|&j| i > j)
|
||||||
|
.map(|j| (bf[i], bf[j]))))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec![],
|
||||||
|
"{:?}",
|
||||||
|
bf
|
||||||
|
);
|
||||||
|
|
||||||
|
debug_assert!(self.is_cfg(bf[0]) || self[bf[0]].kind == Kind::Phi, "{:?}", self[bf[0]]);
|
||||||
|
|
||||||
if outputs.len() != buf.len() {
|
if outputs.len() != buf.len() {
|
||||||
panic!("{:?} {:?}", outputs, buf);
|
panic!("{:?} {:?}", outputs, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ impl HbvmBackend {
|
||||||
files: &[parser::Ast],
|
files: &[parser::Ast],
|
||||||
) -> (usize, bool) {
|
) -> (usize, bool) {
|
||||||
let tail = Function::build(nodes, tys, &mut self.ralloc, sig);
|
let tail = Function::build(nodes, tys, &mut self.ralloc, sig);
|
||||||
|
nodes.basic_blocks();
|
||||||
|
|
||||||
let strip_load = |value| match nodes[value].kind {
|
let strip_load = |value| match nodes[value].kind {
|
||||||
Kind::Load { .. } if nodes[value].ty.loc(tys) == Loc::Stack => nodes[value].inputs[1],
|
Kind::Load { .. } if nodes[value].ty.loc(tys) == Loc::Stack => nodes[value].inputs[1],
|
||||||
|
@ -366,6 +367,8 @@ impl<'a> Function<'a> {
|
||||||
func.visited.clear(nodes.values.len());
|
func.visited.clear(nodes.values.len());
|
||||||
let mut s = Self { tail: true, nodes, tys, sig, func };
|
let mut s = Self { tail: true, nodes, tys, sig, func };
|
||||||
s.emit_node(VOID);
|
s.emit_node(VOID);
|
||||||
|
debug_assert!(s.func.blocks.array_chunks().all(|[a, b]| a.end == b.start));
|
||||||
|
log::info!("{s:?}");
|
||||||
s.tail
|
s.tail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,9 +516,9 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn use_block_of(&self, inst: Nid, uinst: Nid) -> Nid {
|
fn use_block_of(&self, inst: Nid, uinst: Nid) -> Nid {
|
||||||
let mut block = self.use_block(inst, uinst);
|
let mut block = self.use_block(inst, uinst, None);
|
||||||
while !self[block].kind.starts_basic_block() {
|
while !self[block].kind.starts_basic_block() {
|
||||||
block = self.idom(block);
|
block = self.idom(block, None);
|
||||||
}
|
}
|
||||||
block
|
block
|
||||||
}
|
}
|
||||||
|
@ -538,7 +541,7 @@ impl Nodes {
|
||||||
|
|
||||||
fn idom_of(&self, mut nid: Nid) -> Nid {
|
fn idom_of(&self, mut nid: Nid) -> Nid {
|
||||||
while !self[nid].kind.starts_basic_block() {
|
while !self[nid].kind.starts_basic_block() {
|
||||||
nid = self.idom(nid);
|
nid = self.idom(nid, None);
|
||||||
}
|
}
|
||||||
nid
|
nid
|
||||||
}
|
}
|
||||||
|
@ -643,12 +646,18 @@ impl<'a> Regalloc<'a> {
|
||||||
let mut range = b.range();
|
let mut range = b.range();
|
||||||
debug_assert!(range.start < range.end);
|
debug_assert!(range.start < range.end);
|
||||||
range.start = range.start.max(s.instr_of(inst).map_or(0, |n| n + 1) as usize);
|
range.start = range.start.max(s.instr_of(inst).map_or(0, |n| n + 1) as usize);
|
||||||
debug_assert!(range.start < range.end, "{:?}", range);
|
debug_assert!(
|
||||||
|
range.start < range.end,
|
||||||
|
"{:?} {:?} {n} {inst}",
|
||||||
|
range,
|
||||||
|
self.nodes[inst]
|
||||||
|
);
|
||||||
let new = range.end.min(
|
let new = range.end.min(
|
||||||
s.instr_of(uinst)
|
s.instr_of(uinst)
|
||||||
.filter(|_| {
|
.filter(|_| {
|
||||||
n == cursor
|
n == cursor
|
||||||
&& self.nodes.loop_depth(dom) == self.nodes.loop_depth(cursor)
|
&& self.nodes.loop_depth(dom, None)
|
||||||
|
== self.nodes.loop_depth(cursor, None)
|
||||||
})
|
})
|
||||||
.map_or(Nid::MAX, |n| n + 1) as usize,
|
.map_or(Nid::MAX, |n| n + 1) as usize,
|
||||||
);
|
);
|
||||||
|
@ -700,10 +709,14 @@ impl<'a> Regalloc<'a> {
|
||||||
debug_assert!(self.res.dfs_buf.is_empty());
|
debug_assert!(self.res.dfs_buf.is_empty());
|
||||||
self.res.dfs_buf.push(from);
|
self.res.dfs_buf.push(from);
|
||||||
|
|
||||||
debug_assert!(self.nodes.dominates(until, from));
|
debug_assert!(self.nodes.dominates(until, from, None));
|
||||||
|
|
||||||
while let Some(nid) = self.res.dfs_buf.pop() {
|
while let Some(nid) = self.res.dfs_buf.pop() {
|
||||||
debug_assert!(self.nodes.dominates(until, nid), "{until} {:?}", self.nodes[until]);
|
debug_assert!(
|
||||||
|
self.nodes.dominates(until, nid, None),
|
||||||
|
"{until} {:?}",
|
||||||
|
self.nodes[until]
|
||||||
|
);
|
||||||
each(self, nid, self.res.blocks[self.block_of(nid) as usize]);
|
each(self, nid, self.res.blocks[self.block_of(nid) as usize]);
|
||||||
if nid == until {
|
if nid == until {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -144d
|
ADDI64 r254, r254, -136d
|
||||||
ST r31, r254, 80a, 64h
|
ST r31, r254, 80a, 56h
|
||||||
LRA r32, r0, :glob_stru
|
LRA r32, r0, :glob_stru
|
||||||
JAL r31, r0, :new_stru
|
JAL r31, r0, :new_stru
|
||||||
ST r1, r32, 0a, 16h
|
ST r1, r32, 0a, 16h
|
||||||
|
@ -16,58 +16,57 @@ main:
|
||||||
LI64 r32, 200d
|
LI64 r32, 200d
|
||||||
CP r1, r32
|
CP r1, r32
|
||||||
JMP :1
|
JMP :1
|
||||||
2: LI64 r35, 3d
|
2: LI64 r34, 1d
|
||||||
LI64 r36, 1d
|
ST r34, r32, 0a, 8h
|
||||||
ST r36, r32, 0a, 8h
|
ST r34, r32, 8a, 8h
|
||||||
ST r36, r32, 8a, 8h
|
ADDI64 r35, r254, 32d
|
||||||
ADDI64 r37, r254, 32d
|
ST r34, r254, 32a, 8h
|
||||||
ST r36, r254, 32a, 8h
|
ST r34, r254, 40a, 8h
|
||||||
ST r36, r254, 40a, 8h
|
ST r34, r254, 48a, 8h
|
||||||
ST r36, r254, 48a, 8h
|
ST r34, r254, 56a, 8h
|
||||||
ST r36, r254, 56a, 8h
|
ST r34, r254, 64a, 8h
|
||||||
ST r36, r254, 64a, 8h
|
ST r34, r254, 72a, 8h
|
||||||
ST r36, r254, 72a, 8h
|
LI64 r36, 3d
|
||||||
CP r32, r33
|
CP r32, r33
|
||||||
8: JNE r32, r35, :3
|
8: JNE r32, r36, :3
|
||||||
LD r32, r254, 64a, 8h
|
LD r32, r254, 64a, 8h
|
||||||
JEQ r32, r33, :4
|
JEQ r32, r33, :4
|
||||||
LI64 r32, 100d
|
LI64 r32, 100d
|
||||||
CP r1, r32
|
CP r1, r32
|
||||||
JMP :1
|
JMP :1
|
||||||
4: ST r33, r254, 0a, 8h
|
4: ST r34, r254, 32a, 8h
|
||||||
|
ST r34, r254, 40a, 8h
|
||||||
|
ST r34, r254, 48a, 8h
|
||||||
|
ST r34, r254, 56a, 8h
|
||||||
|
ST r34, r254, 64a, 8h
|
||||||
|
ST r34, r254, 72a, 8h
|
||||||
|
ST r33, r254, 0a, 8h
|
||||||
ST r33, r254, 8a, 8h
|
ST r33, r254, 8a, 8h
|
||||||
ST r33, r254, 16a, 8h
|
ST r33, r254, 16a, 8h
|
||||||
ST r33, r254, 24a, 8h
|
ST r33, r254, 24a, 8h
|
||||||
ST r36, r254, 32a, 8h
|
|
||||||
ST r36, r254, 40a, 8h
|
|
||||||
ST r36, r254, 48a, 8h
|
|
||||||
ST r36, r254, 56a, 8h
|
|
||||||
ST r36, r254, 64a, 8h
|
|
||||||
ST r36, r254, 72a, 8h
|
|
||||||
CP r32, r33
|
CP r32, r33
|
||||||
7: LD r38, r254, 64a, 8h
|
7: LD r37, r254, 64a, 8h
|
||||||
JNE r32, r35, :5
|
JNE r32, r36, :5
|
||||||
JEQ r38, r33, :6
|
JEQ r37, r33, :6
|
||||||
LI64 r32, 10d
|
LI64 r32, 10d
|
||||||
CP r1, r32
|
CP r1, r32
|
||||||
JMP :1
|
JMP :1
|
||||||
6: CP r1, r33
|
6: CP r1, r33
|
||||||
JMP :1
|
JMP :1
|
||||||
5: ADD64 r34, r32, r36
|
5: MULI64 r37, r32, 16d
|
||||||
MULI64 r32, r32, 16d
|
ADD64 r37, r35, r37
|
||||||
ADD64 r32, r37, r32
|
ST r33, r37, 0a, 8h
|
||||||
ST r33, r32, 0a, 8h
|
ST r33, r37, 8a, 8h
|
||||||
ST r33, r32, 8a, 8h
|
ADD64 r32, r32, r34
|
||||||
CP r32, r34
|
|
||||||
JMP :7
|
JMP :7
|
||||||
3: MULI64 r34, r32, 16d
|
3: MULI64 r37, r32, 16d
|
||||||
ADD64 r34, r37, r34
|
ADD64 r37, r35, r37
|
||||||
JAL r31, r0, :new_stru
|
JAL r31, r0, :new_stru
|
||||||
ST r1, r34, 0a, 16h
|
ST r1, r37, 0a, 16h
|
||||||
ADD64 r32, r32, r36
|
ADD64 r32, r32, r34
|
||||||
JMP :8
|
JMP :8
|
||||||
1: LD r31, r254, 80a, 64h
|
1: LD r31, r254, 80a, 56h
|
||||||
ADDI64 r254, r254, 144d
|
ADDI64 r254, r254, 136d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
new_stru:
|
new_stru:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -16d
|
||||||
|
@ -77,6 +76,6 @@ new_stru:
|
||||||
LD r1, r13, 0a, 16h
|
LD r1, r13, 0a, 16h
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 739
|
code size: 736
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -10,9 +10,9 @@ opaque:
|
||||||
process:
|
process:
|
||||||
ADDI64 r254, r254, -48d
|
ADDI64 r254, r254, -48d
|
||||||
ST r31, r254, 16a, 32h
|
ST r31, r254, 16a, 32h
|
||||||
LI64 r32, 1000d
|
|
||||||
ADDI64 r33, r254, 0d
|
ADDI64 r33, r254, 0d
|
||||||
ST r0, r254, 0a, 1h
|
ST r0, r254, 0a, 1h
|
||||||
|
LI64 r32, 1000d
|
||||||
4: JGTU r32, r0, :0
|
4: JGTU r32, r0, :0
|
||||||
JMP :1
|
JMP :1
|
||||||
0: CP r2, r33
|
0: CP r2, r33
|
||||||
|
|
|
@ -69,8 +69,8 @@ new:
|
||||||
ADDI64 r254, r254, 24d
|
ADDI64 r254, r254, 24d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
push:
|
push:
|
||||||
ADDI64 r254, r254, -104d
|
ADDI64 r254, r254, -88d
|
||||||
ST r31, r254, 0a, 104h
|
ST r31, r254, 0a, 88h
|
||||||
CP r38, r2
|
CP r38, r2
|
||||||
CP r39, r3
|
CP r39, r3
|
||||||
LI64 r37, 1d
|
LI64 r37, 1d
|
||||||
|
@ -95,12 +95,12 @@ push:
|
||||||
LD r32, r38, 0a, 8h
|
LD r32, r38, 0a, 8h
|
||||||
ADD64 r41, r32, r33
|
ADD64 r41, r32, r33
|
||||||
CP r34, r35
|
CP r34, r35
|
||||||
7: LD r42, r38, 0a, 8h
|
7: LD r33, r38, 0a, 8h
|
||||||
LD r43, r38, 8a, 8h
|
LD r36, r38, 8a, 8h
|
||||||
JNE r41, r32, :5
|
JNE r41, r32, :5
|
||||||
JEQ r43, r0, :6
|
JEQ r36, r0, :6
|
||||||
MUL64 r32, r43, r40
|
MUL64 r32, r36, r40
|
||||||
CP r2, r42
|
CP r2, r33
|
||||||
CP r3, r32
|
CP r3, r32
|
||||||
CP r4, r40
|
CP r4, r40
|
||||||
JAL r31, r0, :free
|
JAL r31, r0, :free
|
||||||
|
@ -122,8 +122,8 @@ push:
|
||||||
ADD64 r32, r32, r37
|
ADD64 r32, r32, r37
|
||||||
ST r32, r38, 8a, 8h
|
ST r32, r38, 8a, 8h
|
||||||
CP r1, r33
|
CP r1, r33
|
||||||
4: LD r31, r254, 0a, 104h
|
4: LD r31, r254, 0a, 88h
|
||||||
ADDI64 r254, r254, 104d
|
ADDI64 r254, r254, 88d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 923
|
code size: 923
|
||||||
ret: 69
|
ret: 69
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -128d
|
ADDI64 r254, r254, -128d
|
||||||
LI8 r15, 69b
|
ADDI64 r15, r254, 0d
|
||||||
LI64 r16, 128d
|
LI8 r16, 69b
|
||||||
|
LI64 r17, 128d
|
||||||
CP r13, r0
|
CP r13, r0
|
||||||
ADDI64 r17, r254, 0d
|
2: LD r14, r254, 42a, 1h
|
||||||
2: LD r18, r254, 42a, 1h
|
JLTU r13, r17, :0
|
||||||
JLTU r13, r16, :0
|
ANDI r13, r14, 255d
|
||||||
ANDI r13, r18, 255d
|
|
||||||
CP r1, r13
|
CP r1, r13
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r14, r13, 1d
|
0: ADDI64 r14, r13, 1d
|
||||||
ADD64 r13, r17, r13
|
ADD64 r13, r15, r13
|
||||||
ST r15, r13, 0a, 1h
|
ST r16, r13, 0a, 1h
|
||||||
CP r13, r14
|
CP r13, r14
|
||||||
JMP :2
|
JMP :2
|
||||||
1: ADDI64 r254, r254, 128d
|
1: ADDI64 r254, r254, 128d
|
||||||
|
|
|
@ -37,26 +37,26 @@ put_filled_rect:
|
||||||
ST r7, r254, 75a, 1h
|
ST r7, r254, 75a, 1h
|
||||||
ADDI64 r7, r254, 75d
|
ADDI64 r7, r254, 75d
|
||||||
CP r16, r7
|
CP r16, r7
|
||||||
LI64 r17, 25d
|
ADDI64 r17, r254, 25d
|
||||||
LI64 r18, 2d
|
LI8 r18, 5b
|
||||||
LI64 r19, 8d
|
ST r18, r254, 25a, 1h
|
||||||
ADDI64 r20, r254, 25d
|
LD r19, r13, 0a, 8h
|
||||||
ADDI64 r21, r254, 50d
|
ST r19, r254, 26a, 4h
|
||||||
LI8 r22, 5b
|
LI64 r20, 1d
|
||||||
ST r22, r254, 25a, 1h
|
ST r20, r254, 30a, 4h
|
||||||
LD r23, r13, 0a, 8h
|
|
||||||
ST r23, r254, 26a, 4h
|
|
||||||
LI64 r24, 1d
|
|
||||||
ST r24, r254, 30a, 4h
|
|
||||||
ST r16, r254, 34a, 8h
|
ST r16, r254, 34a, 8h
|
||||||
ST r22, r254, 50a, 1h
|
LI64 r21, 25d
|
||||||
ST r23, r254, 51a, 4h
|
ADDI64 r22, r254, 50d
|
||||||
ST r24, r254, 55a, 4h
|
ST r18, r254, 50a, 1h
|
||||||
|
ST r19, r254, 51a, 4h
|
||||||
|
ST r20, r254, 55a, 4h
|
||||||
ST r16, r254, 59a, 8h
|
ST r16, r254, 59a, 8h
|
||||||
|
LI64 r23, 2d
|
||||||
|
LI64 r24, 8d
|
||||||
LD r25, r15, 8a, 8h
|
LD r25, r15, 8a, 8h
|
||||||
LD r13, r13, 8a, 8h
|
LD r13, r13, 8a, 8h
|
||||||
ADD64 r26, r13, r25
|
ADD64 r26, r13, r25
|
||||||
SUB64 r26, r26, r24
|
SUB64 r26, r26, r20
|
||||||
LD r27, r14, 8a, 8h
|
LD r27, r14, 8a, 8h
|
||||||
MUL64 r26, r27, r26
|
MUL64 r26, r27, r26
|
||||||
LD r14, r14, 0a, 8h
|
LD r14, r14, 0a, 8h
|
||||||
|
@ -66,36 +66,36 @@ put_filled_rect:
|
||||||
MUL64 r25, r27, r25
|
MUL64 r25, r27, r25
|
||||||
ADD64 r14, r14, r25
|
ADD64 r14, r14, r25
|
||||||
ADD64 r14, r28, r14
|
ADD64 r14, r28, r14
|
||||||
3: JGTU r13, r24, :0
|
3: JGTU r13, r20, :0
|
||||||
JNE r13, r24, :1
|
JNE r13, r20, :1
|
||||||
ADDI64 r13, r254, 0d
|
ADDI64 r13, r254, 0d
|
||||||
ST r22, r254, 0a, 1h
|
ST r18, r254, 0a, 1h
|
||||||
ST r23, r254, 1a, 4h
|
ST r19, r254, 1a, 4h
|
||||||
ST r24, r254, 5a, 4h
|
ST r20, r254, 5a, 4h
|
||||||
ST r16, r254, 9a, 8h
|
ST r16, r254, 9a, 8h
|
||||||
ST r14, r254, 17a, 8h
|
ST r14, r254, 17a, 8h
|
||||||
CP r2, r19
|
CP r2, r24
|
||||||
CP r3, r18
|
CP r3, r23
|
||||||
CP r4, r13
|
CP r4, r13
|
||||||
CP r5, r17
|
CP r5, r21
|
||||||
ECA
|
ECA
|
||||||
JMP :1
|
JMP :1
|
||||||
1: JMP :2
|
1: JMP :2
|
||||||
0: ST r14, r254, 67a, 8h
|
0: ST r14, r254, 67a, 8h
|
||||||
CP r2, r19
|
CP r2, r24
|
||||||
CP r3, r18
|
CP r3, r23
|
||||||
CP r4, r21
|
CP r4, r22
|
||||||
CP r5, r17
|
CP r5, r21
|
||||||
ECA
|
ECA
|
||||||
ST r15, r254, 42a, 8h
|
ST r15, r254, 42a, 8h
|
||||||
CP r2, r19
|
CP r2, r24
|
||||||
CP r3, r18
|
CP r3, r23
|
||||||
CP r4, r20
|
CP r4, r17
|
||||||
CP r5, r17
|
CP r5, r21
|
||||||
ECA
|
ECA
|
||||||
|
SUB64 r13, r13, r23
|
||||||
SUB64 r15, r15, r27
|
SUB64 r15, r15, r27
|
||||||
ADD64 r14, r27, r14
|
ADD64 r14, r27, r14
|
||||||
SUB64 r13, r13, r18
|
|
||||||
JMP :3
|
JMP :3
|
||||||
2: ADDI64 r254, r254, 108d
|
2: ADDI64 r254, r254, 108d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
|
@ -7,8 +7,8 @@ fib:
|
||||||
2: JNE r13, r15, :0
|
2: JNE r13, r15, :0
|
||||||
CP r1, r14
|
CP r1, r14
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADD64 r14, r16, r14
|
0: SUB64 r13, r13, r17
|
||||||
SUB64 r13, r13, r17
|
ADD64 r14, r16, r14
|
||||||
SWA r14, r16
|
SWA r14, r16
|
||||||
JMP :2
|
JMP :2
|
||||||
1: JALA r0, r31, 0a
|
1: JALA r0, r31, 0a
|
||||||
|
|
|
@ -23,8 +23,8 @@ sqrt:
|
||||||
ADD64 r18, r18, r15
|
ADD64 r18, r18, r15
|
||||||
SLU64 r18, r18, r16
|
SLU64 r18, r18, r16
|
||||||
JLTU r13, r18, :2
|
JLTU r13, r18, :2
|
||||||
ADD64 r14, r15, r14
|
|
||||||
SUB64 r13, r13, r18
|
SUB64 r13, r13, r18
|
||||||
|
ADD64 r14, r15, r14
|
||||||
JMP :2
|
JMP :2
|
||||||
2: SRUI64 r15, r15, 1b
|
2: SRUI64 r15, r15, 1b
|
||||||
JMP :3
|
JMP :3
|
||||||
|
|
|
@ -1,46 +1,45 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -40d
|
ADDI64 r254, r254, -40d
|
||||||
LI64 r17, 1d
|
LI64 r17, 1d
|
||||||
LI64 r16, 4d
|
LI64 r15, 4d
|
||||||
CP r14, r0
|
CP r14, r0
|
||||||
ADDI64 r18, r254, 0d
|
ADDI64 r18, r254, 0d
|
||||||
CP r13, r14
|
CP r13, r14
|
||||||
6: JNE r13, r16, :0
|
6: JNE r13, r15, :0
|
||||||
LI64 r19, 2d
|
ADDI64 r19, r254, 32d
|
||||||
ADDI64 r20, r254, 32d
|
LI64 r20, 2d
|
||||||
CP r13, r14
|
CP r13, r14
|
||||||
4: LD r15, r254, 16a, 8h
|
4: LD r15, r254, 16a, 8h
|
||||||
JNE r13, r17, :1
|
JNE r13, r17, :1
|
||||||
CP r1, r15
|
CP r1, r15
|
||||||
JMP :2
|
JMP :2
|
||||||
1: MUL64 r21, r13, r19
|
1: ADD64 r16, r13, r17
|
||||||
ADD64 r16, r13, r17
|
SUB64 r15, r20, r16
|
||||||
SUB64 r13, r19, r16
|
MUL64 r21, r15, r20
|
||||||
MUL64 r22, r13, r19
|
MUL64 r22, r13, r20
|
||||||
CP r13, r14
|
CP r13, r14
|
||||||
5: JNE r13, r19, :3
|
5: JNE r13, r20, :3
|
||||||
CP r13, r16
|
CP r13, r16
|
||||||
JMP :4
|
JMP :4
|
||||||
3: ADD64 r15, r13, r17
|
3: ADD64 r15, r13, r17
|
||||||
ADD64 r23, r21, r13
|
ADD64 r23, r22, r13
|
||||||
ADD64 r13, r22, r13
|
ADD64 r13, r21, r13
|
||||||
MULI64 r23, r23, 8d
|
MULI64 r23, r23, 8d
|
||||||
MULI64 r13, r13, 8d
|
MULI64 r13, r13, 8d
|
||||||
ADD64 r23, r18, r23
|
ADD64 r23, r18, r23
|
||||||
ADD64 r13, r18, r13
|
ADD64 r13, r18, r13
|
||||||
BMC r23, r20, 8h
|
BMC r23, r19, 8h
|
||||||
BMC r13, r23, 8h
|
BMC r13, r23, 8h
|
||||||
BMC r20, r13, 8h
|
BMC r19, r13, 8h
|
||||||
CP r13, r15
|
CP r13, r15
|
||||||
JMP :5
|
JMP :5
|
||||||
0: ADD64 r15, r13, r17
|
0: MULI64 r16, r13, 8d
|
||||||
MULI64 r19, r13, 8d
|
ADD64 r16, r18, r16
|
||||||
ADD64 r19, r18, r19
|
ST r13, r16, 0a, 8h
|
||||||
ST r13, r19, 0a, 8h
|
ADD64 r13, r13, r17
|
||||||
CP r13, r15
|
|
||||||
JMP :6
|
JMP :6
|
||||||
2: ADDI64 r254, r254, 40d
|
2: ADDI64 r254, r254, 40d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 270
|
code size: 267
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -28,8 +28,8 @@ fib_iter:
|
||||||
2: JNE r13, r15, :0
|
2: JNE r13, r15, :0
|
||||||
CP r1, r14
|
CP r1, r14
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADD64 r14, r16, r14
|
0: SUB64 r13, r13, r17
|
||||||
SUB64 r13, r13, r17
|
ADD64 r14, r16, r14
|
||||||
SWA r14, r16
|
SWA r14, r16
|
||||||
JMP :2
|
JMP :2
|
||||||
1: JALA r0, r31, 0a
|
1: JALA r0, r31, 0a
|
||||||
|
|
|
@ -8,9 +8,9 @@ main:
|
||||||
4: JLTU r13, r17, :0
|
4: JLTU r13, r17, :0
|
||||||
LI64 r16, 10d
|
LI64 r16, 10d
|
||||||
CP r13, r14
|
CP r13, r14
|
||||||
3: LD r17, r254, 2048a, 1h
|
3: LD r15, r254, 2048a, 1h
|
||||||
JLTU r13, r16, :1
|
JLTU r13, r16, :1
|
||||||
ANDI r13, r17, 255d
|
ANDI r13, r15, 255d
|
||||||
CP r1, r13
|
CP r1, r13
|
||||||
JMP :2
|
JMP :2
|
||||||
1: ADD64 r15, r13, r14
|
1: ADD64 r15, r13, r14
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
main:
|
main:
|
||||||
LI64 r16, 4621819117588971520d
|
LI64 r16, 1d
|
||||||
LI64 r17, 1d
|
LI64 r17, 4621819117588971520d
|
||||||
LI64 r18, 3d
|
LI64 r18, 3d
|
||||||
CP r14, r0
|
CP r14, r0
|
||||||
CP r15, r14
|
CP r15, r14
|
||||||
3: JNE r15, r18, :0
|
3: JNE r15, r18, :0
|
||||||
CP r1, r17
|
CP r1, r16
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ITF64 r19, r15
|
0: ITF64 r19, r15
|
||||||
CP r13, r14
|
CP r13, r14
|
||||||
5: JNE r13, r18, :2
|
5: JNE r13, r18, :2
|
||||||
ADD64 r15, r15, r17
|
ADD64 r15, r15, r16
|
||||||
JMP :3
|
JMP :3
|
||||||
2: ITF64 r20, r13
|
2: ITF64 r20, r13
|
||||||
FMUL64 r20, r20, r19
|
FMUL64 r20, r20, r19
|
||||||
FCMPLT64 r20, r20, r16
|
FCMPLT64 r20, r20, r17
|
||||||
NOT r20, r20
|
NOT r20, r20
|
||||||
ANDI r20, r20, 255d
|
ANDI r20, r20, 255d
|
||||||
JNE r20, r0, :4
|
JNE r20, r0, :4
|
||||||
ADD64 r13, r13, r17
|
ADD64 r13, r13, r16
|
||||||
JMP :5
|
JMP :5
|
||||||
4: CP r1, r14
|
4: CP r1, r14
|
||||||
1: JALA r0, r31, 0a
|
1: JALA r0, r31, 0a
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -1d
|
ADDI64 r254, r254, -1d
|
||||||
|
ST r0, r254, 0a, 1h
|
||||||
LI64 r14, 255d
|
LI64 r14, 255d
|
||||||
LI8 r13, 1b
|
LI8 r13, 1b
|
||||||
ST r0, r254, 0a, 1h
|
|
||||||
2: LD r15, r254, 0a, 1h
|
2: LD r15, r254, 0a, 1h
|
||||||
ANDI r16, r15, 255d
|
ANDI r16, r15, 255d
|
||||||
CMPU r17, r16, r14
|
CMPU r17, r16, r14
|
||||||
|
|
Loading…
Reference in a new issue