Compare commits
2 commits
be828b8c54
...
97eb985a02
Author | SHA1 | Date | |
---|---|---|---|
97eb985a02 | |||
7ef1adf7e2 |
47
f.txt
Normal file
47
f.txt
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
start: 0
|
||||||
|
46-c65535: +: [0, 38, 45] [47]
|
||||||
|
45-c65535: &: [0, 43, 44] [46]
|
||||||
|
44-c65535: cint: #255 [0] [45]
|
||||||
|
43-c65535: load: [0, 42, 23] [45]
|
||||||
|
42-c65535: +: [0, 22, 18] [43]
|
||||||
|
39-c65535: stre: [0, 0, 36, 37] [47]
|
||||||
|
39-c65535: stre: [0, 0, 36, 37] [47]
|
||||||
|
37-c65535: stre: [0, 35, 36, 3] [38, 39]
|
||||||
|
36-c65535: stck: [0, 3] [37, 38, 39]
|
||||||
|
35-c65535: load: [0, 24, 34] [37]
|
||||||
|
34-c65535: stre: [0, 31, 33, 30] [35, 47]
|
||||||
|
33-c65535: +: [0, 24, 32] [34]
|
||||||
|
32-c65535: cint: #16 [0] [33]
|
||||||
|
31-c65535: cint: #4 [0] [34]
|
||||||
|
30-c65535: stre: [0, 27, 29, 26] [34]
|
||||||
|
29-c65535: +: [0, 24, 28] [30]
|
||||||
|
28-c65535: cint: #8 [0] [29]
|
||||||
|
27-c65535: cint: #2 [0] [30]
|
||||||
|
26-c65535: stre: [0, 25, 24, 3] [30]
|
||||||
|
25-c65535: cint: #1 [0] [26]
|
||||||
|
24-c65535: stck: [0, 3] [26, 29, 33, 35]
|
||||||
|
23-c65535: stre: [0, 21, 22, 3] [43, 47]
|
||||||
|
22-c65535: stck: [0, 3] [23, 42]
|
||||||
|
21-c65535: load: [0, 6, 20] [23]
|
||||||
|
20-c65535: stre: [0, 17, 19, 14] [21, 47]
|
||||||
|
19-c65535: +: [0, 6, 18] [20]
|
||||||
|
18-c65535: cint: #3 [0] [19, 42]
|
||||||
|
17-c65535: cint: #1 [0] [20]
|
||||||
|
14-c65535: stre: [0, 5, 13, 11] [20]
|
||||||
|
13-c65535: +: [0, 6, 12] [14]
|
||||||
|
12-c65535: cint: #2 [0] [13]
|
||||||
|
11-c65535: stre: [0, 7, 10, 8] [14]
|
||||||
|
10-c65535: +: [0, 6, 9] [11]
|
||||||
|
9-c65535: cint: #1 [0] [10]
|
||||||
|
8-c65535: stre: [0, 7, 6, 3] [11]
|
||||||
|
7-c65535: cint: #0 [0] [8, 11]
|
||||||
|
6-c65535: stck: [0, 3] [8, 10, 13, 19, 21]
|
||||||
|
5-c65535: cint: #511 [0] [14]
|
||||||
|
4-c65535: loops: [0] []
|
||||||
|
3-c65535: mem: [0] [6, 8, 22, 23, 24, 26, 36, 37, 47]
|
||||||
|
2-c65535: ctrl: entry [0] [38]
|
||||||
|
b2: 0 0 [38]
|
||||||
|
38-c65535: call: 1 0 [2, 36, 37] [46, 47]
|
||||||
|
47-c65535: ret: [38, 46, 3, 20, 23, 34, 39] [1]
|
||||||
|
|
||||||
|
|
38
f1.txt
Normal file
38
f1.txt
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
|
||||||
|
start: 0
|
||||||
|
34-c65535: stre: [0, 31, 51, 30] [39, 47, 38]
|
||||||
|
51-c65535: +: [0, 36, 32] [34]
|
||||||
|
32-c65535: cint: #16 [0] [51]
|
||||||
|
31-c65535: cint: #4 [0] [34]
|
||||||
|
30-c65535: stre: [0, 27, 50, 26] [34]
|
||||||
|
50-c65535: +: [0, 36, 28] [30]
|
||||||
|
28-c65535: cint: #8 [0] [50]
|
||||||
|
27-c65535: cint: #2 [0] [30]
|
||||||
|
26-c65535: stre: [0, 25, 36, 3] [30]
|
||||||
|
25-c65535: cint: #1 [0] [26, 46]
|
||||||
|
39-c65535: stre: [0, 0, 36, 34] [47]
|
||||||
|
36-c65535: stck: [0, 3] [51, 38, 39, 26, 50]
|
||||||
|
22-c65535: stck: [0, 3] [49, 42, 8, 48]
|
||||||
|
39-c65535: stre: [0, 0, 36, 34] [47]
|
||||||
|
20-c65535: stre: [0, 17, 42, 14] [47, 47]
|
||||||
|
46-c65535: +: [0, 38, 25] [47]
|
||||||
|
18-c65535: cint: #3 [0] [42]
|
||||||
|
17-c65535: cint: #1 [0] [20]
|
||||||
|
14-c65535: stre: [0, 5, 49, 11] [20]
|
||||||
|
49-c65535: +: [0, 22, 12] [14]
|
||||||
|
12-c65535: cint: #2 [0] [49]
|
||||||
|
11-c65535: stre: [0, 7, 48, 8] [14]
|
||||||
|
48-c65535: +: [0, 22, 9] [11]
|
||||||
|
9-c65535: cint: #1 [0] [48]
|
||||||
|
8-c65535: stre: [0, 7, 22, 3] [11]
|
||||||
|
7-c65535: cint: #0 [0] [8, 11]
|
||||||
|
42-c65535: +: [0, 22, 18] [20]
|
||||||
|
5-c65535: cint: #511 [0] [14]
|
||||||
|
4-c65535: loops: [0] []
|
||||||
|
3-c65535: mem: [0] [47, 8, 22, 26, 36]
|
||||||
|
2-c65535: ctrl: entry [0] [38]
|
||||||
|
b2: 0 0 [38]
|
||||||
|
38-c65535: call: 1 0 [2, 36, 34] [46, 47]
|
||||||
|
47-c65535: ret: [38, 46, 3, 20, 20, 34, 39] [1]
|
||||||
|
|
||||||
|
|
39
f2.txt
Normal file
39
f2.txt
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
start: 0
|
||||||
|
42-c65535: +: [0, 22, 18] [43, 20]
|
||||||
|
36-c65535: stck: [0, 3] [51, 38, 39, 26, 50]
|
||||||
|
39-c65535: stre: [0, 0, 36, 34] [47]
|
||||||
|
34-c65535: stre: [0, 31, 51, 30] [39, 47, 38]
|
||||||
|
51-c65535: +: [0, 36, 32] [34]
|
||||||
|
32-c65535: cint: #16 [0] [51]
|
||||||
|
31-c65535: cint: #4 [0] [34]
|
||||||
|
30-c65535: stre: [0, 27, 50, 26] [34]
|
||||||
|
50-c65535: +: [0, 36, 28] [30]
|
||||||
|
28-c65535: cint: #8 [0] [50]
|
||||||
|
27-c65535: cint: #2 [0] [30]
|
||||||
|
26-c65535: stre: [0, 25, 36, 3] [30]
|
||||||
|
25-c65535: cint: #1 [0] [26]
|
||||||
|
39-c65535: stre: [0, 0, 36, 34] [47]
|
||||||
|
45-c65535: &: [0, 43, 44] [46]
|
||||||
|
22-c65535: stck: [0, 3] [49, 42, 8, 48]
|
||||||
|
44-c65535: cint: #255 [0] [45]
|
||||||
|
20-c65535: stre: [0, 17, 42, 14] [47, 47, 43]
|
||||||
|
46-c65535: +: [0, 38, 45] [47]
|
||||||
|
18-c65535: cint: #3 [0] [42]
|
||||||
|
17-c65535: cint: #1 [0] [20]
|
||||||
|
14-c65535: stre: [0, 5, 49, 11] [20]
|
||||||
|
49-c65535: +: [0, 22, 12] [14]
|
||||||
|
12-c65535: cint: #2 [0] [49]
|
||||||
|
11-c65535: stre: [0, 7, 48, 8] [14]
|
||||||
|
48-c65535: +: [0, 22, 9] [11]
|
||||||
|
9-c65535: cint: #1 [0] [48]
|
||||||
|
8-c65535: stre: [0, 7, 22, 3] [11]
|
||||||
|
7-c65535: cint: #0 [0] [8, 11]
|
||||||
|
43-c65535: load: [0, 42, 20] [45]
|
||||||
|
5-c65535: cint: #511 [0] [14]
|
||||||
|
4-c65535: loops: [0] []
|
||||||
|
3-c65535: mem: [0] [47, 8, 22, 26, 36]
|
||||||
|
2-c65535: ctrl: entry [0] [38]
|
||||||
|
b2: 0 0 [38]
|
||||||
|
38-c65535: call: 1 0 [2, 36, 34] [46, 47]
|
||||||
|
47-c65535: ret: [38, 46, 3, 20, 20, 34, 39] [1]
|
||||||
|
|
467
lang/src/son.rs
467
lang/src/son.rs
|
@ -45,7 +45,7 @@ impl crate::ctx_map::CtxEntry for Nid {
|
||||||
type Key<'a> = (Kind, &'a [Nid], ty::Id);
|
type Key<'a> = (Kind, &'a [Nid], ty::Id);
|
||||||
|
|
||||||
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a> {
|
fn key<'a>(&self, ctx: &'a Self::Ctx) -> Self::Key<'a> {
|
||||||
ctx[*self as usize].as_ref().unwrap().key()
|
ctx[*self as usize].as_ref().unwrap_or_else(|(_, t)| panic!("{t:#?}")).key()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ struct Nodes {
|
||||||
visited: BitSet,
|
visited: BitSet,
|
||||||
free: Nid,
|
free: Nid,
|
||||||
lookup: Lookup,
|
lookup: Lookup,
|
||||||
|
complete: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Nodes {
|
impl Default for Nodes {
|
||||||
|
@ -82,6 +83,7 @@ impl Default for Nodes {
|
||||||
free: Nid::MAX,
|
free: Nid::MAX,
|
||||||
lookup: Default::default(),
|
lookup: Default::default(),
|
||||||
visited: Default::default(),
|
visited: Default::default(),
|
||||||
|
complete: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,7 +232,7 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_up(&mut self, rpo: &mut Vec<Nid>) {
|
fn push_up(&mut self, rpo: &mut Vec<Nid>) {
|
||||||
rpo.clear();
|
debug_assert!(rpo.is_empty());
|
||||||
self.collect_rpo(VOID, rpo);
|
self.collect_rpo(VOID, rpo);
|
||||||
|
|
||||||
for &node in rpo.iter().rev() {
|
for &node in rpo.iter().rev() {
|
||||||
|
@ -262,6 +264,8 @@ impl Nodes {
|
||||||
&& !matches!(nod.kind, Kind::Arg | Kind::Mem | Kind::Loops))
|
&& !matches!(nod.kind, Kind::Arg | Kind::Mem | Kind::Loops))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
rpo.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn better(&mut self, is: Nid, then: Nid) -> bool {
|
fn better(&mut self, is: Nid, then: Nid) -> bool {
|
||||||
|
@ -491,6 +495,7 @@ impl Nodes {
|
||||||
self.values.clear();
|
self.values.clear();
|
||||||
self.lookup.clear();
|
self.lookup.clear();
|
||||||
self.free = Nid::MAX;
|
self.free = Nid::MAX;
|
||||||
|
self.complete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_node_nop(&mut self, ty: ty::Id, kind: Kind, inps: impl Into<Vc>) -> Nid {
|
fn new_node_nop(&mut self, ty: ty::Id, kind: Kind, inps: impl Into<Vc>) -> Nid {
|
||||||
|
@ -610,13 +615,13 @@ impl Nodes {
|
||||||
fn late_peephole(&mut self, target: Nid) -> Option<Nid> {
|
fn late_peephole(&mut self, target: Nid) -> Option<Nid> {
|
||||||
if let Some(id) = self.peephole(target) {
|
if let Some(id) = self.peephole(target) {
|
||||||
self.replace(target, id);
|
self.replace(target, id);
|
||||||
return Some(id);
|
return None;
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_peeps(&mut self, mut fuel: usize, stack: &mut Vec<Nid>) {
|
fn iter_peeps(&mut self, mut fuel: usize, stack: &mut Vec<Nid>) {
|
||||||
stack.clear();
|
debug_assert!(stack.is_empty());
|
||||||
|
|
||||||
self.iter()
|
self.iter()
|
||||||
.filter_map(|(id, node)| node.kind.is_peeped().then_some(id))
|
.filter_map(|(id, node)| node.kind.is_peeped().then_some(id))
|
||||||
|
@ -627,19 +632,57 @@ impl Nodes {
|
||||||
&& let Some(node) = stack.pop()
|
&& let Some(node) = stack.pop()
|
||||||
{
|
{
|
||||||
fuel -= 1;
|
fuel -= 1;
|
||||||
|
|
||||||
|
if self[node].outputs.is_empty() {
|
||||||
|
self.push_adjacent_nodes(node, stack);
|
||||||
|
}
|
||||||
|
|
||||||
if self.unlock_remove(node) {
|
if self.unlock_remove(node) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let new = self.late_peephole(node);
|
|
||||||
if let Some(new) = new {
|
if let Some(new) = self.peephole(node) {
|
||||||
let prev_len = stack.len();
|
self.replace(node, new);
|
||||||
for &i in self[new].outputs.iter().chain(self[new].inputs.iter()) {
|
self.push_adjacent_nodes(new, stack);
|
||||||
if self[i].kind.is_peeped() && self[i].lock_rc == 0 {
|
|
||||||
stack.push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stack.iter().skip(prev_len).for_each(|&n| self.lock(n));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug_assert_matches!(
|
||||||
|
self.iter()
|
||||||
|
.find(|(i, n)| n.lock_rc != 0 && n.kind.is_peeped() && !stack.contains(i)),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.drain(..).for_each(|s| _ = self.unlock_remove(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_adjacent_nodes(&mut self, of: Nid, stack: &mut Vec<Nid>) {
|
||||||
|
let prev_len = stack.len();
|
||||||
|
for &i in self[of]
|
||||||
|
.outputs
|
||||||
|
.iter()
|
||||||
|
.chain(self[of].inputs.iter())
|
||||||
|
.chain(self[of].peep_triggers.iter())
|
||||||
|
{
|
||||||
|
if self.values[i as usize].is_ok() && self[i].kind.is_peeped() && self[i].lock_rc == 0 {
|
||||||
|
stack.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self[of].peep_triggers = Vc::default();
|
||||||
|
stack.iter().skip(prev_len).for_each(|&n| self.lock(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn aclass_index(&self, mut region: Nid) -> (usize, Nid) {
|
||||||
|
loop {
|
||||||
|
region = match self[region].kind {
|
||||||
|
Kind::BinOp { op: TokenKind::Add | TokenKind::Sub } => self[region].inputs[1],
|
||||||
|
Kind::Phi => {
|
||||||
|
debug_assert_eq!(self[region].inputs[2], 0);
|
||||||
|
self[region].inputs[1]
|
||||||
|
}
|
||||||
|
_ => break (self[region].aclass, region),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,11 +866,47 @@ impl Nodes {
|
||||||
|
|
||||||
return Some(ctrl);
|
return Some(ctrl);
|
||||||
}
|
}
|
||||||
K::Call { .. } | K::Return => {
|
K::Call { .. } => {
|
||||||
if self[target].inputs[0] == NEVER {
|
if self[target].inputs[0] == NEVER {
|
||||||
return Some(NEVER);
|
return Some(NEVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
K::Return => {
|
||||||
|
if self[target].inputs[0] == NEVER {
|
||||||
|
return Some(NEVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut new_inps = Vc::from(&self[target].inputs[..2]);
|
||||||
|
'a: for &n in self[target].inputs.clone().iter().skip(2) {
|
||||||
|
if self[n].kind != Kind::Stre || self[n].inputs.len() != 4 {
|
||||||
|
new_inps.push(n);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cursor = n;
|
||||||
|
let class = self.aclass_index(self[cursor].inputs[2]);
|
||||||
|
|
||||||
|
if self[class.1].kind != Kind::Stck {
|
||||||
|
new_inps.push(n);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = self[cursor].inputs[3];
|
||||||
|
while cursor != MEM {
|
||||||
|
if self.aclass_index(self[cursor].inputs[2]) != class
|
||||||
|
|| self[cursor].inputs.len() != 4
|
||||||
|
{
|
||||||
|
new_inps.push(n);
|
||||||
|
continue 'a;
|
||||||
|
}
|
||||||
|
cursor = self[cursor].inputs[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if new_inps.as_slice() != self[target].inputs.as_slice() {
|
||||||
|
return Some(self.new_node_nop(ty::Id::VOID, Kind::Return, new_inps));
|
||||||
|
}
|
||||||
|
}
|
||||||
K::Phi => {
|
K::Phi => {
|
||||||
let &[ctrl, lhs, rhs] = self[target].inputs.as_slice() else { unreachable!() };
|
let &[ctrl, lhs, rhs] = self[target].inputs.as_slice() else { unreachable!() };
|
||||||
|
|
||||||
|
@ -857,18 +936,129 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
K::Stre => {
|
K::Stre => {
|
||||||
if self[target].inputs[1] != VOID
|
let &[_, value, region, store, ..] = self[target].inputs.as_slice() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
'eliminate: {
|
||||||
|
if self[target].outputs.is_empty() {
|
||||||
|
break 'eliminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self[value].kind != Kind::Load || self[value].outputs.as_slice() != [target]
|
||||||
|
{
|
||||||
|
for &ele in self[value].outputs.clone().iter().filter(|&&n| n != target) {
|
||||||
|
self[ele].peep_triggers.push(target);
|
||||||
|
}
|
||||||
|
break 'eliminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
let &[_, stack, last_store] = self[value].inputs.as_slice() else {
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
|
if self[stack].ty != self[value].ty || self[stack].kind != Kind::Stck {
|
||||||
|
break 'eliminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut unidentifed = self[stack].outputs.clone();
|
||||||
|
let load_idx = unidentifed.iter().position(|&n| n == value).unwrap();
|
||||||
|
unidentifed.swap_remove(load_idx);
|
||||||
|
|
||||||
|
let mut saved = Vc::default();
|
||||||
|
let mut cursor = last_store;
|
||||||
|
let mut first_store = last_store;
|
||||||
|
while cursor != MEM && self[cursor].kind == Kind::Stre {
|
||||||
|
let mut contact_point = cursor;
|
||||||
|
let mut region = self[cursor].inputs[2];
|
||||||
|
if let Kind::BinOp { op } = self[region].kind {
|
||||||
|
debug_assert_matches!(op, TokenKind::Add | TokenKind::Sub);
|
||||||
|
contact_point = region;
|
||||||
|
region = self[region].inputs[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if region != stack {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let Some(index) = unidentifed.iter().position(|&n| n == contact_point)
|
||||||
|
else {
|
||||||
|
break 'eliminate;
|
||||||
|
};
|
||||||
|
unidentifed.remove(index);
|
||||||
|
saved.push(contact_point);
|
||||||
|
first_store = cursor;
|
||||||
|
cursor = *self[cursor].inputs.get(3).unwrap_or(&MEM);
|
||||||
|
|
||||||
|
if unidentifed.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this can be an offset already due to previous peeps so handle that
|
||||||
|
if let &[mcall] = unidentifed.as_slice()
|
||||||
|
&& matches!(self[mcall].kind, Kind::Call { .. })
|
||||||
|
&& self[mcall].inputs.last() == Some(&stack)
|
||||||
|
{
|
||||||
|
self.modify_input(mcall, self[mcall].inputs.len() - 1, region);
|
||||||
|
|
||||||
|
return Some(last_store);
|
||||||
|
} else {
|
||||||
|
debug_assert_matches!(
|
||||||
|
self[last_store].kind,
|
||||||
|
Kind::Stre | Kind::Mem,
|
||||||
|
"{:?}",
|
||||||
|
self[last_store]
|
||||||
|
);
|
||||||
|
debug_assert_matches!(
|
||||||
|
self[first_store].kind,
|
||||||
|
Kind::Stre | Kind::Mem,
|
||||||
|
"{:?}",
|
||||||
|
self[first_store]
|
||||||
|
);
|
||||||
|
|
||||||
|
if !unidentifed.is_empty() {
|
||||||
|
break 'eliminate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: when the loads and stores become parallel we will need to get saved
|
||||||
|
// differently
|
||||||
|
let mut prev_store = store;
|
||||||
|
for mut oper in saved.into_iter().rev() {
|
||||||
|
let mut region = region;
|
||||||
|
if let Kind::BinOp { op } = self[oper].kind {
|
||||||
|
debug_assert_eq!(self[oper].outputs.len(), 1);
|
||||||
|
debug_assert_eq!(self[self[oper].outputs[0]].kind, Kind::Stre);
|
||||||
|
region = self.new_node(self[oper].ty, Kind::BinOp { op }, [
|
||||||
|
VOID,
|
||||||
|
region,
|
||||||
|
self[oper].inputs[2],
|
||||||
|
]);
|
||||||
|
oper = self[oper].outputs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut inps = self[oper].inputs.clone();
|
||||||
|
debug_assert_eq!(inps.len(), 4);
|
||||||
|
inps[2] = region;
|
||||||
|
inps[3] = prev_store;
|
||||||
|
prev_store = self.new_node(self[oper].ty, Kind::Stre, inps);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Some(prev_store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if value != VOID
|
||||||
&& self[target].inputs.len() == 4
|
&& self[target].inputs.len() == 4
|
||||||
&& self[self[target].inputs[1]].kind != Kind::Load
|
&& self[value].kind != Kind::Load
|
||||||
&& self[self[target].inputs[3]].kind == Kind::Stre
|
&& self[store].kind == Kind::Stre
|
||||||
&& self[self[target].inputs[3]].lock_rc == 0
|
&& self[store].lock_rc == 0
|
||||||
&& self[self[target].inputs[3]].inputs[2] == self[target].inputs[2]
|
&& self[store].inputs[2] == region
|
||||||
{
|
{
|
||||||
return Some(self.modify_input(
|
if self[store].inputs[1] == value {
|
||||||
self[target].inputs[3],
|
return Some(store);
|
||||||
1,
|
}
|
||||||
self[target].inputs[1],
|
|
||||||
));
|
return Some(self.modify_input(store, 1, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
K::Load => {
|
K::Load => {
|
||||||
|
@ -908,43 +1098,45 @@ impl Nodes {
|
||||||
|
|
||||||
fn replace(&mut self, target: Nid, with: Nid) {
|
fn replace(&mut self, target: Nid, with: Nid) {
|
||||||
debug_assert_ne!(target, with, "{:?}", self[target]);
|
debug_assert_ne!(target, with, "{:?}", self[target]);
|
||||||
let mut back_press = 0;
|
for out in self[target].outputs.clone() {
|
||||||
for i in 0..self[target].outputs.len() {
|
|
||||||
let out = self[target].outputs[i - back_press];
|
|
||||||
let index = self[out].inputs.iter().position(|&p| p == target).unwrap();
|
let index = self[out].inputs.iter().position(|&p| p == target).unwrap();
|
||||||
self.lock(target);
|
|
||||||
let prev_len = self[target].outputs.len();
|
|
||||||
self.modify_input(out, index, with);
|
self.modify_input(out, index, with);
|
||||||
back_press += (self[target].outputs.len() != prev_len) as usize;
|
|
||||||
self.unlock(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.remove(target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modify_input(&mut self, target: Nid, inp_index: usize, with: Nid) -> Nid {
|
fn modify_input(&mut self, target: Nid, inp_index: usize, with: Nid) -> Nid {
|
||||||
self.remove_node_lookup(target);
|
self.remove_node_lookup(target);
|
||||||
debug_assert_ne!(self[target].inputs[inp_index], with, "{:?}", self[target]);
|
debug_assert_ne!(self[target].inputs[inp_index], with, "{:?}", self[target]);
|
||||||
|
|
||||||
let prev = self[target].inputs[inp_index];
|
if self[target].is_not_gvnd() && (self[target].kind != Kind::Phi || with == 0) {
|
||||||
self[target].inputs[inp_index] = with;
|
let prev = self[target].inputs[inp_index];
|
||||||
let (entry, hash) = self.lookup.entry(target.key(&self.values), &self.values);
|
self[target].inputs[inp_index] = with;
|
||||||
match entry {
|
self[with].outputs.push(target);
|
||||||
hash_map::RawEntryMut::Occupied(other) => {
|
let index = self[prev].outputs.iter().position(|&o| o == target).unwrap();
|
||||||
let rpl = other.get_key_value().0.value;
|
self[prev].outputs.swap_remove(index);
|
||||||
self[target].inputs[inp_index] = prev;
|
self.remove(prev);
|
||||||
self.lookup.insert(target.key(&self.values), target, &self.values);
|
target
|
||||||
self.replace(target, rpl);
|
} else {
|
||||||
rpl
|
let prev = self[target].inputs[inp_index];
|
||||||
}
|
self[target].inputs[inp_index] = with;
|
||||||
hash_map::RawEntryMut::Vacant(slot) => {
|
let (entry, hash) = self.lookup.entry(target.key(&self.values), &self.values);
|
||||||
slot.insert(crate::ctx_map::Key { value: target, hash }, ());
|
match entry {
|
||||||
let index = self[prev].outputs.iter().position(|&o| o == target).unwrap();
|
hash_map::RawEntryMut::Occupied(other) => {
|
||||||
self[prev].outputs.swap_remove(index);
|
let rpl = other.get_key_value().0.value;
|
||||||
self[with].outputs.push(target);
|
self[target].inputs[inp_index] = prev;
|
||||||
self.remove(prev);
|
self.lookup.insert(target.key(&self.values), target, &self.values);
|
||||||
|
self.replace(target, rpl);
|
||||||
|
rpl
|
||||||
|
}
|
||||||
|
hash_map::RawEntryMut::Vacant(slot) => {
|
||||||
|
slot.insert(crate::ctx_map::Key { value: target, hash }, ());
|
||||||
|
let index = self[prev].outputs.iter().position(|&o| o == target).unwrap();
|
||||||
|
self[prev].outputs.swap_remove(index);
|
||||||
|
self[with].outputs.push(target);
|
||||||
|
self.remove(prev);
|
||||||
|
|
||||||
target
|
target
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1313,7 @@ impl Nodes {
|
||||||
if !matches!(node.kind, Kind::End | Kind::Mem | Kind::Arg | Kind::Loops)
|
if !matches!(node.kind, Kind::End | Kind::Mem | Kind::Arg | Kind::Loops)
|
||||||
&& node.outputs.is_empty()
|
&& node.outputs.is_empty()
|
||||||
{
|
{
|
||||||
log::error!("outputs are empry {id} {:?}", node.kind);
|
log::error!("outputs are empry {id} {:?}", node);
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
if node.inputs.first() == Some(&NEVER) && id != NEVER {
|
if node.inputs.first() == Some(&NEVER) && id != NEVER {
|
||||||
|
@ -1211,124 +1403,6 @@ impl Nodes {
|
||||||
dominated = self.idom(dominated);
|
dominated = self.idom(dominated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eliminate_stack_temporaries(&mut self) {
|
|
||||||
'o: for stack in self[MEM].outputs.clone() {
|
|
||||||
if self.values[stack as usize].is_err() || self[stack].kind != Kind::Stck {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let mut full_read_into = None;
|
|
||||||
let mut unidentifed = Vc::default();
|
|
||||||
for &o in self[stack].outputs.iter() {
|
|
||||||
match self[o].kind {
|
|
||||||
Kind::Load
|
|
||||||
if self[o].ty == self[stack].ty
|
|
||||||
&& self[o].outputs.iter().all(|&n| self[n].kind == Kind::Stre)
|
|
||||||
&& let mut full_stores = self[o].outputs.iter().filter(|&&n| {
|
|
||||||
self[n].kind == Kind::Stre && self[n].inputs[1] == o
|
|
||||||
})
|
|
||||||
&& let Some(&n) = full_stores.next()
|
|
||||||
&& full_stores.next().is_none() =>
|
|
||||||
{
|
|
||||||
if full_read_into.replace((n, self[o].inputs[2])).is_some() {
|
|
||||||
continue 'o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unidentifed.push(o),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let Some((dst, last_store)) = full_read_into else { continue };
|
|
||||||
|
|
||||||
let mut saved = Vc::default();
|
|
||||||
let mut cursor = last_store;
|
|
||||||
let mut first_store = last_store;
|
|
||||||
while cursor != MEM && self[cursor].kind == Kind::Stre {
|
|
||||||
let mut contact_point = cursor;
|
|
||||||
let mut region = self[cursor].inputs[2];
|
|
||||||
if let Kind::BinOp { op } = self[region].kind {
|
|
||||||
debug_assert_matches!(op, TokenKind::Add | TokenKind::Sub);
|
|
||||||
contact_point = region;
|
|
||||||
region = self[region].inputs[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
if region != stack {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let Some(index) = unidentifed.iter().position(|&n| n == contact_point) else {
|
|
||||||
continue 'o;
|
|
||||||
};
|
|
||||||
unidentifed.remove(index);
|
|
||||||
saved.push(contact_point);
|
|
||||||
first_store = cursor;
|
|
||||||
cursor = *self[cursor].inputs.get(3).unwrap_or(&MEM);
|
|
||||||
|
|
||||||
if unidentifed.is_empty() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let region = self[dst].inputs[2];
|
|
||||||
// TODO: this can be an offset already due to previous peeps so handle that
|
|
||||||
if let &[mcall] = unidentifed.as_slice()
|
|
||||||
&& matches!(self[mcall].kind, Kind::Call { .. })
|
|
||||||
&& self[mcall].inputs.last() == Some(&stack)
|
|
||||||
{
|
|
||||||
self.modify_input(mcall, self[mcall].inputs.len() - 1, region);
|
|
||||||
} else {
|
|
||||||
debug_assert_matches!(
|
|
||||||
self[last_store].kind,
|
|
||||||
Kind::Stre | Kind::Mem,
|
|
||||||
"{:?}",
|
|
||||||
self[last_store]
|
|
||||||
);
|
|
||||||
debug_assert_matches!(
|
|
||||||
self[first_store].kind,
|
|
||||||
Kind::Stre | Kind::Mem,
|
|
||||||
"{:?}",
|
|
||||||
self[first_store]
|
|
||||||
);
|
|
||||||
|
|
||||||
if !unidentifed.is_empty() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: when the loads and stores become parallel we will need to get saved
|
|
||||||
// differently
|
|
||||||
for mut oper in saved.into_iter().rev() {
|
|
||||||
let mut region = region;
|
|
||||||
if let Kind::BinOp { op } = self[oper].kind {
|
|
||||||
debug_assert_eq!(self[oper].outputs.len(), 1);
|
|
||||||
debug_assert_eq!(self[self[oper].outputs[0]].kind, Kind::Stre);
|
|
||||||
region = self.new_node(self[oper].ty, Kind::BinOp { op }, [
|
|
||||||
VOID,
|
|
||||||
region,
|
|
||||||
self[oper].inputs[2],
|
|
||||||
]);
|
|
||||||
oper = self[oper].outputs[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.modify_input(oper, 2, region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// self[first_store].lock_rc = u16::MAX - 1;
|
|
||||||
// self[last_store].lock_rc = u16::MAX - 1;
|
|
||||||
|
|
||||||
let prev_store = self[dst].inputs[3];
|
|
||||||
if prev_store != MEM && first_store != MEM {
|
|
||||||
self.modify_input(first_store, 3, prev_store);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.replace(dst, last_store);
|
|
||||||
if self.values[stack as usize].is_ok() {
|
|
||||||
self.lock(stack);
|
|
||||||
}
|
|
||||||
if self.values[dst as usize].is_ok() {
|
|
||||||
self.lock(dst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Index<Nid> for Nodes {
|
impl ops::Index<Nid> for Nodes {
|
||||||
|
@ -1426,7 +1500,7 @@ impl Kind {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_peeped(&self) -> bool {
|
fn is_peeped(&self) -> bool {
|
||||||
!matches!(self, Self::End | Self::Arg)
|
!matches!(self, Self::End | Self::Arg | Self::Mem | Self::Loops)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1449,6 +1523,7 @@ pub struct Node {
|
||||||
kind: Kind,
|
kind: Kind,
|
||||||
inputs: Vc,
|
inputs: Vc,
|
||||||
outputs: Vc,
|
outputs: Vc,
|
||||||
|
peep_triggers: Vc,
|
||||||
ty: ty::Id,
|
ty: ty::Id,
|
||||||
offset: Offset,
|
offset: Offset,
|
||||||
ralloc_backref: RallocBRef,
|
ralloc_backref: RallocBRef,
|
||||||
|
@ -1473,7 +1548,8 @@ impl Node {
|
||||||
|
|
||||||
fn is_not_gvnd(&self) -> bool {
|
fn is_not_gvnd(&self) -> bool {
|
||||||
(self.kind == Kind::Phi && self.inputs[2] == 0)
|
(self.kind == Kind::Phi && self.inputs[2] == 0)
|
||||||
|| matches!(self.kind, Kind::Arg | Kind::Stck | Kind::End)
|
|| matches!(self.kind, Kind::Arg | Kind::Stck)
|
||||||
|
|| self.kind.is_cfg()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_mem(&self) -> bool {
|
fn is_mem(&self) -> bool {
|
||||||
|
@ -1724,11 +1800,12 @@ impl ItemCtx {
|
||||||
self.scope.aclasses.push(AClass::new(&mut self.nodes));
|
self.scope.aclasses.push(AClass::new(&mut self.nodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finalize(&mut self, stack: &mut Vec<Nid>) {
|
fn finalize(&mut self, stack: &mut Vec<Nid>, _tys: &Types, _files: &[parser::Ast]) {
|
||||||
self.scope.clear(&mut self.nodes);
|
self.scope.clear(&mut self.nodes);
|
||||||
mem::take(&mut self.ctrl).soft_remove(&mut self.nodes);
|
mem::take(&mut self.ctrl).soft_remove(&mut self.nodes);
|
||||||
self.nodes.eliminate_stack_temporaries();
|
|
||||||
self.nodes.iter_peeps(1000, stack);
|
self.nodes.iter_peeps(1000, stack);
|
||||||
|
|
||||||
self.nodes.unlock(MEM);
|
self.nodes.unlock(MEM);
|
||||||
self.nodes.unlock(NEVER);
|
self.nodes.unlock(NEVER);
|
||||||
self.nodes.unlock(LOOPS);
|
self.nodes.unlock(LOOPS);
|
||||||
|
@ -1993,7 +2070,7 @@ impl<'a> Codegen<'a> {
|
||||||
);
|
);
|
||||||
debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
|
debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
|
||||||
|
|
||||||
let (value_index, value_region) = self.aclass_index(value);
|
let (value_index, value_region) = self.ci.nodes.aclass_index(value);
|
||||||
if value_index != 0 {
|
if value_index != 0 {
|
||||||
// simply switch the class to the default one
|
// simply switch the class to the default one
|
||||||
let aclass = &mut self.ci.scope.aclasses[value_index];
|
let aclass = &mut self.ci.scope.aclasses[value_index];
|
||||||
|
@ -2018,7 +2095,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes[value_region].aclass = 0;
|
self.ci.nodes[value_region].aclass = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = self.aclass_index(region);
|
let (index, _) = self.ci.nodes.aclass_index(region);
|
||||||
let aclass = &mut self.ci.scope.aclasses[index];
|
let aclass = &mut self.ci.scope.aclasses[index];
|
||||||
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
||||||
let mut vc = Vc::from([VOID, value, region, aclass.last_store.get()]);
|
let mut vc = Vc::from([VOID, value, region, aclass.last_store.get()]);
|
||||||
|
@ -2031,11 +2108,10 @@ impl<'a> Codegen<'a> {
|
||||||
vc.push(load);
|
vc.push(load);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let store = self.ci.nodes.new_node_nop(ty, Kind::Stre, vc);
|
mem::take(&mut aclass.last_store).soft_remove(&mut self.ci.nodes);
|
||||||
aclass.last_store.set(store, &mut self.ci.nodes);
|
let store = self.ci.nodes.new_node(ty, Kind::Stre, vc);
|
||||||
let opted = self.ci.nodes.late_peephole(store).unwrap_or(store);
|
aclass.last_store = StrongRef::new(store, &mut self.ci.nodes);
|
||||||
aclass.last_store.set_remove(opted, &mut self.ci.nodes);
|
store
|
||||||
opted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_mem(&mut self, region: Nid, ty: ty::Id) -> Nid {
|
fn load_mem(&mut self, region: Nid, ty: ty::Id) -> Nid {
|
||||||
|
@ -2052,7 +2128,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.ty_display(self.ci.nodes[region].ty)
|
self.ty_display(self.ci.nodes[region].ty)
|
||||||
);
|
);
|
||||||
debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
|
debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
|
||||||
let (index, _) = self.aclass_index(region);
|
let (index, _) = self.ci.nodes.aclass_index(region);
|
||||||
let aclass = &mut self.ci.scope.aclasses[index];
|
let aclass = &mut self.ci.scope.aclasses[index];
|
||||||
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
|
||||||
let vc = [VOID, region, aclass.last_store.get()];
|
let vc = [VOID, region, aclass.last_store.get()];
|
||||||
|
@ -2061,21 +2137,6 @@ impl<'a> Codegen<'a> {
|
||||||
load
|
load
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aclass_index(&mut self, mut region: Nid) -> (usize, Nid) {
|
|
||||||
loop {
|
|
||||||
region = match self.ci.nodes[region].kind {
|
|
||||||
Kind::BinOp { op: TokenKind::Add | TokenKind::Sub } => {
|
|
||||||
self.ci.nodes[region].inputs[1]
|
|
||||||
}
|
|
||||||
Kind::Phi => {
|
|
||||||
debug_assert_eq!(self.ci.nodes[region].inputs[2], 0);
|
|
||||||
self.ci.nodes[region].inputs[1]
|
|
||||||
}
|
|
||||||
_ => break (self.ci.nodes[region].aclass, region),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate(&mut self, entry: FileId) {
|
pub fn generate(&mut self, entry: FileId) {
|
||||||
self.find_type(0, entry, entry, Err("main"), self.files);
|
self.find_type(0, entry, entry, Err("main"), self.files);
|
||||||
if self.tys.ins.funcs.is_empty() {
|
if self.tys.ins.funcs.is_empty() {
|
||||||
|
@ -2229,7 +2290,7 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ci.ctrl.set(
|
self.ci.ctrl.set(
|
||||||
self.ci.nodes.new_node(ty::Id::VOID, Kind::Return, inps),
|
self.ci.nodes.new_node_nop(ty::Id::VOID, Kind::Return, inps),
|
||||||
&mut self.ci.nodes,
|
&mut self.ci.nodes,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2567,7 +2628,7 @@ impl<'a> Codegen<'a> {
|
||||||
for arg in args {
|
for arg in args {
|
||||||
let value = self.expr(arg)?;
|
let value = self.expr(arg)?;
|
||||||
if let Some(base) = self.tys.base_of(value.ty) {
|
if let Some(base) = self.tys.base_of(value.ty) {
|
||||||
clobbered_aliases.push(self.aclass_index(value.id).0);
|
clobbered_aliases.push(self.ci.nodes.aclass_index(value.id).0);
|
||||||
if base.has_pointers(self.tys) {
|
if base.has_pointers(self.tys) {
|
||||||
clobbered_aliases.push(0);
|
clobbered_aliases.push(0);
|
||||||
}
|
}
|
||||||
|
@ -2674,7 +2735,7 @@ impl<'a> Codegen<'a> {
|
||||||
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
|
self.assert_ty(arg.pos(), &mut value, ty, fa!("argument {}", carg.name));
|
||||||
|
|
||||||
if let Some(base) = self.tys.base_of(value.ty) {
|
if let Some(base) = self.tys.base_of(value.ty) {
|
||||||
clobbered_aliases.push(self.aclass_index(value.id).0);
|
clobbered_aliases.push(self.ci.nodes.aclass_index(value.id).0);
|
||||||
if base.has_pointers(self.tys) {
|
if base.has_pointers(self.tys) {
|
||||||
clobbered_aliases.push(0);
|
clobbered_aliases.push(0);
|
||||||
}
|
}
|
||||||
|
@ -3600,7 +3661,7 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
self.ci.scope.vars.drain(..).for_each(|v| v.remove_ignore_arg(&mut self.ci.nodes));
|
self.ci.scope.vars.drain(..).for_each(|v| v.remove_ignore_arg(&mut self.ci.nodes));
|
||||||
|
|
||||||
self.ci.finalize(&mut self.pool.nid_stack);
|
self.ci.finalize(&mut self.pool.nid_stack, self.tys, self.files);
|
||||||
|
|
||||||
if self.errors.borrow().len() == prev_err_len {
|
if self.errors.borrow().len() == prev_err_len {
|
||||||
self.ci.emit_body(self.tys, self.files, sig, self.pool);
|
self.ci.emit_body(self.tys, self.files, sig, self.pool);
|
||||||
|
@ -3737,7 +3798,7 @@ impl TypeParser for Codegen<'_> {
|
||||||
self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) });
|
self.expr(&Expr::Return { pos: expr.pos(), val: Some(expr) });
|
||||||
|
|
||||||
scope = mem::take(&mut self.ci.scope.vars);
|
scope = mem::take(&mut self.ci.scope.vars);
|
||||||
self.ci.finalize(&mut self.pool.nid_stack);
|
self.ci.finalize(&mut self.pool.nid_stack, self.tys, self.files);
|
||||||
|
|
||||||
let res = if self.errors.borrow().len() == prev_err_len {
|
let res = if self.errors.borrow().len() == prev_err_len {
|
||||||
self.emit_and_eval(file, ret, &mut [])
|
self.emit_and_eval(file, ret, &mut [])
|
||||||
|
@ -3781,7 +3842,7 @@ impl TypeParser for Codegen<'_> {
|
||||||
|
|
||||||
self.expr(&(Expr::Return { pos: expr.pos(), val: Some(expr) }));
|
self.expr(&(Expr::Return { pos: expr.pos(), val: Some(expr) }));
|
||||||
|
|
||||||
self.ci.finalize(&mut self.pool.nid_stack);
|
self.ci.finalize(&mut self.pool.nid_stack, self.tys, self.files);
|
||||||
|
|
||||||
let ret = self.ci.ret.expect("for return type to be infered");
|
let ret = self.ci.ret.expect("for return type to be infered");
|
||||||
if self.errors.borrow().len() == prev_err_len {
|
if self.errors.borrow().len() == prev_err_len {
|
||||||
|
|
|
@ -809,6 +809,7 @@ impl<'a> Function<'a> {
|
||||||
let mut args = self.nodes[VOID].outputs[ARG_START..].to_owned().into_iter();
|
let mut args = self.nodes[VOID].outputs[ARG_START..].to_owned().into_iter();
|
||||||
while let Some(ty) = typs.next_value(self.tys) {
|
while let Some(ty) = typs.next_value(self.tys) {
|
||||||
let arg = args.next().unwrap();
|
let arg = args.next().unwrap();
|
||||||
|
debug_assert_eq!(self.nodes[arg].kind, Kind::Arg);
|
||||||
match parama.next(ty, self.tys) {
|
match parama.next(ty, self.tys) {
|
||||||
None => {}
|
None => {}
|
||||||
Some(PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _)) => {
|
Some(PLoc::Reg(r, _) | PLoc::WideReg(r, _) | PLoc::Ref(r, _)) => {
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
main:
|
||||||
|
ADDI64 r254, r254, -24d
|
||||||
|
ADDI64 r2, r254, 16d
|
||||||
|
ST r2, r254, 0a, 8h
|
||||||
|
LI64 r5, 0d
|
||||||
|
LI64 r4, 2d
|
||||||
|
ST r5, r254, 8a, 8h
|
||||||
|
ST r4, r254, 16a, 8h
|
||||||
|
LD r10, r254, 0a, 8h
|
||||||
|
ST r5, r10, 0a, 8h
|
||||||
|
LD r1, r254, 16a, 8h
|
||||||
|
ADDI64 r254, r254, 24d
|
||||||
|
JALA r0, r31, 0a
|
||||||
|
code size: 150
|
||||||
|
ret: 0
|
||||||
|
status: Ok(())
|
|
@ -1,24 +1,17 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -44d
|
ADDI64 r254, r254, -40d
|
||||||
ST r31, r254, 28a, 16h
|
ST r31, r254, 24a, 16h
|
||||||
LI64 r32, 1d
|
LI64 r32, 1d
|
||||||
ADDI64 r2, r254, 0d
|
ADDI64 r2, r254, 0d
|
||||||
ST r32, r254, 0a, 8h
|
ST r32, r254, 0a, 8h
|
||||||
LI64 r8, 2d
|
LI64 r5, 2d
|
||||||
ST r8, r254, 8a, 8h
|
ST r5, r254, 8a, 8h
|
||||||
LI64 r11, 4d
|
LI64 r8, 4d
|
||||||
ST r11, r254, 16a, 8h
|
ST r8, r254, 16a, 8h
|
||||||
JAL r31, r0, :pass
|
JAL r31, r0, :pass
|
||||||
LI8 r10, 0b
|
|
||||||
ST r10, r254, 24a, 1h
|
|
||||||
ST r10, r254, 25a, 1h
|
|
||||||
LI16 r12, 511h
|
|
||||||
ST r12, r254, 26a, 1h
|
|
||||||
LI16 r4, 1h
|
|
||||||
ST r4, r254, 27a, 1h
|
|
||||||
ADD64 r1, r1, r32
|
ADD64 r1, r1, r32
|
||||||
LD r31, r254, 28a, 16h
|
LD r31, r254, 24a, 16h
|
||||||
ADDI64 r254, r254, 44d
|
ADDI64 r254, r254, 40d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
pass:
|
pass:
|
||||||
LD r4, r2, 8a, 8h
|
LD r4, r2, 8a, 8h
|
||||||
|
@ -29,6 +22,6 @@ pass:
|
||||||
LD r1, r10, 0a, 8h
|
LD r1, r10, 0a, 8h
|
||||||
ADD64 r1, r1, r9
|
ADD64 r1, r1, r9
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 294
|
code size: 231
|
||||||
ret: 8
|
ret: 8
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -2,8 +2,8 @@ cond:
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -8d
|
||||||
ST r31, r254, 8a, 8h
|
ST r31, r254, 0a, 8h
|
||||||
JAL r31, r0, :cond
|
JAL r31, r0, :cond
|
||||||
LI64 r5, 0d
|
LI64 r5, 0d
|
||||||
CP r7, r5
|
CP r7, r5
|
||||||
|
@ -12,10 +12,9 @@ main:
|
||||||
CP r1, r5
|
CP r1, r5
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r1, 2d
|
0: LI64 r1, 2d
|
||||||
1: ST r1, r254, 0a, 8h
|
1: LD r31, r254, 0a, 8h
|
||||||
LD r31, r254, 8a, 8h
|
ADDI64 r254, r254, 8d
|
||||||
ADDI64 r254, r254, 16d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 147
|
code size: 134
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -31d
|
ADDI64 r254, r254, -16d
|
||||||
LI64 r1, 10d
|
LI64 r1, 10d
|
||||||
ADDI64 r4, r254, 15d
|
ADDI64 r4, r254, 0d
|
||||||
ST r1, r254, 15a, 8h
|
ST r1, r254, 0a, 8h
|
||||||
LI64 r7, 20d
|
LI64 r7, 20d
|
||||||
ST r7, r254, 23a, 8h
|
ST r7, r254, 8a, 8h
|
||||||
LI64 r6, 6d
|
LI64 r6, 6d
|
||||||
LI64 r5, 5d
|
LI64 r5, 5d
|
||||||
LI64 r2, 1d
|
LI64 r2, 1d
|
||||||
LD r3, r4, 0a, 16h
|
LD r3, r4, 0a, 16h
|
||||||
ECA
|
ECA
|
||||||
LRA r5, r0, :arbitrary text
|
|
||||||
|
|
||||||
ADDI64 r7, r254, 0d
|
|
||||||
BMC r5, r7, 15h
|
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
ADDI64 r254, r254, 31d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
ev: Ecall
|
ev: Ecall
|
||||||
code size: 190
|
code size: 152
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -22,22 +22,19 @@ scalar_values:
|
||||||
LI64 r1, 0d
|
LI64 r1, 0d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
structs:
|
structs:
|
||||||
ADDI64 r254, r254, -48d
|
ADDI64 r254, r254, -32d
|
||||||
LI64 r3, 5d
|
LI64 r2, 5d
|
||||||
ST r3, r254, 0a, 8h
|
ST r2, r254, 16a, 8h
|
||||||
ST r3, r254, 8a, 8h
|
ST r2, r254, 24a, 8h
|
||||||
LD r7, r254, 0a, 8h
|
LD r6, r254, 16a, 8h
|
||||||
ADDI64 r9, r7, 15d
|
ADDI64 r8, r6, 15d
|
||||||
ST r9, r254, 24a, 8h
|
ST r8, r254, 0a, 8h
|
||||||
LI64 r8, 20d
|
LI64 r7, 20d
|
||||||
ST r8, r254, 32a, 8h
|
ST r7, r254, 8a, 8h
|
||||||
LI64 r9, 0d
|
LD r1, r254, 0a, 8h
|
||||||
LD r3, r254, 24a, 8h
|
SUB64 r1, r1, r7
|
||||||
ST r8, r254, 16a, 8h
|
ADDI64 r254, r254, 32d
|
||||||
ST r9, r254, 40a, 8h
|
|
||||||
SUB64 r1, r3, r8
|
|
||||||
ADDI64 r254, r254, 48d
|
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 346
|
code size: 310
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -2,31 +2,31 @@ main:
|
||||||
ADDI64 r254, r254, -152d
|
ADDI64 r254, r254, -152d
|
||||||
LI8 r1, 0b
|
LI8 r1, 0b
|
||||||
LI8 r3, 1b
|
LI8 r3, 1b
|
||||||
ST r1, r254, 148a, 1h
|
ST r1, r254, 132a, 1h
|
||||||
ST r3, r254, 144a, 1h
|
ST r3, r254, 128a, 1h
|
||||||
ST r1, r254, 149a, 1h
|
ST r1, r254, 133a, 1h
|
||||||
ST r3, r254, 145a, 1h
|
ST r3, r254, 129a, 1h
|
||||||
ST r1, r254, 150a, 1h
|
ST r1, r254, 134a, 1h
|
||||||
ST r3, r254, 146a, 1h
|
ST r3, r254, 130a, 1h
|
||||||
ST r1, r254, 151a, 1h
|
ST r1, r254, 135a, 1h
|
||||||
ST r3, r254, 147a, 1h
|
ST r3, r254, 131a, 1h
|
||||||
LD r1, r254, 148a, 1h
|
LD r1, r254, 132a, 1h
|
||||||
LD r4, r254, 144a, 1h
|
LD r4, r254, 128a, 1h
|
||||||
ADD8 r5, r4, r1
|
ADD8 r5, r4, r1
|
||||||
LD r8, r254, 145a, 1h
|
LD r8, r254, 129a, 1h
|
||||||
LD r9, r254, 149a, 1h
|
LD r9, r254, 133a, 1h
|
||||||
ST r5, r254, 148a, 1h
|
ST r5, r254, 132a, 1h
|
||||||
ADD8 r12, r9, r8
|
ADD8 r12, r9, r8
|
||||||
LD r4, r254, 146a, 1h
|
LD r4, r254, 130a, 1h
|
||||||
LD r5, r254, 150a, 1h
|
LD r5, r254, 134a, 1h
|
||||||
ST r12, r254, 149a, 1h
|
ST r12, r254, 133a, 1h
|
||||||
ADD8 r7, r5, r4
|
ADD8 r7, r5, r4
|
||||||
ST r7, r254, 150a, 1h
|
ST r7, r254, 134a, 1h
|
||||||
ST r3, r254, 151a, 1h
|
ST r3, r254, 135a, 1h
|
||||||
LD r12, r254, 149a, 1h
|
LD r12, r254, 133a, 1h
|
||||||
LD r1, r254, 150a, 1h
|
LD r1, r254, 134a, 1h
|
||||||
ADD8 r4, r1, r12
|
ADD8 r4, r1, r12
|
||||||
LD r5, r254, 148a, 1h
|
LD r5, r254, 132a, 1h
|
||||||
ADD8 r7, r5, r4
|
ADD8 r7, r5, r4
|
||||||
LI8 r9, 4b
|
LI8 r9, 4b
|
||||||
ADD8 r1, r7, r3
|
ADD8 r1, r7, r3
|
||||||
|
@ -36,61 +36,61 @@ main:
|
||||||
LI64 r1, 1008d
|
LI64 r1, 1008d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r6, 1d
|
0: LI64 r6, 1d
|
||||||
ADDI64 r5, r254, 112d
|
ADDI64 r5, r254, 80d
|
||||||
ST r6, r254, 112a, 8h
|
ST r6, r254, 80a, 8h
|
||||||
LI64 r9, 2d
|
LI64 r9, 2d
|
||||||
ST r9, r254, 120a, 8h
|
ST r9, r254, 88a, 8h
|
||||||
LI64 r2, 3d
|
LI64 r2, 3d
|
||||||
ADDI64 r1, r254, 96d
|
ADDI64 r1, r254, 64d
|
||||||
ST r2, r254, 64a, 8h
|
ST r2, r254, 48a, 8h
|
||||||
LI64 r6, 4d
|
LI64 r6, 4d
|
||||||
LI64 r2, 0d
|
LI64 r2, 0d
|
||||||
BMC r5, r1, 16h
|
BMC r5, r1, 16h
|
||||||
ST r6, r254, 72a, 8h
|
ST r6, r254, 56a, 8h
|
||||||
ST r2, r254, 80a, 8h
|
ST r2, r254, 0a, 8h
|
||||||
LD r11, r254, 96a, 8h
|
LD r11, r254, 64a, 8h
|
||||||
LD r1, r254, 64a, 8h
|
LD r1, r254, 48a, 8h
|
||||||
ST r2, r254, 88a, 8h
|
ST r2, r254, 8a, 8h
|
||||||
ADD64 r4, r1, r11
|
ADD64 r4, r1, r11
|
||||||
LD r7, r254, 104a, 8h
|
LD r7, r254, 72a, 8h
|
||||||
LD r2, r254, 80a, 8h
|
LD r2, r254, 0a, 8h
|
||||||
ST r4, r254, 32a, 8h
|
ST r4, r254, 96a, 8h
|
||||||
ADD64 r12, r7, r6
|
ADD64 r12, r7, r6
|
||||||
SUB64 r3, r2, r1
|
SUB64 r3, r2, r1
|
||||||
ADDI64 r8, r254, 0d
|
ADDI64 r8, r254, 16d
|
||||||
ST r12, r254, 40a, 8h
|
ST r12, r254, 104a, 8h
|
||||||
SUB64 r2, r1, r11
|
SUB64 r2, r1, r11
|
||||||
ST r3, r254, 0a, 8h
|
ST r3, r254, 16a, 8h
|
||||||
LI64 r9, -4d
|
LI64 r9, -4d
|
||||||
ST r2, r254, 48a, 8h
|
ST r2, r254, 112a, 8h
|
||||||
SUB64 r7, r6, r7
|
SUB64 r7, r6, r7
|
||||||
ST r9, r254, 8a, 8h
|
ST r9, r254, 24a, 8h
|
||||||
ADDI64 r8, r8, 16d
|
ADDI64 r8, r8, 16d
|
||||||
ST r7, r254, 56a, 8h
|
ST r7, r254, 120a, 8h
|
||||||
BMC r5, r8, 16h
|
BMC r5, r8, 16h
|
||||||
LD r6, r254, 32a, 8h
|
LD r6, r254, 96a, 8h
|
||||||
LD r8, r254, 0a, 8h
|
|
||||||
ADD64 r9, r8, r6
|
|
||||||
LD r11, r254, 8a, 8h
|
|
||||||
LD r1, r254, 40a, 8h
|
|
||||||
ST r9, r254, 0a, 8h
|
|
||||||
ADD64 r4, r1, r11
|
|
||||||
LD r8, r254, 16a, 8h
|
LD r8, r254, 16a, 8h
|
||||||
LD r9, r254, 48a, 8h
|
ADD64 r9, r8, r6
|
||||||
ST r4, r254, 8a, 8h
|
LD r11, r254, 24a, 8h
|
||||||
|
LD r1, r254, 104a, 8h
|
||||||
|
ST r9, r254, 16a, 8h
|
||||||
|
ADD64 r4, r1, r11
|
||||||
|
LD r8, r254, 32a, 8h
|
||||||
|
LD r9, r254, 112a, 8h
|
||||||
|
ST r4, r254, 24a, 8h
|
||||||
ADD64 r12, r9, r8
|
ADD64 r12, r9, r8
|
||||||
LD r2, r254, 24a, 8h
|
LD r2, r254, 40a, 8h
|
||||||
ST r12, r254, 16a, 8h
|
ST r12, r254, 32a, 8h
|
||||||
ADD64 r12, r2, r7
|
ADD64 r12, r2, r7
|
||||||
ST r12, r254, 24a, 8h
|
ST r12, r254, 40a, 8h
|
||||||
LD r7, r254, 0a, 8h
|
LD r7, r254, 16a, 8h
|
||||||
LD r9, r254, 16a, 8h
|
LD r9, r254, 32a, 8h
|
||||||
ADD64 r11, r9, r7
|
ADD64 r11, r9, r7
|
||||||
LD r1, r254, 8a, 8h
|
LD r1, r254, 24a, 8h
|
||||||
ST r11, r254, 128a, 8h
|
ST r11, r254, 136a, 8h
|
||||||
ADD64 r6, r1, r12
|
ADD64 r6, r1, r12
|
||||||
ST r6, r254, 136a, 8h
|
ST r6, r254, 144a, 8h
|
||||||
LD r7, r254, 128a, 8h
|
LD r7, r254, 136a, 8h
|
||||||
ADD64 r1, r7, r6
|
ADD64 r1, r7, r6
|
||||||
1: ADDI64 r254, r254, 152d
|
1: ADDI64 r254, r254, 152d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
|
|
|
@ -1,25 +1,23 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -80d
|
ADDI64 r254, r254, -56d
|
||||||
ST r31, r254, 48a, 32h
|
ST r31, r254, 32a, 24h
|
||||||
LI64 r2, 4d
|
LI64 r3, 4d
|
||||||
ADDI64 r32, r254, 32d
|
ADDI64 r2, r254, 16d
|
||||||
ST r2, r254, 32a, 8h
|
ST r3, r254, 16a, 8h
|
||||||
LI64 r33, 3d
|
LI64 r32, 3d
|
||||||
ST r33, r254, 40a, 8h
|
ST r32, r254, 24a, 8h
|
||||||
ADDI64 r34, r254, 0d
|
ADDI64 r33, r254, 0d
|
||||||
LD r3, r32, 0a, 16h
|
LD r3, r2, 0a, 16h
|
||||||
JAL r31, r0, :odher_pass
|
JAL r31, r0, :odher_pass
|
||||||
ST r1, r254, 0a, 16h
|
ST r1, r254, 0a, 16h
|
||||||
ADDI64 r11, r254, 16d
|
LD r2, r254, 8a, 8h
|
||||||
BMC r32, r11, 16h
|
JNE r2, r32, :0
|
||||||
LD r4, r254, 8a, 8h
|
CP r2, r33
|
||||||
JNE r4, r33, :0
|
|
||||||
CP r2, r34
|
|
||||||
JAL r31, r0, :pass
|
JAL r31, r0, :pass
|
||||||
JMP :1
|
JMP :1
|
||||||
0: LI64 r1, 0d
|
0: LI64 r1, 0d
|
||||||
1: LD r31, r254, 48a, 32h
|
1: LD r31, r254, 32a, 24h
|
||||||
ADDI64 r254, r254, 80d
|
ADDI64 r254, r254, 56d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
odher_pass:
|
odher_pass:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -16d
|
||||||
|
@ -31,6 +29,6 @@ odher_pass:
|
||||||
pass:
|
pass:
|
||||||
LD r1, r2, 0a, 8h
|
LD r1, r2, 0a, 8h
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 321
|
code size: 305
|
||||||
ret: 4
|
ret: 4
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -14,32 +14,30 @@ main:
|
||||||
ADDI64 r254, r254, 24d
|
ADDI64 r254, r254, 24d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
maina:
|
maina:
|
||||||
ADDI64 r254, r254, -44d
|
ADDI64 r254, r254, -36d
|
||||||
ST r31, r254, 36a, 8h
|
ST r31, r254, 28a, 8h
|
||||||
ADDI64 r6, r254, 32d
|
ADDI64 r5, r254, 24d
|
||||||
JAL r31, r0, :small_struct
|
JAL r31, r0, :small_struct
|
||||||
ST r1, r254, 32a, 4h
|
ST r1, r254, 24a, 4h
|
||||||
LI8 r11, 0b
|
LI8 r11, 0b
|
||||||
ADDI64 r10, r254, 24d
|
ADDI64 r10, r254, 0d
|
||||||
ST r11, r254, 24a, 1h
|
ST r11, r254, 0a, 1h
|
||||||
ST r11, r254, 25a, 1h
|
ST r11, r254, 1a, 1h
|
||||||
ST r11, r254, 26a, 1h
|
ST r11, r254, 2a, 1h
|
||||||
LI8 r4, 3b
|
LI8 r4, 3b
|
||||||
ST r4, r254, 27a, 1h
|
ST r4, r254, 3a, 1h
|
||||||
LI8 r7, 1b
|
LI8 r7, 1b
|
||||||
ST r7, r254, 28a, 1h
|
ST r7, r254, 4a, 1h
|
||||||
ST r11, r254, 29a, 1h
|
ST r11, r254, 5a, 1h
|
||||||
ST r11, r254, 30a, 1h
|
ST r11, r254, 6a, 1h
|
||||||
ST r11, r254, 31a, 1h
|
ST r11, r254, 7a, 1h
|
||||||
ADDI64 r2, r254, 0d
|
ADDI64 r1, r254, 8d
|
||||||
BMC r10, r2, 8h
|
BMC r10, r1, 8h
|
||||||
ADDI64 r5, r2, 8d
|
ADDI64 r4, r1, 8d
|
||||||
ADDI64 r4, r254, 16d
|
|
||||||
BMC r10, r5, 8h
|
|
||||||
BMC r10, r4, 8h
|
BMC r10, r4, 8h
|
||||||
LD r1, r2, 0a, 16h
|
LD r1, r1, 0a, 16h
|
||||||
LD r31, r254, 36a, 8h
|
LD r31, r254, 28a, 8h
|
||||||
ADDI64 r254, r254, 44d
|
ADDI64 r254, r254, 36d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
small_struct:
|
small_struct:
|
||||||
ADDI64 r254, r254, -4d
|
ADDI64 r254, r254, -4d
|
||||||
|
@ -50,6 +48,6 @@ small_struct:
|
||||||
LD r1, r3, 0a, 4h
|
LD r1, r3, 0a, 4h
|
||||||
ADDI64 r254, r254, 4d
|
ADDI64 r254, r254, 4d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 514
|
code size: 498
|
||||||
ret: 2
|
ret: 2
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
Loading…
Reference in a new issue