forked from AbleOS/holey-bytes
saving this to make sure
This commit is contained in:
parent
37db783699
commit
bbd7e12af4
290
lang/src/son.rs
290
lang/src/son.rs
|
@ -9,7 +9,7 @@ use {
|
|||
idfl::{self},
|
||||
CtorField, Expr, FileId, Pos,
|
||||
},
|
||||
task,
|
||||
reg, task,
|
||||
ty::{self, Arg, ArrayLen, Loc, Tuple},
|
||||
vc::{BitSet, Vc},
|
||||
FTask, Func, Global, Ident, Offset, OffsetIter, Reloc, Sig, StringRef, SymKey, TypeParser,
|
||||
|
@ -375,7 +375,8 @@ impl Nodes {
|
|||
to: &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);
|
||||
if to_value.value() != from_value.value() {
|
||||
self.load_loop_var(i, from_value, loops);
|
||||
|
@ -387,8 +388,21 @@ impl Nodes {
|
|||
}
|
||||
}
|
||||
|
||||
to.loads.drain(..).for_each(|l| _ = l.remove(self));
|
||||
from.loads.drain(..).for_each(|l| _ = l.remove(self));
|
||||
for (i, (to_class, from_class)) in
|
||||
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(
|
||||
|
@ -1122,29 +1136,16 @@ impl Nodes {
|
|||
}
|
||||
}
|
||||
|
||||
fn load_loop_var(&mut self, index: usize, value: &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],
|
||||
) {
|
||||
fn load_loop_var(&mut self, index: usize, var: &mut Variable, loops: &mut [Loop]) {
|
||||
if var.value() != VOID {
|
||||
return;
|
||||
}
|
||||
|
||||
let [loops @ .., loob] = loops else { unreachable!() };
|
||||
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) {
|
||||
let inps = [node, lvar.value(), VOID];
|
||||
|
@ -1153,6 +1154,24 @@ impl Nodes {
|
|||
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) {
|
||||
if !cfg!(debug_assertions) {
|
||||
return;
|
||||
|
@ -1223,6 +1242,7 @@ impl Nodes {
|
|||
|
||||
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];
|
||||
|
@ -1240,6 +1260,7 @@ impl Nodes {
|
|||
};
|
||||
unidentifed.remove(index);
|
||||
saved.push(contact_point);
|
||||
first_store = cursor;
|
||||
cursor = *self[cursor].inputs.get(3).unwrap_or(&MEM);
|
||||
|
||||
if unidentifed.is_empty() {
|
||||
|
@ -1255,6 +1276,19 @@ impl Nodes {
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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() {
|
||||
self.lock(stack);
|
||||
}
|
||||
|
@ -1413,6 +1452,7 @@ pub struct Node {
|
|||
depth: IDomDepth,
|
||||
lock_rc: LockRc,
|
||||
loop_depth: LoopDepth,
|
||||
aclass: usize,
|
||||
}
|
||||
|
||||
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)]
|
||||
pub struct Scope {
|
||||
vars: Vec<Variable>,
|
||||
loads: Vec<StrongRef>,
|
||||
store: Variable,
|
||||
aclasses: Vec<AClass>,
|
||||
}
|
||||
|
||||
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 {
|
||||
Self {
|
||||
vars: self.vars.iter().map(|v| v.dup(nodes)).collect(),
|
||||
loads: self.loads.iter().map(|l| l.dup(nodes)).collect(),
|
||||
store: self.store.dup(nodes),
|
||||
aclasses: self.aclasses.iter().map(|v| v.dup(nodes)).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn clear(&mut self, nodes: &mut Nodes) {
|
||||
self.vars.drain(..).for_each(|n| n.remove(nodes));
|
||||
self.loads.drain(..).for_each(|l| _ = l.remove(nodes));
|
||||
mem::take(&mut self.store).remove(nodes);
|
||||
self.aclasses.drain(..).for_each(|l| l.remove(nodes));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1661,8 +1718,7 @@ impl ItemCtx {
|
|||
let loops = self.nodes.new_node(ty::Id::VOID, Kind::Loops, [VOID]);
|
||||
debug_assert_eq!(loops, LOOPS);
|
||||
self.nodes.lock(loops);
|
||||
self.scope.store =
|
||||
Variable::new(Ident::default(), ty::Id::VOID, false, MEM, &mut self.nodes);
|
||||
self.scope.aclasses.push(AClass::new(&mut self.nodes));
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
self.ci.nodes.load_loop_store(&mut self.ci.scope.store, &mut self.ci.loops);
|
||||
let mut vc = Vc::from([VOID, value, region, self.ci.scope.store.value()]);
|
||||
for load in self.ci.scope.loads.drain(..) {
|
||||
let index = self.aclass_index(region);
|
||||
let aclass = &mut self.ci.scope.aclasses[index];
|
||||
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 {
|
||||
load.soft_remove(&mut self.ci.nodes);
|
||||
continue;
|
||||
|
@ -1939,9 +1997,9 @@ impl<'a> Codegen<'a> {
|
|||
}
|
||||
}
|
||||
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);
|
||||
self.ci.scope.store.set_value_remove(opted, &mut self.ci.nodes);
|
||||
aclass.last_store.set_remove(opted, &mut self.ci.nodes);
|
||||
opted
|
||||
}
|
||||
|
||||
|
@ -1959,13 +2017,26 @@ impl<'a> Codegen<'a> {
|
|||
self.ty_display(self.ci.nodes[region].ty)
|
||||
);
|
||||
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 vc = [VOID, region, self.ci.scope.store.value()];
|
||||
let index = self.aclass_index(region);
|
||||
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);
|
||||
self.ci.scope.loads.push(StrongRef::new(load, &mut self.ci.nodes));
|
||||
aclass.loads.push(StrongRef::new(load, &mut self.ci.nodes));
|
||||
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) {
|
||||
self.find_type(0, entry, entry, Err("main"), self.files);
|
||||
if self.tys.ins.funcs.is_empty() {
|
||||
|
@ -2114,8 +2185,10 @@ impl<'a> Codegen<'a> {
|
|||
if self.ci.inline_depth == 0 {
|
||||
debug_assert_ne!(self.ci.ctrl.get(), VOID);
|
||||
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);
|
||||
inps.push(self.ci.scope.store.value());
|
||||
for (i, aclass) in self.ci.scope.aclasses.iter_mut().enumerate() {
|
||||
self.ci.nodes.load_loop_aclass(i, aclass, &mut self.ci.loops);
|
||||
inps.push(aclass.last_store.get());
|
||||
}
|
||||
|
||||
self.ci.ctrl.set(
|
||||
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 arg_base = self.tys.tmp.args.len();
|
||||
let mut has_ptr_arg = false;
|
||||
let mut clobbered_aliases = vec![];
|
||||
for arg in args {
|
||||
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);
|
||||
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
|
||||
self.ci.nodes.lock(value.id);
|
||||
|
@ -2468,9 +2549,10 @@ impl<'a> Codegen<'a> {
|
|||
self.ci.nodes.unlock(n);
|
||||
}
|
||||
|
||||
if has_ptr_arg {
|
||||
inps.push(self.ci.scope.store.value());
|
||||
self.ci.scope.loads.retain_mut(|load| {
|
||||
for &clobbered in clobbered_aliases.iter() {
|
||||
let aclass = &mut self.ci.scope.aclasses[clobbered];
|
||||
inps.push(aclass.last_store.get());
|
||||
aclass.loads.retain_mut(|load| {
|
||||
if inps.contains(&load.get()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2498,10 +2580,6 @@ impl<'a> Codegen<'a> {
|
|||
&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)))
|
||||
}
|
||||
Expr::Call { func, args, .. } => {
|
||||
|
@ -2541,16 +2619,25 @@ impl<'a> Codegen<'a> {
|
|||
let mut cargs = cargs.iter();
|
||||
let mut args = args.iter();
|
||||
let mut has_ptr_arg = false;
|
||||
let mut clobbered_aliases = vec![];
|
||||
while let Some(ty) = tys.next(self.tys) {
|
||||
let carg = cargs.next().unwrap();
|
||||
let Some(arg) = args.next() else { break };
|
||||
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))?;
|
||||
debug_assert_ne!(self.ci.nodes[value.id].kind, Kind::Stre);
|
||||
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);
|
||||
inps.push(value.id);
|
||||
}
|
||||
|
@ -2559,9 +2646,10 @@ impl<'a> Codegen<'a> {
|
|||
self.ci.nodes.unlock(n);
|
||||
}
|
||||
|
||||
if has_ptr_arg {
|
||||
inps.push(self.ci.scope.store.value());
|
||||
self.ci.scope.loads.retain_mut(|load| {
|
||||
for &clobbered in clobbered_aliases.iter() {
|
||||
let aclass = &mut self.ci.scope.aclasses[clobbered];
|
||||
inps.push(aclass.last_store.get());
|
||||
aclass.loads.retain_mut(|load| {
|
||||
if inps.contains(&load.get()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -2589,10 +2677,6 @@ impl<'a> Codegen<'a> {
|
|||
&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)))
|
||||
}
|
||||
Expr::Directive { name: "inline", args: [func, args @ ..], .. } => {
|
||||
|
@ -2893,10 +2977,14 @@ impl<'a> Codegen<'a> {
|
|||
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);
|
||||
}
|
||||
|
||||
for aclass in self.ci.scope.aclasses.iter_mut() {
|
||||
aclass.last_store.set(VOID, &mut self.ci.nodes);
|
||||
}
|
||||
|
||||
self.expr(body);
|
||||
|
||||
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 {
|
||||
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 loop_var.value() != scope_var.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);
|
||||
self.ci.ctrl.set(NEVER, &mut self.ci.nodes);
|
||||
|
||||
|
@ -2965,8 +3078,13 @@ impl<'a> Codegen<'a> {
|
|||
|
||||
self.ci.nodes.lock(node);
|
||||
|
||||
for ((dest_var, scope_var), loop_var) in
|
||||
self.ci.scope.iter_mut().zip(scope.iter_mut()).zip(bres.iter_mut())
|
||||
for ((dest_var, scope_var), loop_var) in self
|
||||
.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 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));
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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 orig_store = self.ci.scope.store.dup(&mut self.ci.nodes);
|
||||
let mut orig_classes = vec![];
|
||||
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);
|
||||
|
||||
self.ci.ctrl.set(
|
||||
|
@ -3050,7 +3206,7 @@ impl<'a> Codegen<'a> {
|
|||
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 {
|
||||
then_scope.clear(&mut self.ci.nodes);
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -36d
|
||||
ST r31, r254, 28a, 8h
|
||||
LI8 r2, 0b
|
||||
ST r2, r254, 0a, 1h
|
||||
ST r2, r254, 1a, 1h
|
||||
LI16 r4, 511h
|
||||
ST r4, r254, 2a, 1h
|
||||
LI16 r8, 1h
|
||||
ST r8, r254, 3a, 1h
|
||||
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
|
||||
ADDI64 r254, r254, -44d
|
||||
ST r31, r254, 28a, 16h
|
||||
LI64 r32, 1d
|
||||
ADDI64 r2, r254, 0d
|
||||
ST r32, r254, 0a, 8h
|
||||
LI64 r8, 2d
|
||||
ST r8, r254, 8a, 8h
|
||||
LI64 r11, 4d
|
||||
ST r11, r254, 16a, 8h
|
||||
JAL r31, r0, :pass
|
||||
LD r12, r254, 3a, 1h
|
||||
ANDI r2, r12, 255d
|
||||
ADD64 r1, r1, r2
|
||||
LD r31, r254, 28a, 8h
|
||||
ADDI64 r254, r254, 36d
|
||||
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
|
||||
LD r31, r254, 28a, 16h
|
||||
ADDI64 r254, r254, 44d
|
||||
JALA r0, r31, 0a
|
||||
pass:
|
||||
LD r4, r2, 8a, 8h
|
||||
|
@ -31,6 +29,6 @@ pass:
|
|||
LD r1, r10, 0a, 8h
|
||||
ADD64 r1, r1, r9
|
||||
JALA r0, r31, 0a
|
||||
code size: 318
|
||||
code size: 294
|
||||
ret: 8
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,48 +1,44 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -24d
|
||||
LI8 r3, 255b
|
||||
ADDI64 r2, r254, 12d
|
||||
ST r3, r254, 12a, 1h
|
||||
LI8 r6, 0b
|
||||
ST r6, r254, 13a, 1h
|
||||
ST r6, r254, 14a, 1h
|
||||
ST r3, r254, 15a, 1h
|
||||
LI32 r11, 0w
|
||||
ST r11, r254, 16a, 4h
|
||||
LI32 r3, 2w
|
||||
ST r3, r254, 20a, 4h
|
||||
ADDI64 r5, r254, 0d
|
||||
BMC r2, r5, 12h
|
||||
LD r8, r254, 8a, 4h
|
||||
ANDI r8, r8, 4294967295d
|
||||
ADDI64 r254, r254, -12d
|
||||
LI8 r1, 255b
|
||||
ST r1, r254, 0a, 1h
|
||||
LI8 r4, 0b
|
||||
ST r4, r254, 1a, 1h
|
||||
ST r4, r254, 2a, 1h
|
||||
ST r1, r254, 3a, 1h
|
||||
LI32 r9, 0w
|
||||
ST r9, r254, 4a, 4h
|
||||
LI32 r12, 2w
|
||||
ST r12, r254, 8a, 4h
|
||||
LD r3, r254, 8a, 4h
|
||||
ANDI r3, r3, 4294967295d
|
||||
JEQ r8, r3, :0
|
||||
ANDI r12, r12, 4294967295d
|
||||
JEQ r3, r12, :0
|
||||
LI64 r1, 0d
|
||||
JMP :1
|
||||
0: LD r2, r254, 4a, 4h
|
||||
ANDI r2, r2, 4294967295d
|
||||
ANDI r11, r11, 4294967295d
|
||||
JEQ r2, r11, :2
|
||||
0: LD r10, r254, 4a, 4h
|
||||
ANDI r10, r10, 4294967295d
|
||||
ANDI r9, r9, 4294967295d
|
||||
JEQ r10, r9, :2
|
||||
LI64 r1, 64d
|
||||
JMP :1
|
||||
2: LD r11, r254, 0a, 1h
|
||||
LD r9, r254, 4a, 4h
|
||||
LD r12, r254, 8a, 4h
|
||||
LD r5, r254, 1a, 1h
|
||||
ANDI r4, r11, 255d
|
||||
ADD32 r3, r12, r9
|
||||
LD r11, r254, 2a, 1h
|
||||
ANDI r10, r5, 255d
|
||||
ADD32 r9, r3, r4
|
||||
2: LD r4, r254, 0a, 1h
|
||||
LD r7, r254, 1a, 1h
|
||||
ANDI r8, r4, 255d
|
||||
LD r6, r254, 4a, 4h
|
||||
LD r1, r254, 2a, 1h
|
||||
ANDI r2, r7, 255d
|
||||
ADD32 r7, r6, r8
|
||||
LD r5, r254, 3a, 1h
|
||||
ANDI r4, r11, 255d
|
||||
ADD32 r3, r9, r10
|
||||
ANDI r6, r1, 255d
|
||||
ADD32 r11, r7, r2
|
||||
ANDI r9, r5, 255d
|
||||
ADD32 r8, r3, r4
|
||||
ADD32 r12, r8, r9
|
||||
ANDI r1, r12, 4294967295d
|
||||
1: ADDI64 r254, r254, 24d
|
||||
ADD32 r2, r11, r6
|
||||
ADD32 r4, r2, r9
|
||||
ADD32 r6, r4, r12
|
||||
ANDI r1, r6, 4294967295d
|
||||
1: ADDI64 r254, r254, 12d
|
||||
JALA r0, r31, 0a
|
||||
code size: 427
|
||||
code size: 387
|
||||
ret: 512
|
||||
status: Ok(())
|
||||
|
|
|
@ -23,25 +23,21 @@ scalar_values:
|
|||
JALA r0, r31, 0a
|
||||
structs:
|
||||
ADDI64 r254, r254, -48d
|
||||
LI64 r1, 0d
|
||||
ST r1, r254, 40a, 8h
|
||||
LI64 r4, 20d
|
||||
ST r4, r254, 0a, 8h
|
||||
LI64 r7, 5d
|
||||
ST r7, r254, 8a, 8h
|
||||
ST r7, r254, 16a, 8h
|
||||
LD r11, r254, 0a, 8h
|
||||
LD r1, r254, 8a, 8h
|
||||
ADD64 r3, r1, r11
|
||||
SUB64 r5, r3, r7
|
||||
ST r5, r254, 24a, 8h
|
||||
ST r4, r254, 32a, 8h
|
||||
LD r9, r254, 40a, 8h
|
||||
LD r11, r254, 24a, 8h
|
||||
ADD64 r1, r11, r9
|
||||
SUB64 r1, r1, r4
|
||||
LI64 r3, 5d
|
||||
ST r3, r254, 0a, 8h
|
||||
ST r3, r254, 8a, 8h
|
||||
LD r7, r254, 0a, 8h
|
||||
ADDI64 r9, r7, 15d
|
||||
ST r9, r254, 24a, 8h
|
||||
LI64 r8, 20d
|
||||
ST r8, r254, 32a, 8h
|
||||
LI64 r9, 0d
|
||||
LD r3, r254, 24a, 8h
|
||||
ST r8, r254, 16a, 8h
|
||||
ST r9, r254, 40a, 8h
|
||||
SUB64 r1, r3, r8
|
||||
ADDI64 r254, r254, 48d
|
||||
JALA r0, r31, 0a
|
||||
code size: 373
|
||||
code size: 346
|
||||
ret: 0
|
||||
status: Ok(())
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
main:
|
||||
ADDI64 r254, r254, -24d
|
||||
ST r31, r254, 16a, 8h
|
||||
ADDI64 r3, r254, 0d
|
||||
ADDI64 r2, r254, 8d
|
||||
LI64 r4, 0d
|
||||
ST r4, r254, 8a, 8h
|
||||
ADDI64 r3, r254, 0d
|
||||
ST r4, r254, 0a, 8h
|
||||
ST r4, r254, 8a, 8h
|
||||
LI64 r4, 1024d
|
||||
JAL r31, r0, :set
|
||||
ANDI r1, r1, 4294967295d
|
||||
|
|
Loading…
Reference in a new issue