fixing the matrix
This commit is contained in:
parent
ea628c1278
commit
4bfb5f192e
223
lang/src/son.rs
223
lang/src/son.rs
|
@ -198,14 +198,18 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut deepest = VOID;
|
let mut deepest = VOID;
|
||||||
for i in 1..self[node].inputs.len() {
|
for i in 0..self[node].inputs.len() {
|
||||||
let inp = self[node].inputs[i];
|
let inp = self[node].inputs[i];
|
||||||
if self.idepth(inp) > self.idepth(deepest) {
|
if self.idepth(inp) > self.idepth(deepest) {
|
||||||
deepest = self.idom(inp);
|
if matches!(self[inp].kind, Kind::Call { .. }) {
|
||||||
|
deepest = inp;
|
||||||
|
} else {
|
||||||
|
deepest = self.idom(inp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if deepest == VOID {
|
if deepest == self[node].inputs[0] {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,6 +330,14 @@ impl Nodes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self[node].kind == Kind::Load {
|
||||||
|
min = self.find_antideps(node, min);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self[node].kind == Kind::Stre {
|
||||||
|
self[node].antidep = 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);
|
||||||
}
|
}
|
||||||
|
@ -340,6 +352,67 @@ impl Nodes {
|
||||||
self[min].outputs.push(node);
|
self[min].outputs.push(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_antideps(&mut self, load: Nid, mut min: Nid) -> Nid {
|
||||||
|
debug_assert!(self[load].kind == Kind::Load);
|
||||||
|
|
||||||
|
let (aclass, _) = self.aclass_index(self[load].inputs[1]);
|
||||||
|
|
||||||
|
let mut cursor = min;
|
||||||
|
while cursor != self[load].inputs[0] {
|
||||||
|
self[cursor].antidep = load;
|
||||||
|
if self[cursor].clobbers.contains(&aclass) {
|
||||||
|
min = self[cursor].inputs[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cursor = self.idom(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self[load].inputs[2] == MEM {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
for out in self[self[load].inputs[2]].outputs.clone() {
|
||||||
|
match self[out].kind {
|
||||||
|
Kind::Stre => {
|
||||||
|
let mut cursor = self[out].inputs[0];
|
||||||
|
while cursor != self[out].antidep {
|
||||||
|
if self[cursor].antidep == load {
|
||||||
|
min = self.common_dom(min, cursor);
|
||||||
|
if min == cursor {
|
||||||
|
self.bind(load, out);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cursor = self.idom(cursor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Kind::Phi => {
|
||||||
|
let n = self[out].inputs[1..]
|
||||||
|
.iter()
|
||||||
|
.position(|&n| n == self[load].inputs[2])
|
||||||
|
.unwrap();
|
||||||
|
let mut cursor = self[self[out].inputs[0]].inputs[n];
|
||||||
|
while cursor != self[out].antidep {
|
||||||
|
if self[cursor].antidep == load {
|
||||||
|
min = self.common_dom(min, cursor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cursor = self.idom(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
min
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind(&mut self, from: Nid, to: Nid) {
|
||||||
|
self[from].outputs.push(to);
|
||||||
|
self[to].inputs.push(from);
|
||||||
|
}
|
||||||
|
|
||||||
fn use_block(&mut self, target: Nid, from: Nid) -> Nid {
|
fn use_block(&mut self, target: Nid, from: Nid) -> Nid {
|
||||||
if self[from].kind != Kind::Phi {
|
if self[from].kind != Kind::Phi {
|
||||||
return self.idom(from);
|
return self.idom(from);
|
||||||
|
@ -405,7 +478,6 @@ impl Nodes {
|
||||||
to_class
|
to_class
|
||||||
.last_store
|
.last_store
|
||||||
.set_remove(self.new_node(ty::Id::VOID, Kind::Phi, inps), self);
|
.set_remove(self.new_node(ty::Id::VOID, Kind::Phi, inps), self);
|
||||||
to_class.loads.drain(..).for_each(|d| _ = d.remove(self));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -439,12 +511,18 @@ impl Nodes {
|
||||||
if node.ty != ty::Id::VOID {
|
if node.ty != ty::Id::VOID {
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
" node{i}[label=\"{i} {} {}\" color={color}]",
|
" node{i}[label=\"{i} {} {} {} {}\" color={color}]",
|
||||||
node.kind,
|
node.kind,
|
||||||
ty::Display::new(tys, files, node.ty)
|
ty::Display::new(tys, files, node.ty),
|
||||||
|
node.aclass,
|
||||||
|
node.mem,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
writeln!(out, " node{i}[label=\"{i} {}\" color={color}]", node.kind,)?;
|
writeln!(
|
||||||
|
out,
|
||||||
|
" node{i}[label=\"{i} {} {} {}\" color={color}]",
|
||||||
|
node.kind, node.aclass, node.mem,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j, &o) in node.outputs.iter().enumerate() {
|
for (j, &o) in node.outputs.iter().enumerate() {
|
||||||
|
@ -675,14 +753,8 @@ impl Nodes {
|
||||||
stack.iter().skip(prev_len).for_each(|&n| self.lock(n));
|
stack.iter().skip(prev_len).for_each(|&n| self.lock(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn aclass_index(&self, mut region: Nid) -> (usize, Nid) {
|
pub fn aclass_index(&self, region: Nid) -> (usize, Nid) {
|
||||||
loop {
|
(self[region].aclass, self[region].mem)
|
||||||
region = match self[region].kind {
|
|
||||||
Kind::BinOp { op: TokenKind::Add | TokenKind::Sub } => self[region].inputs[1],
|
|
||||||
Kind::Phi if self[region].inputs[2] == 0 => self[region].inputs[1],
|
|
||||||
_ => break (self[region].aclass, region),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peephole(&mut self, target: Nid) -> Option<Nid> {
|
fn peephole(&mut self, target: Nid) -> Option<Nid> {
|
||||||
|
@ -959,7 +1031,7 @@ impl Nodes {
|
||||||
let stre = self[store].inputs[3];
|
let stre = self[store].inputs[3];
|
||||||
if stre != MEM {
|
if stre != MEM {
|
||||||
self[a].inputs.push(stre);
|
self[a].inputs.push(stre);
|
||||||
self[a].inputs.swap(len - 2, len - 1);
|
self[a].inputs.swap(len - 1, len);
|
||||||
self[stre].outputs.push(a);
|
self[stre].outputs.push(a);
|
||||||
}
|
}
|
||||||
return Some(self[store].inputs[2]);
|
return Some(self[store].inputs[2]);
|
||||||
|
@ -1106,6 +1178,10 @@ impl Nodes {
|
||||||
if self[store].kind == Kind::Stre
|
if self[store].kind == Kind::Stre
|
||||||
&& self[store].inputs[2] == region
|
&& self[store].inputs[2] == region
|
||||||
&& self[store].ty == self[target].ty
|
&& self[store].ty == self[target].ty
|
||||||
|
&& self[store]
|
||||||
|
.outputs
|
||||||
|
.iter()
|
||||||
|
.all(|&n| !matches!(self[n].kind, Kind::Call { .. }))
|
||||||
{
|
{
|
||||||
return Some(self[store].inputs[1]);
|
return Some(self[store].inputs[1]);
|
||||||
}
|
}
|
||||||
|
@ -1116,6 +1192,10 @@ impl Nodes {
|
||||||
while cursor != MEM
|
while cursor != MEM
|
||||||
&& self[cursor].kind == Kind::Stre
|
&& self[cursor].kind == Kind::Stre
|
||||||
&& self[cursor].inputs[1] != VOID
|
&& self[cursor].inputs[1] != VOID
|
||||||
|
&& self[cursor]
|
||||||
|
.outputs
|
||||||
|
.iter()
|
||||||
|
.all(|&n| !matches!(self[n].kind, Kind::Call { .. }))
|
||||||
{
|
{
|
||||||
if self[cursor].inputs[2] == region && self[cursor].ty == self[target].ty {
|
if self[cursor].inputs[2] == region && self[cursor].ty == self[target].ty {
|
||||||
return Some(self[cursor].inputs[1]);
|
return Some(self[cursor].inputs[1]);
|
||||||
|
@ -1394,8 +1474,11 @@ impl Nodes {
|
||||||
self.load_loop_var(index, lvar, loops);
|
self.load_loop_var(index, lvar, loops);
|
||||||
|
|
||||||
if !self[lvar.value()].is_lazy_phi(node) {
|
if !self[lvar.value()].is_lazy_phi(node) {
|
||||||
let inps = [node, lvar.value(), VOID];
|
let lvalue = lvar.value();
|
||||||
|
let inps = [node, lvalue, VOID];
|
||||||
lvar.set_value(self.new_node_nop(lvar.ty, Kind::Phi, inps), self);
|
lvar.set_value(self.new_node_nop(lvar.ty, Kind::Phi, inps), self);
|
||||||
|
self[lvar.value()].aclass = self[lvalue].aclass;
|
||||||
|
self[lvar.value()].mem = self[lvalue].mem;
|
||||||
}
|
}
|
||||||
var.set_value(lvar.value(), self);
|
var.set_value(lvar.value(), self);
|
||||||
}
|
}
|
||||||
|
@ -1578,6 +1661,7 @@ pub struct Node {
|
||||||
inputs: Vc,
|
inputs: Vc,
|
||||||
outputs: Vc,
|
outputs: Vc,
|
||||||
peep_triggers: Vc,
|
peep_triggers: Vc,
|
||||||
|
clobbers: Vec<usize>,
|
||||||
ty: ty::Id,
|
ty: ty::Id,
|
||||||
offset: Offset,
|
offset: Offset,
|
||||||
ralloc_backref: RallocBRef,
|
ralloc_backref: RallocBRef,
|
||||||
|
@ -1585,6 +1669,8 @@ pub struct Node {
|
||||||
lock_rc: LockRc,
|
lock_rc: LockRc,
|
||||||
loop_depth: LoopDepth,
|
loop_depth: LoopDepth,
|
||||||
aclass: usize,
|
aclass: usize,
|
||||||
|
mem: Nid,
|
||||||
|
antidep: Nid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
|
@ -1602,7 +1688,7 @@ 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)
|
|| matches!(self.kind, Kind::Arg | Kind::Stck | Kind::Stre)
|
||||||
|| self.kind.is_cfg()
|
|| self.kind.is_cfg()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1759,24 +1845,21 @@ impl Variable {
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct AClass {
|
pub struct AClass {
|
||||||
last_store: StrongRef,
|
last_store: StrongRef,
|
||||||
loads: Vec<StrongRef>,
|
clobber: StrongRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AClass {
|
impl AClass {
|
||||||
fn dup(&self, nodes: &mut Nodes) -> Self {
|
fn dup(&self, nodes: &mut Nodes) -> Self {
|
||||||
Self {
|
Self { last_store: self.last_store.dup(nodes), clobber: self.clobber.dup(nodes) }
|
||||||
last_store: self.last_store.dup(nodes),
|
|
||||||
loads: self.loads.iter().map(|v| v.dup(nodes)).collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(mut self, nodes: &mut Nodes) {
|
fn remove(self, nodes: &mut Nodes) {
|
||||||
self.last_store.remove(nodes);
|
self.last_store.remove(nodes);
|
||||||
self.loads.drain(..).for_each(|n| _ = n.remove(nodes));
|
self.clobber.remove(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(nodes: &mut Nodes) -> Self {
|
fn new(nodes: &mut Nodes) -> Self {
|
||||||
Self { last_store: StrongRef::new(MEM, nodes), loads: Default::default() }
|
Self { last_store: StrongRef::new(MEM, nodes), clobber: StrongRef::new(VOID, nodes) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2111,6 +2194,7 @@ impl<'a> Codegen<'a> {
|
||||||
fn new_stack(&mut self, ty: ty::Id) -> Nid {
|
fn new_stack(&mut self, ty: ty::Id) -> Nid {
|
||||||
let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]);
|
let stck = self.ci.nodes.new_node_nop(ty, Kind::Stck, [VOID, MEM]);
|
||||||
self.ci.nodes[stck].aclass = self.ci.scope.aclasses.len();
|
self.ci.nodes[stck].aclass = self.ci.scope.aclasses.len();
|
||||||
|
self.ci.nodes[stck].mem = stck;
|
||||||
self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes));
|
self.ci.scope.aclasses.push(AClass::new(&mut self.ci.nodes));
|
||||||
stck
|
stck
|
||||||
}
|
}
|
||||||
|
@ -2129,7 +2213,6 @@ impl<'a> Codegen<'a> {
|
||||||
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];
|
||||||
let loads = mem::take(&mut aclass.loads);
|
|
||||||
self.ci.nodes.load_loop_aclass(value_index, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(value_index, aclass, &mut self.ci.loops);
|
||||||
let last_store = aclass.last_store.get();
|
let last_store = aclass.last_store.get();
|
||||||
let mut cursor = last_store;
|
let mut cursor = last_store;
|
||||||
|
@ -2146,23 +2229,13 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes);
|
self.ci.scope.aclasses[0].last_store.set(last_store, &mut self.ci.nodes);
|
||||||
}
|
}
|
||||||
self.ci.scope.aclasses[0].loads.extend(loads);
|
|
||||||
self.ci.nodes[value_region].aclass = 0;
|
self.ci.nodes[value_region].aclass = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let (index, _) = self.ci.nodes.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 vc = Vc::from([aclass.clobber.get(), value, region, aclass.last_store.get()]);
|
||||||
for load in aclass.loads.drain(..) {
|
|
||||||
if load.get() == value {
|
|
||||||
load.soft_remove(&mut self.ci.nodes);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(load) = load.remove(&mut self.ci.nodes) {
|
|
||||||
vc.push(load);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mem::take(&mut aclass.last_store).soft_remove(&mut self.ci.nodes);
|
mem::take(&mut aclass.last_store).soft_remove(&mut self.ci.nodes);
|
||||||
let store = self.ci.nodes.new_node(ty, Kind::Stre, vc);
|
let store = self.ci.nodes.new_node(ty, Kind::Stre, vc);
|
||||||
aclass.last_store = StrongRef::new(store, &mut self.ci.nodes);
|
aclass.last_store = StrongRef::new(store, &mut self.ci.nodes);
|
||||||
|
@ -2186,10 +2259,8 @@ impl<'a> Codegen<'a> {
|
||||||
let (index, _) = self.ci.nodes.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 = [aclass.clobber.get(), region, aclass.last_store.get()];
|
||||||
let load = self.ci.nodes.new_node(ty, Kind::Load, vc);
|
self.ci.nodes.new_node(ty, Kind::Load, vc)
|
||||||
aclass.loads.push(StrongRef::new(load, &mut self.ci.nodes));
|
|
||||||
load
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(&mut self, entry: FileId) {
|
pub fn generate(&mut self, entry: FileId) {
|
||||||
|
@ -2545,9 +2616,13 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes.unlock(lhs.id);
|
self.ci.nodes.unlock(lhs.id);
|
||||||
let mut rhs = rhs?;
|
let mut rhs = rhs?;
|
||||||
self.strip_var(&mut rhs);
|
self.strip_var(&mut rhs);
|
||||||
let ty = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
let (ty, aclass, mem) = self.binop_ty(pos, &mut lhs, &mut rhs, op);
|
||||||
let inps = [VOID, lhs.id, rhs.id];
|
let inps = [VOID, lhs.id, rhs.id];
|
||||||
Some(self.ci.nodes.new_node_lit(ty.bin_ret(op), Kind::BinOp { op }, inps))
|
let bop =
|
||||||
|
self.ci.nodes.new_node_lit(ty.bin_ret(op), Kind::BinOp { op }, inps);
|
||||||
|
self.ci.nodes[bop.id].aclass = aclass;
|
||||||
|
self.ci.nodes[bop.id].mem = mem;
|
||||||
|
Some(bop)
|
||||||
}
|
}
|
||||||
ty::Kind::Struct(s) if op.is_homogenous() => {
|
ty::Kind::Struct(s) if op.is_homogenous() => {
|
||||||
self.ci.nodes.lock(lhs.id);
|
self.ci.nodes.lock(lhs.id);
|
||||||
|
@ -2597,9 +2672,13 @@ impl<'a> Codegen<'a> {
|
||||||
let inps = [VOID, idx.id, size];
|
let inps = [VOID, idx.id, size];
|
||||||
let offset =
|
let offset =
|
||||||
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps);
|
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Mul }, inps);
|
||||||
|
let (aclass, mem) = self.ci.nodes.aclass_index(bs.id);
|
||||||
let inps = [VOID, bs.id, offset];
|
let inps = [VOID, bs.id, offset];
|
||||||
let ptr =
|
let ptr =
|
||||||
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
||||||
|
self.ci.nodes[ptr].aclass = aclass;
|
||||||
|
self.ci.nodes[ptr].mem = mem;
|
||||||
|
|
||||||
Some(Value::ptr(ptr).ty(elem))
|
Some(Value::ptr(ptr).ty(elem))
|
||||||
}
|
}
|
||||||
Expr::Embed { id, .. } => {
|
Expr::Embed { id, .. } => {
|
||||||
|
@ -2808,7 +2887,7 @@ impl<'a> Codegen<'a> {
|
||||||
&mut self.ci.nodes,
|
&mut self.ci.nodes,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.add_clobber_stores(&clobbered_aliases);
|
self.add_clobber_stores(clobbered_aliases);
|
||||||
|
|
||||||
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty)))
|
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty)))
|
||||||
}
|
}
|
||||||
|
@ -2884,7 +2963,7 @@ impl<'a> Codegen<'a> {
|
||||||
&mut self.ci.nodes,
|
&mut self.ci.nodes,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.add_clobber_stores(&clobbered_aliases);
|
self.add_clobber_stores(clobbered_aliases);
|
||||||
|
|
||||||
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(sig.ret)))
|
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(sig.ret)))
|
||||||
}
|
}
|
||||||
|
@ -3458,10 +3537,10 @@ impl<'a> Codegen<'a> {
|
||||||
if let Some(base) = self.tys.base_of(value.ty) {
|
if let Some(base) = self.tys.base_of(value.ty) {
|
||||||
clobbered_aliases.push(self.ci.nodes.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(DEFAULT_ACLASS);
|
||||||
}
|
}
|
||||||
} else if value.ty.has_pointers(self.tys) {
|
} else if value.ty.has_pointers(self.tys) {
|
||||||
clobbered_aliases.push(0);
|
clobbered_aliases.push(DEFAULT_ACLASS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3470,31 +3549,14 @@ impl<'a> Codegen<'a> {
|
||||||
let aclass = &mut self.ci.scope.aclasses[clobbered];
|
let aclass = &mut self.ci.scope.aclasses[clobbered];
|
||||||
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
|
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
|
||||||
inps.push(aclass.last_store.get());
|
inps.push(aclass.last_store.get());
|
||||||
aclass.loads.retain_mut(|load| {
|
|
||||||
if inps.contains(&load.get()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(load) = mem::take(load).remove(&mut self.ci.nodes) {
|
|
||||||
inps.push(load);
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_clobber_stores(&mut self, clobbered_aliases: &[usize]) {
|
fn add_clobber_stores(&mut self, clobbered_aliases: Vec<usize>) {
|
||||||
for &clobbered in clobbered_aliases.iter() {
|
for &clobbered in clobbered_aliases.iter() {
|
||||||
if clobbered == DEFAULT_ACLASS {
|
self.ci.scope.aclasses[clobbered].clobber.set(self.ci.ctrl.get(), &mut self.ci.nodes);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let aclass = self.ci.scope.aclasses[clobbered].last_store.get();
|
|
||||||
if aclass == MEM {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
self.store_mem(self.ci.nodes[aclass].inputs[2], ty::Id::VOID, VOID);
|
|
||||||
}
|
}
|
||||||
|
self.ci.nodes[self.ci.ctrl.get()].clobbers = clobbered_aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn struct_op(
|
fn struct_op(
|
||||||
|
@ -3665,8 +3727,12 @@ impl<'a> Codegen<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let off = self.ci.nodes.new_node_nop(ty::Id::INT, Kind::CInt { value: off as i64 }, [VOID]);
|
let off = self.ci.nodes.new_node_nop(ty::Id::INT, Kind::CInt { value: off as i64 }, [VOID]);
|
||||||
|
let (aclass, mem) = self.ci.nodes.aclass_index(val);
|
||||||
let inps = [VOID, val, off];
|
let inps = [VOID, val, off];
|
||||||
self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps)
|
let seted = self.ci.nodes.new_node(ty::Id::INT, Kind::BinOp { op: TokenKind::Add }, inps);
|
||||||
|
self.ci.nodes[seted].aclass = aclass;
|
||||||
|
self.ci.nodes[seted].mem = mem;
|
||||||
|
seted
|
||||||
}
|
}
|
||||||
|
|
||||||
fn strip_var(&mut self, n: &mut Value) {
|
fn strip_var(&mut self, n: &mut Value) {
|
||||||
|
@ -3822,17 +3888,23 @@ impl<'a> Codegen<'a> {
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn binop_ty(&mut self, pos: Pos, lhs: &mut Value, rhs: &mut Value, op: TokenKind) -> ty::Id {
|
fn binop_ty(
|
||||||
|
&mut self,
|
||||||
|
pos: Pos,
|
||||||
|
lhs: &mut Value,
|
||||||
|
rhs: &mut Value,
|
||||||
|
op: TokenKind,
|
||||||
|
) -> (ty::Id, usize, Nid) {
|
||||||
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty) {
|
if let Some(upcasted) = lhs.ty.try_upcast(rhs.ty) {
|
||||||
let to_correct = if lhs.ty != upcasted {
|
let to_correct = if lhs.ty != upcasted {
|
||||||
Some(lhs)
|
Some((lhs, rhs))
|
||||||
} else if rhs.ty != upcasted {
|
} else if rhs.ty != upcasted {
|
||||||
Some(rhs)
|
Some((rhs, lhs))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(oper) = to_correct {
|
if let Some((oper, other)) = to_correct {
|
||||||
if self.tys.size_of(upcasted) > self.tys.size_of(oper.ty) {
|
if self.tys.size_of(upcasted) > self.tys.size_of(oper.ty) {
|
||||||
self.extend(oper, upcasted);
|
self.extend(oper, upcasted);
|
||||||
}
|
}
|
||||||
|
@ -3846,15 +3918,16 @@ impl<'a> Codegen<'a> {
|
||||||
self.ci.nodes.new_node(upcasted, Kind::BinOp { op: TokenKind::Mul }, [
|
self.ci.nodes.new_node(upcasted, Kind::BinOp { op: TokenKind::Mul }, [
|
||||||
VOID, oper.id, cnst,
|
VOID, oper.id, cnst,
|
||||||
]);
|
]);
|
||||||
|
return (upcasted, self.ci.nodes[other.id].aclass, self.ci.nodes[other.id].mem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
upcasted
|
(upcasted, DEFAULT_ACLASS, VOID)
|
||||||
} else {
|
} else {
|
||||||
let ty = self.ty_display(lhs.ty);
|
let ty = self.ty_display(lhs.ty);
|
||||||
let expected = self.ty_display(rhs.ty);
|
let expected = self.ty_display(rhs.ty);
|
||||||
self.report(pos, fa!("'{ty} {op} {expected}' is not supported"));
|
self.report(pos, fa!("'{ty} {op} {expected}' is not supported"));
|
||||||
ty::Id::NEVER
|
(ty::Id::NEVER, DEFAULT_ACLASS, VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -408,12 +408,20 @@ impl ItemCtx {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(PLoc::WideReg(r, size)) = ret {
|
if let Some(PLoc::WideReg(r, size)) = ret {
|
||||||
|
debug_assert_eq!(
|
||||||
|
fuc.nodes[*node.inputs.last().unwrap()].kind,
|
||||||
|
Kind::Stck
|
||||||
|
);
|
||||||
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
|
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
|
||||||
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
|
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
|
||||||
}
|
}
|
||||||
if let Some(PLoc::Reg(r, size)) = ret
|
if let Some(PLoc::Reg(r, size)) = ret
|
||||||
&& node.ty.loc(tys) == Loc::Stack
|
&& node.ty.loc(tys) == Loc::Stack
|
||||||
{
|
{
|
||||||
|
debug_assert_eq!(
|
||||||
|
fuc.nodes[*node.inputs.last().unwrap()].kind,
|
||||||
|
Kind::Stck
|
||||||
|
);
|
||||||
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
|
let stck = fuc.nodes[*node.inputs.last().unwrap()].offset;
|
||||||
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
|
self.emit(instrs::st(r, reg::STACK_PTR, stck as _, size));
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,12 +87,12 @@ push:
|
||||||
LD r12, r38, 0a, 8h
|
LD r12, r38, 0a, 8h
|
||||||
ADD64 r11, r12, r8
|
ADD64 r11, r12, r8
|
||||||
CP r3, r39
|
CP r3, r39
|
||||||
9: JNE r11, r12, :5
|
9: LD r2, r38, 0a, 8h
|
||||||
LD r8, r38, 8a, 8h
|
LD r8, r38, 8a, 8h
|
||||||
|
JNE r11, r12, :5
|
||||||
JEQ r8, r1, :6
|
JEQ r8, r1, :6
|
||||||
CP r4, r37
|
CP r4, r37
|
||||||
MUL64 r3, r8, r4
|
MUL64 r3, r8, r4
|
||||||
LD r2, r38, 0a, 8h
|
|
||||||
JAL r31, r0, :free
|
JAL r31, r0, :free
|
||||||
CP r5, r39
|
CP r5, r39
|
||||||
JMP :7
|
JMP :7
|
||||||
|
|
|
@ -4,9 +4,9 @@ main:
|
||||||
LI64 r6, 128d
|
LI64 r6, 128d
|
||||||
LI64 r7, 0d
|
LI64 r7, 0d
|
||||||
ADDI64 r4, r254, 0d
|
ADDI64 r4, r254, 0d
|
||||||
2: JLTU r7, r6, :0
|
2: LD r12, r254, 42a, 1h
|
||||||
LD r1, r254, 42a, 1h
|
JLTU r7, r6, :0
|
||||||
ANDI r1, r1, 255d
|
ANDI r1, r12, 255d
|
||||||
JMP :1
|
JMP :1
|
||||||
0: ADDI64 r3, r7, 1d
|
0: ADDI64 r3, r7, 1d
|
||||||
ADD64 r7, r4, r7
|
ADD64 r7, r4, r7
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
main:
|
main:
|
||||||
ADDI64 r254, r254, -56d
|
ADDI64 r254, r254, -48d
|
||||||
ST r31, r254, 40a, 16h
|
ST r31, r254, 40a, 8h
|
||||||
LI64 r4, 4d
|
LI64 r4, 4d
|
||||||
ADDI64 r3, r254, 24d
|
ADDI64 r3, r254, 24d
|
||||||
ADDI64 r6, r254, 0d
|
ADDI64 r6, r254, 0d
|
||||||
ST r4, r254, 24a, 8h
|
ST r4, r254, 24a, 8h
|
||||||
LI64 r32, 1d
|
LI64 r5, 1d
|
||||||
ST r32, r254, 32a, 8h
|
ST r5, r254, 32a, 8h
|
||||||
ST r32, r254, 16a, 8h
|
ST r5, r254, 16a, 8h
|
||||||
BMC r3, r6, 16h
|
BMC r3, r6, 16h
|
||||||
JAL r31, r0, :opaque
|
JAL r31, r0, :opaque
|
||||||
ST r1, r254, 0a, 16h
|
ST r1, r254, 0a, 16h
|
||||||
LD r4, r254, 8a, 8h
|
LD r4, r254, 8a, 8h
|
||||||
ADD64 r7, r4, r32
|
LD r6, r254, 16a, 8h
|
||||||
LD r5, r254, 0a, 8h
|
ADD64 r8, r6, r4
|
||||||
SUB64 r1, r5, r7
|
LD r6, r254, 0a, 8h
|
||||||
LD r31, r254, 40a, 16h
|
SUB64 r1, r6, r8
|
||||||
ADDI64 r254, r254, 56d
|
LD r31, r254, 40a, 8h
|
||||||
|
ADDI64 r254, r254, 48d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
opaque:
|
opaque:
|
||||||
ADDI64 r254, r254, -16d
|
ADDI64 r254, r254, -16d
|
||||||
|
@ -28,6 +29,6 @@ opaque:
|
||||||
LD r1, r2, 0a, 16h
|
LD r1, r2, 0a, 16h
|
||||||
ADDI64 r254, r254, 16d
|
ADDI64 r254, r254, 16d
|
||||||
JALA r0, r31, 0a
|
JALA r0, r31, 0a
|
||||||
code size: 310
|
code size: 323
|
||||||
ret: 0
|
ret: 0
|
||||||
status: Ok(())
|
status: Ok(())
|
||||||
|
|
|
@ -8,8 +8,8 @@ main:
|
||||||
6: JNE r8, r7, :0
|
6: JNE r8, r7, :0
|
||||||
LI64 r7, 2d
|
LI64 r7, 2d
|
||||||
CP r8, r4
|
CP r8, r4
|
||||||
4: JNE r8, r6, :1
|
4: LD r1, r254, 0a, 8h
|
||||||
LD r1, r254, 0a, 8h
|
JNE r8, r6, :1
|
||||||
JMP :2
|
JMP :2
|
||||||
1: MUL64 r10, r8, r7
|
1: MUL64 r10, r8, r7
|
||||||
ADD64 r8, r8, r6
|
ADD64 r8, r8, r6
|
||||||
|
@ -19,14 +19,14 @@ main:
|
||||||
5: JNE r2, r7, :3
|
5: JNE r2, r7, :3
|
||||||
JMP :4
|
JMP :4
|
||||||
3: ADD64 r1, r2, r6
|
3: ADD64 r1, r2, r6
|
||||||
ADD64 r11, r10, r2
|
ADD64 r11, r9, r2
|
||||||
ADD64 r12, r9, r2
|
MULI64 r3, r11, 8d
|
||||||
MULI64 r2, r11, 8d
|
ADD64 r12, r10, r2
|
||||||
|
ADD64 r11, r5, r3
|
||||||
MULI64 r12, r12, 8d
|
MULI64 r12, r12, 8d
|
||||||
ADD64 r11, r5, r2
|
|
||||||
ADD64 r12, r5, r12
|
ADD64 r12, r5, r12
|
||||||
BMC r12, r11, 8h
|
|
||||||
BMC r11, r12, 8h
|
BMC r11, r12, 8h
|
||||||
|
BMC r12, r11, 8h
|
||||||
CP r2, r1
|
CP r2, r1
|
||||||
JMP :5
|
JMP :5
|
||||||
0: ADD64 r11, r8, r6
|
0: ADD64 r11, r8, r6
|
||||||
|
|
|
@ -8,9 +8,9 @@ main:
|
||||||
4: JLTU r9, r8, :0
|
4: JLTU r9, r8, :0
|
||||||
LI64 r4, 10d
|
LI64 r4, 10d
|
||||||
CP r7, r6
|
CP r7, r6
|
||||||
3: JLTU r7, r4, :1
|
3: LD r9, r254, 2048a, 1h
|
||||||
LD r10, r254, 2048a, 1h
|
JLTU r7, r4, :1
|
||||||
ANDI r1, r10, 255d
|
ANDI r1, r9, 255d
|
||||||
JMP :2
|
JMP :2
|
||||||
1: ADD64 r12, r7, r6
|
1: ADD64 r12, r7, r6
|
||||||
MULI64 r1, r7, 1024d
|
MULI64 r1, r7, 1024d
|
||||||
|
|
Loading…
Reference in a new issue