saving this to make sure

This commit is contained in:
Jakub Doka 2024-10-28 16:18:53 +01:00
parent 37db783699
commit bbd7e12af4
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
5 changed files with 292 additions and 146 deletions

View file

@ -9,7 +9,7 @@ use {
idfl::{self}, idfl::{self},
CtorField, Expr, FileId, Pos, CtorField, Expr, FileId, Pos,
}, },
task, reg, task,
ty::{self, Arg, ArrayLen, Loc, Tuple}, ty::{self, Arg, ArrayLen, Loc, Tuple},
vc::{BitSet, Vc}, vc::{BitSet, Vc},
FTask, Func, Global, Ident, Offset, OffsetIter, Reloc, Sig, StringRef, SymKey, TypeParser, FTask, Func, Global, Ident, Offset, OffsetIter, Reloc, Sig, StringRef, SymKey, TypeParser,
@ -375,7 +375,8 @@ impl Nodes {
to: &mut Scope, to: &mut Scope,
from: &mut Scope, from: &mut Scope,
) { ) {
for (i, (to_value, from_value)) in to.iter_mut().zip(from.iter_mut()).enumerate() { for (i, (to_value, from_value)) in to.vars.iter_mut().zip(from.vars.iter_mut()).enumerate()
{
debug_assert_eq!(to_value.ty, from_value.ty); debug_assert_eq!(to_value.ty, from_value.ty);
if to_value.value() != from_value.value() { if to_value.value() != from_value.value() {
self.load_loop_var(i, from_value, loops); self.load_loop_var(i, from_value, loops);
@ -387,8 +388,21 @@ impl Nodes {
} }
} }
to.loads.drain(..).for_each(|l| _ = l.remove(self)); for (i, (to_class, from_class)) in
from.loads.drain(..).for_each(|l| _ = l.remove(self)); to.aclasses.iter_mut().zip(from.aclasses.iter_mut()).enumerate()
{
if to_class.last_store.get() != from_class.last_store.get() {
self.load_loop_aclass(i, from_class, loops);
self.load_loop_aclass(i, to_class, loops);
if to_class.last_store.get() != from_class.last_store.get() {
let inps = [ctrl.get(), from_class.last_store.get(), to_class.last_store.get()];
to_class
.last_store
.set_remove(self.new_node(ty::Id::VOID, Kind::Phi, inps), self);
to_class.loads.drain(..).for_each(|d| _ = d.remove(self));
}
}
}
} }
fn graphviz_low( fn graphviz_low(
@ -1122,29 +1136,16 @@ impl Nodes {
} }
} }
fn load_loop_var(&mut self, index: usize, value: &mut Variable, loops: &mut [Loop]) { fn load_loop_var(&mut self, index: usize, var: &mut Variable, loops: &mut [Loop]) {
self.load_loop_value(&mut |l| l.scope.iter_mut().nth(index).unwrap(), value, loops);
}
fn load_loop_store(&mut self, value: &mut Variable, loops: &mut [Loop]) {
self.load_loop_value(&mut |l| &mut l.scope.store, value, loops);
}
fn load_loop_value(
&mut self,
get_lvalue: &mut impl FnMut(&mut Loop) -> &mut Variable,
var: &mut Variable,
loops: &mut [Loop],
) {
if var.value() != VOID { if var.value() != VOID {
return; return;
} }
let [loops @ .., loob] = loops else { unreachable!() }; let [loops @ .., loob] = loops else { unreachable!() };
let node = loob.node; let node = loob.node;
let lvar = get_lvalue(loob); let lvar = &mut loob.scope.vars[index];
self.load_loop_value(get_lvalue, 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 inps = [node, lvar.value(), VOID];
@ -1153,6 +1154,24 @@ impl Nodes {
var.set_value(lvar.value(), self); var.set_value(lvar.value(), self);
} }
fn load_loop_aclass(&mut self, index: usize, var: &mut AClass, loops: &mut [Loop]) {
if var.last_store.get() != VOID {
return;
}
let [loops @ .., loob] = loops else { unreachable!() };
let node = loob.node;
let lvar = &mut loob.scope.aclasses[index];
self.load_loop_aclass(index, lvar, loops);
if !self[lvar.last_store.get()].is_lazy_phi(node) {
let inps = [node, lvar.last_store.get(), VOID];
lvar.last_store.set(self.new_node_nop(ty::Id::VOID, Kind::Phi, inps), self);
}
var.last_store.set(lvar.last_store.get(), self);
}
fn check_dominance(&mut self, nd: Nid, min: Nid, check_outputs: bool) { fn check_dominance(&mut self, nd: Nid, min: Nid, check_outputs: bool) {
if !cfg!(debug_assertions) { if !cfg!(debug_assertions) {
return; return;
@ -1223,6 +1242,7 @@ impl Nodes {
let mut saved = Vc::default(); let mut saved = Vc::default();
let mut cursor = last_store; let mut cursor = last_store;
let mut first_store = last_store;
while cursor != MEM && self[cursor].kind == Kind::Stre { while cursor != MEM && self[cursor].kind == Kind::Stre {
let mut contact_point = cursor; let mut contact_point = cursor;
let mut region = self[cursor].inputs[2]; let mut region = self[cursor].inputs[2];
@ -1240,6 +1260,7 @@ impl Nodes {
}; };
unidentifed.remove(index); unidentifed.remove(index);
saved.push(contact_point); saved.push(contact_point);
first_store = cursor;
cursor = *self[cursor].inputs.get(3).unwrap_or(&MEM); cursor = *self[cursor].inputs.get(3).unwrap_or(&MEM);
if unidentifed.is_empty() { if unidentifed.is_empty() {
@ -1255,6 +1276,19 @@ impl Nodes {
{ {
self.modify_input(mcall, self[mcall].inputs.len() - 1, region); self.modify_input(mcall, self[mcall].inputs.len() - 1, region);
} else { } 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() { if !unidentifed.is_empty() {
continue; continue;
} }
@ -1278,7 +1312,12 @@ impl Nodes {
} }
} }
self.replace(dst, *self[dst].inputs.get(3).unwrap_or(&MEM)); 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() { if self.values[stack as usize].is_ok() {
self.lock(stack); self.lock(stack);
} }
@ -1413,6 +1452,7 @@ pub struct Node {
depth: IDomDepth, depth: IDomDepth,
lock_rc: LockRc, lock_rc: LockRc,
loop_depth: LoopDepth, loop_depth: LoopDepth,
aclass: usize,
} }
impl Node { impl Node {
@ -1583,30 +1623,47 @@ impl Variable {
} }
} }
#[derive(Default, Clone)]
pub struct AClass {
last_store: StrongRef,
loads: Vec<StrongRef>,
}
impl AClass {
fn dup(&self, nodes: &mut Nodes) -> Self {
Self {
last_store: self.last_store.dup(nodes),
loads: self.loads.iter().map(|v| v.dup(nodes)).collect(),
}
}
fn remove(mut self, nodes: &mut Nodes) {
self.last_store.remove(nodes);
self.loads.drain(..).for_each(|n| _ = n.remove(nodes));
}
fn new(nodes: &mut Nodes) -> Self {
Self { last_store: StrongRef::new(MEM, nodes), loads: Default::default() }
}
}
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct Scope { pub struct Scope {
vars: Vec<Variable>, vars: Vec<Variable>,
loads: Vec<StrongRef>, aclasses: Vec<AClass>,
store: Variable,
} }
impl Scope { impl Scope {
fn iter_mut(&mut self) -> impl Iterator<Item = &mut Variable> {
core::iter::once(&mut self.store).chain(self.vars.iter_mut())
}
fn dup(&self, nodes: &mut Nodes) -> Self { fn dup(&self, nodes: &mut Nodes) -> Self {
Self { Self {
vars: self.vars.iter().map(|v| v.dup(nodes)).collect(), vars: self.vars.iter().map(|v| v.dup(nodes)).collect(),
loads: self.loads.iter().map(|l| l.dup(nodes)).collect(), aclasses: self.aclasses.iter().map(|v| v.dup(nodes)).collect(),
store: self.store.dup(nodes),
} }
} }
fn clear(&mut self, nodes: &mut Nodes) { fn clear(&mut self, nodes: &mut Nodes) {
self.vars.drain(..).for_each(|n| n.remove(nodes)); self.vars.drain(..).for_each(|n| n.remove(nodes));
self.loads.drain(..).for_each(|l| _ = l.remove(nodes)); self.aclasses.drain(..).for_each(|l| l.remove(nodes));
mem::take(&mut self.store).remove(nodes);
} }
} }
@ -1661,8 +1718,7 @@ impl ItemCtx {
let loops = self.nodes.new_node(ty::Id::VOID, Kind::Loops, [VOID]); let loops = self.nodes.new_node(ty::Id::VOID, Kind::Loops, [VOID]);
debug_assert_eq!(loops, LOOPS); debug_assert_eq!(loops, LOOPS);
self.nodes.lock(loops); self.nodes.lock(loops);
self.scope.store = self.scope.aclasses.push(AClass::new(&mut self.nodes));
Variable::new(Ident::default(), ty::Id::VOID, false, MEM, &mut self.nodes);
} }
fn finalize(&mut self, stack: &mut Vec<Nid>) { fn finalize(&mut self, stack: &mut Vec<Nid>) {
@ -1927,9 +1983,11 @@ impl<'a> Codegen<'a> {
); );
debug_assert!(self.ci.nodes[region].kind != Kind::Stre); debug_assert!(self.ci.nodes[region].kind != Kind::Stre);
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops); let index = self.aclass_index(region);
let mut vc = Vc::from([VOID, value, region, self.ci.scope.store.value()]); let aclass = &mut self.ci.scope.aclasses[index];
for load in self.ci.scope.loads.drain(..) { self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
let mut vc = Vc::from([VOID, value, region, aclass.last_store.get()]);
for load in aclass.loads.drain(..) {
if load.get() == value { if load.get() == value {
load.soft_remove(&mut self.ci.nodes); load.soft_remove(&mut self.ci.nodes);
continue; continue;
@ -1939,9 +1997,9 @@ impl<'a> Codegen<'a> {
} }
} }
let store = self.ci.nodes.new_node_nop(ty, Kind::Stre, vc); let store = self.ci.nodes.new_node_nop(ty, Kind::Stre, vc);
self.ci.scope.store.set_value(store, &mut self.ci.nodes); aclass.last_store.set(store, &mut self.ci.nodes);
let opted = self.ci.nodes.late_peephole(store).unwrap_or(store); let opted = self.ci.nodes.late_peephole(store).unwrap_or(store);
self.ci.scope.store.set_value_remove(opted, &mut self.ci.nodes); aclass.last_store.set_remove(opted, &mut self.ci.nodes);
opted opted
} }
@ -1959,13 +2017,26 @@ 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);
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops); let index = self.aclass_index(region);
let vc = [VOID, region, self.ci.scope.store.value()]; let aclass = &mut self.ci.scope.aclasses[index];
self.ci.nodes.load_loop_aclass(index, aclass, &mut self.ci.loops);
let vc = [VOID, region, aclass.last_store.get()];
let load = self.ci.nodes.new_node(ty, Kind::Load, vc); let load = self.ci.nodes.new_node(ty, Kind::Load, vc);
self.ci.scope.loads.push(StrongRef::new(load, &mut self.ci.nodes)); aclass.loads.push(StrongRef::new(load, &mut self.ci.nodes));
load load
} }
pub fn aclass_index(&mut self, mut region: Nid) -> usize {
loop {
region = match self.ci.nodes[region].kind {
Kind::BinOp { op: TokenKind::Add | TokenKind::Sub } | Kind::Phi => {
self.ci.nodes[region].inputs[1]
}
_ => break self.ci.nodes[region].aclass,
};
}
}
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() {
@ -2114,8 +2185,10 @@ impl<'a> Codegen<'a> {
if self.ci.inline_depth == 0 { if self.ci.inline_depth == 0 {
debug_assert_ne!(self.ci.ctrl.get(), VOID); debug_assert_ne!(self.ci.ctrl.get(), VOID);
let mut inps = Vc::from([self.ci.ctrl.get(), value.id]); let mut inps = Vc::from([self.ci.ctrl.get(), value.id]);
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops); for (i, aclass) in self.ci.scope.aclasses.iter_mut().enumerate() {
inps.push(self.ci.scope.store.value()); self.ci.nodes.load_loop_aclass(i, aclass, &mut self.ci.loops);
inps.push(aclass.last_store.get());
}
self.ci.ctrl.set( self.ci.ctrl.set(
self.ci.nodes.new_node(ty::Id::VOID, Kind::Return, inps), self.ci.nodes.new_node(ty::Id::VOID, Kind::Return, inps),
@ -2453,9 +2526,17 @@ impl<'a> Codegen<'a> {
let mut inps = Vc::from([NEVER]); let mut inps = Vc::from([NEVER]);
let arg_base = self.tys.tmp.args.len(); let arg_base = self.tys.tmp.args.len();
let mut has_ptr_arg = false; let mut has_ptr_arg = false;
let mut clobbered_aliases = vec![];
for arg in args { for arg in args {
let value = self.expr(arg)?; let value = self.expr(arg)?;
has_ptr_arg |= value.ty.has_pointers(self.tys); if let Some(base) = self.tys.base_of(value.ty) {
clobbered_aliases.push(self.aclass_index(value.id));
if base.has_pointers(self.tys) {
clobbered_aliases.push(0);
}
} else if value.ty.has_pointers(self.tys) {
clobbered_aliases.push(0);
}
self.tys.tmp.args.push(value.ty); self.tys.tmp.args.push(value.ty);
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
self.ci.nodes.lock(value.id); self.ci.nodes.lock(value.id);
@ -2468,9 +2549,10 @@ impl<'a> Codegen<'a> {
self.ci.nodes.unlock(n); self.ci.nodes.unlock(n);
} }
if has_ptr_arg { for &clobbered in clobbered_aliases.iter() {
inps.push(self.ci.scope.store.value()); let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.scope.loads.retain_mut(|load| { inps.push(aclass.last_store.get());
aclass.loads.retain_mut(|load| {
if inps.contains(&load.get()) { if inps.contains(&load.get()) {
return true; return true;
} }
@ -2498,10 +2580,6 @@ impl<'a> Codegen<'a> {
&mut self.ci.nodes, &mut self.ci.nodes,
); );
if has_ptr_arg {
self.store_mem(VOID, ty::Id::VOID, VOID);
}
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty))) alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty)))
} }
Expr::Call { func, args, .. } => { Expr::Call { func, args, .. } => {
@ -2541,16 +2619,25 @@ impl<'a> Codegen<'a> {
let mut cargs = cargs.iter(); let mut cargs = cargs.iter();
let mut args = args.iter(); let mut args = args.iter();
let mut has_ptr_arg = false; let mut has_ptr_arg = false;
let mut clobbered_aliases = vec![];
while let Some(ty) = tys.next(self.tys) { while let Some(ty) = tys.next(self.tys) {
let carg = cargs.next().unwrap(); let carg = cargs.next().unwrap();
let Some(arg) = args.next() else { break }; let Some(arg) = args.next() else { break };
let Arg::Value(ty) = ty else { continue }; let Arg::Value(ty) = ty else { continue };
has_ptr_arg |= ty.has_pointers(self.tys);
let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?; let mut value = self.expr_ctx(arg, Ctx::default().with_ty(ty))?;
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre); debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
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) {
clobbered_aliases.push(self.aclass_index(value.id));
if base.has_pointers(self.tys) {
clobbered_aliases.push(0);
}
} else if value.ty.has_pointers(self.tys) {
clobbered_aliases.push(0);
}
self.ci.nodes.lock(value.id); self.ci.nodes.lock(value.id);
inps.push(value.id); inps.push(value.id);
} }
@ -2559,9 +2646,10 @@ impl<'a> Codegen<'a> {
self.ci.nodes.unlock(n); self.ci.nodes.unlock(n);
} }
if has_ptr_arg { for &clobbered in clobbered_aliases.iter() {
inps.push(self.ci.scope.store.value()); let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.scope.loads.retain_mut(|load| { inps.push(aclass.last_store.get());
aclass.loads.retain_mut(|load| {
if inps.contains(&load.get()) { if inps.contains(&load.get()) {
return true; return true;
} }
@ -2589,10 +2677,6 @@ impl<'a> Codegen<'a> {
&mut self.ci.nodes, &mut self.ci.nodes,
); );
if has_ptr_arg {
self.store_mem(VOID, ty::Id::VOID, VOID);
}
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)))
} }
Expr::Directive { name: "inline", args: [func, args @ ..], .. } => { Expr::Directive { name: "inline", args: [func, args @ ..], .. } => {
@ -2893,10 +2977,14 @@ impl<'a> Codegen<'a> {
scope: self.ci.scope.dup(&mut self.ci.nodes), scope: self.ci.scope.dup(&mut self.ci.nodes),
}); });
for var in &mut self.ci.scope.iter_mut() { for var in self.ci.scope.vars.iter_mut() {
var.set_value(VOID, &mut self.ci.nodes); var.set_value(VOID, &mut self.ci.nodes);
} }
for aclass in self.ci.scope.aclasses.iter_mut() {
aclass.last_store.set(VOID, &mut self.ci.nodes);
}
self.expr(body); self.expr(body);
let Loop { ctrl: [con, ..], ctrl_scope: [cons, ..], .. } = let Loop { ctrl: [con, ..], ctrl_scope: [cons, ..], .. } =
@ -2931,7 +3019,9 @@ impl<'a> Codegen<'a> {
} }
let Some(bre) = bre.unwrap(&mut self.ci.nodes) else { let Some(bre) = bre.unwrap(&mut self.ci.nodes) else {
for (loop_var, scope_var) in self.ci.scope.iter_mut().zip(scope.iter_mut()) { for (loop_var, scope_var) in
self.ci.scope.vars.iter_mut().zip(scope.vars.iter_mut())
{
if self.ci.nodes[scope_var.value()].is_lazy_phi(node) { if self.ci.nodes[scope_var.value()].is_lazy_phi(node) {
if loop_var.value() != scope_var.value() { if loop_var.value() != scope_var.value() {
scope_var.set_value( scope_var.set_value(
@ -2950,6 +3040,29 @@ impl<'a> Codegen<'a> {
} }
} }
} }
for (loop_class, scope_class) in
self.ci.scope.aclasses.iter_mut().zip(scope.aclasses.iter_mut())
{
if self.ci.nodes[scope_class.last_store.get()].is_lazy_phi(node) {
if loop_class.last_store.get() != scope_class.last_store.get() {
scope_class.last_store.set(
self.ci.nodes.modify_input(
scope_class.last_store.get(),
2,
loop_class.last_store.get(),
),
&mut self.ci.nodes,
);
} else {
let phi = &self.ci.nodes[scope_class.last_store.get()];
let prev = phi.inputs[1];
self.ci.nodes.replace(scope_class.last_store.get(), prev);
scope_class.last_store.set(prev, &mut self.ci.nodes);
}
}
}
scope.clear(&mut self.ci.nodes); scope.clear(&mut self.ci.nodes);
self.ci.ctrl.set(NEVER, &mut self.ci.nodes); self.ci.ctrl.set(NEVER, &mut self.ci.nodes);
@ -2965,8 +3078,13 @@ impl<'a> Codegen<'a> {
self.ci.nodes.lock(node); self.ci.nodes.lock(node);
for ((dest_var, scope_var), loop_var) in for ((dest_var, scope_var), loop_var) in self
self.ci.scope.iter_mut().zip(scope.iter_mut()).zip(bres.iter_mut()) .ci
.scope
.vars
.iter_mut()
.zip(scope.vars.iter_mut())
.zip(bres.vars.iter_mut())
{ {
if self.ci.nodes[scope_var.value()].is_lazy_phi(node) { if self.ci.nodes[scope_var.value()].is_lazy_phi(node) {
if loop_var.value() != scope_var.value() { if loop_var.value() != scope_var.value() {
@ -2992,9 +3110,44 @@ impl<'a> Codegen<'a> {
debug_assert!(!self.ci.nodes[dest_var.value()].is_lazy_phi(node)); debug_assert!(!self.ci.nodes[dest_var.value()].is_lazy_phi(node));
} }
for ((dest_class, scope_class), loop_class) in self
.ci
.scope
.aclasses
.iter_mut()
.zip(scope.aclasses.iter_mut())
.zip(bres.aclasses.iter_mut())
{
if self.ci.nodes[scope_class.last_store.get()].is_lazy_phi(node) {
if loop_class.last_store.get() != scope_class.last_store.get() {
scope_class.last_store.set(
self.ci.nodes.modify_input(
scope_class.last_store.get(),
2,
loop_class.last_store.get(),
),
&mut self.ci.nodes,
);
} else {
if dest_class.last_store.get() == scope_class.last_store.get() {
dest_class.last_store.set(VOID, &mut self.ci.nodes);
}
let phi = &self.ci.nodes[scope_class.last_store.get()];
let prev = phi.inputs[1];
self.ci.nodes.replace(scope_class.last_store.get(), prev);
scope_class.last_store.set(prev, &mut self.ci.nodes);
}
}
if dest_class.last_store.get() == VOID {
dest_class.last_store.set(scope_class.last_store.get(), &mut self.ci.nodes);
}
debug_assert!(!self.ci.nodes[dest_class.last_store.get()].is_lazy_phi(node));
}
scope.clear(&mut self.ci.nodes); scope.clear(&mut self.ci.nodes);
bres.clear(&mut self.ci.nodes); bres.clear(&mut self.ci.nodes);
self.ci.scope.loads.drain(..).for_each(|l| _ = l.remove(&mut self.ci.nodes));
self.ci.nodes.unlock(node); self.ci.nodes.unlock(node);
let rpl = self.ci.nodes.late_peephole(node).unwrap_or(node); let rpl = self.ci.nodes.late_peephole(node).unwrap_or(node);
@ -3029,8 +3182,11 @@ impl<'a> Codegen<'a> {
} }
} }
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops); let mut orig_classes = vec![];
let orig_store = self.ci.scope.store.dup(&mut self.ci.nodes); for (i, aclass) in self.ci.scope.aclasses.iter_mut().enumerate() {
self.ci.nodes.load_loop_aclass(i, aclass, &mut self.ci.loops);
orig_classes.push(aclass.dup(&mut self.ci.nodes));
}
let else_scope = self.ci.scope.dup(&mut self.ci.nodes); let else_scope = self.ci.scope.dup(&mut self.ci.nodes);
self.ci.ctrl.set( self.ci.ctrl.set(
@ -3050,7 +3206,7 @@ impl<'a> Codegen<'a> {
self.ci.ctrl.get() self.ci.ctrl.get()
}; };
orig_store.remove(&mut self.ci.nodes); orig_classes.into_iter().for_each(|c| c.remove(&mut self.ci.nodes));
if lcntrl == Nid::MAX && rcntrl == Nid::MAX { if lcntrl == Nid::MAX && rcntrl == Nid::MAX {
then_scope.clear(&mut self.ci.nodes); then_scope.clear(&mut self.ci.nodes);

View file

@ -1,26 +1,24 @@
main: main:
ADDI64 r254, r254, -36d ADDI64 r254, r254, -44d
ST r31, r254, 28a, 8h ST r31, r254, 28a, 16h
LI8 r2, 0b LI64 r32, 1d
ST r2, r254, 0a, 1h ADDI64 r2, r254, 0d
ST r2, r254, 1a, 1h ST r32, r254, 0a, 8h
LI16 r4, 511h LI64 r8, 2d
ST r4, r254, 2a, 1h ST r8, r254, 8a, 8h
LI16 r8, 1h LI64 r11, 4d
ST r8, r254, 3a, 1h ST r11, r254, 16a, 8h
LI64 r11, 1d
ADDI64 r2, r254, 4d
ST r11, r254, 4a, 8h
LI64 r3, 2d
ST r3, r254, 12a, 8h
LI64 r6, 4d
ST r6, r254, 20a, 8h
JAL r31, r0, :pass JAL r31, r0, :pass
LD r12, r254, 3a, 1h LI8 r10, 0b
ANDI r2, r12, 255d ST r10, r254, 24a, 1h
ADD64 r1, r1, r2 ST r10, r254, 25a, 1h
LD r31, r254, 28a, 8h LI16 r12, 511h
ADDI64 r254, r254, 36d ST r12, r254, 26a, 1h
LI16 r4, 1h
ST r4, r254, 27a, 1h
ADD64 r1, r1, r32
LD r31, r254, 28a, 16h
ADDI64 r254, r254, 44d
JALA r0, r31, 0a JALA r0, r31, 0a
pass: pass:
LD r4, r2, 8a, 8h LD r4, r2, 8a, 8h
@ -31,6 +29,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: 318 code size: 294
ret: 8 ret: 8
status: Ok(()) status: Ok(())

View file

@ -1,48 +1,44 @@
main: main:
ADDI64 r254, r254, -24d ADDI64 r254, r254, -12d
LI8 r3, 255b LI8 r1, 255b
ADDI64 r2, r254, 12d ST r1, r254, 0a, 1h
ST r3, r254, 12a, 1h LI8 r4, 0b
LI8 r6, 0b ST r4, r254, 1a, 1h
ST r6, r254, 13a, 1h ST r4, r254, 2a, 1h
ST r6, r254, 14a, 1h ST r1, r254, 3a, 1h
ST r3, r254, 15a, 1h LI32 r9, 0w
LI32 r11, 0w ST r9, r254, 4a, 4h
ST r11, r254, 16a, 4h LI32 r12, 2w
LI32 r3, 2w ST r12, r254, 8a, 4h
ST r3, r254, 20a, 4h LD r3, r254, 8a, 4h
ADDI64 r5, r254, 0d
BMC r2, r5, 12h
LD r8, r254, 8a, 4h
ANDI r8, r8, 4294967295d
ANDI r3, r3, 4294967295d ANDI r3, r3, 4294967295d
JEQ r8, r3, :0 ANDI r12, r12, 4294967295d
JEQ r3, r12, :0
LI64 r1, 0d LI64 r1, 0d
JMP :1 JMP :1
0: LD r2, r254, 4a, 4h 0: LD r10, r254, 4a, 4h
ANDI r2, r2, 4294967295d ANDI r10, r10, 4294967295d
ANDI r11, r11, 4294967295d ANDI r9, r9, 4294967295d
JEQ r2, r11, :2 JEQ r10, r9, :2
LI64 r1, 64d LI64 r1, 64d
JMP :1 JMP :1
2: LD r11, r254, 0a, 1h 2: LD r4, r254, 0a, 1h
LD r9, r254, 4a, 4h LD r7, r254, 1a, 1h
LD r12, r254, 8a, 4h ANDI r8, r4, 255d
LD r5, r254, 1a, 1h LD r6, r254, 4a, 4h
ANDI r4, r11, 255d LD r1, r254, 2a, 1h
ADD32 r3, r12, r9 ANDI r2, r7, 255d
LD r11, r254, 2a, 1h ADD32 r7, r6, r8
ANDI r10, r5, 255d
ADD32 r9, r3, r4
LD r5, r254, 3a, 1h LD r5, r254, 3a, 1h
ANDI r4, r11, 255d ANDI r6, r1, 255d
ADD32 r3, r9, r10 ADD32 r11, r7, r2
ANDI r9, r5, 255d ANDI r9, r5, 255d
ADD32 r8, r3, r4 ADD32 r2, r11, r6
ADD32 r12, r8, r9 ADD32 r4, r2, r9
ANDI r1, r12, 4294967295d ADD32 r6, r4, r12
1: ADDI64 r254, r254, 24d ANDI r1, r6, 4294967295d
1: ADDI64 r254, r254, 12d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 427 code size: 387
ret: 512 ret: 512
status: Ok(()) status: Ok(())

View file

@ -23,25 +23,21 @@ scalar_values:
JALA r0, r31, 0a JALA r0, r31, 0a
structs: structs:
ADDI64 r254, r254, -48d ADDI64 r254, r254, -48d
LI64 r1, 0d LI64 r3, 5d
ST r1, r254, 40a, 8h ST r3, r254, 0a, 8h
LI64 r4, 20d ST r3, r254, 8a, 8h
ST r4, r254, 0a, 8h LD r7, r254, 0a, 8h
LI64 r7, 5d ADDI64 r9, r7, 15d
ST r7, r254, 8a, 8h ST r9, r254, 24a, 8h
ST r7, r254, 16a, 8h LI64 r8, 20d
LD r11, r254, 0a, 8h ST r8, r254, 32a, 8h
LD r1, r254, 8a, 8h LI64 r9, 0d
ADD64 r3, r1, r11 LD r3, r254, 24a, 8h
SUB64 r5, r3, r7 ST r8, r254, 16a, 8h
ST r5, r254, 24a, 8h ST r9, r254, 40a, 8h
ST r4, r254, 32a, 8h SUB64 r1, r3, r8
LD r9, r254, 40a, 8h
LD r11, r254, 24a, 8h
ADD64 r1, r11, r9
SUB64 r1, r1, r4
ADDI64 r254, r254, 48d ADDI64 r254, r254, 48d
JALA r0, r31, 0a JALA r0, r31, 0a
code size: 373 code size: 346
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -1,11 +1,11 @@
main: main:
ADDI64 r254, r254, -24d ADDI64 r254, r254, -24d
ST r31, r254, 16a, 8h ST r31, r254, 16a, 8h
ADDI64 r3, r254, 0d
ADDI64 r2, r254, 8d ADDI64 r2, r254, 8d
LI64 r4, 0d LI64 r4, 0d
ST r4, r254, 8a, 8h
ADDI64 r3, r254, 0d
ST r4, r254, 0a, 8h ST r4, r254, 0a, 8h
ST r4, r254, 8a, 8h
LI64 r4, 1024d LI64 r4, 1024d
JAL r31, r0, :set JAL r31, r0, :set
ANDI r1, r1, 4294967295d ANDI r1, r1, 4294967295d