unifiing annoying clobber logic

This commit is contained in:
Jakub Doka 2024-10-29 15:15:30 +01:00
parent 9cf7933251
commit da7cd5926c
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143

View file

@ -2748,14 +2748,7 @@ impl<'a> Codegen<'a> {
let mut clobbered_aliases = vec![GLOBAL_ACLASS]; let mut clobbered_aliases = vec![GLOBAL_ACLASS];
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) { self.add_clobbers(value, &mut clobbered_aliases);
clobbered_aliases.push(self.ci.nodes.aclass_index(value.id).0);
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);
@ -2768,22 +2761,7 @@ impl<'a> Codegen<'a> {
self.ci.nodes.unlock(n); self.ci.nodes.unlock(n);
} }
for &clobbered in clobbered_aliases.iter() { self.append_clobbers(&mut inps, &clobbered_aliases);
let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
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
});
}
let alt_value = match ty.loc(self.tys) { let alt_value = match ty.loc(self.tys) {
Loc::Reg => None, Loc::Reg => None,
@ -2800,16 +2778,7 @@ impl<'a> Codegen<'a> {
&mut self.ci.nodes, &mut self.ci.nodes,
); );
for &clobbered in clobbered_aliases.iter() { self.add_clobber_stores(&clobbered_aliases);
if clobbered == DEFAULT_ACLASS {
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);
}
alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty))) alt_value.or(Some(Value::new(self.ci.ctrl.get()).ty(ty)))
} }
@ -2858,15 +2827,7 @@ impl<'a> Codegen<'a> {
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));
self.add_clobbers(value, &mut clobbered_aliases);
if let Some(base) = self.tys.base_of(value.ty) {
clobbered_aliases.push(self.ci.nodes.aclass_index(value.id).0);
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);
@ -2876,22 +2837,7 @@ impl<'a> Codegen<'a> {
self.ci.nodes.unlock(n); self.ci.nodes.unlock(n);
} }
for &clobbered in clobbered_aliases.iter() { self.append_clobbers(&mut inps, &clobbered_aliases);
let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
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
});
}
let alt_value = match sig.ret.loc(self.tys) { let alt_value = match sig.ret.loc(self.tys) {
Loc::Reg => None, Loc::Reg => None,
@ -2908,16 +2854,7 @@ impl<'a> Codegen<'a> {
&mut self.ci.nodes, &mut self.ci.nodes,
); );
for &clobbered in clobbered_aliases.iter() { self.add_clobber_stores(&clobbered_aliases);
if clobbered == DEFAULT_ACLASS {
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);
}
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)))
} }
@ -3487,6 +3424,49 @@ impl<'a> Codegen<'a> {
} }
} }
fn add_clobbers(&mut self, value: Value, clobbered_aliases: &mut Vec<usize>) {
if let Some(base) = self.tys.base_of(value.ty) {
clobbered_aliases.push(self.ci.nodes.aclass_index(value.id).0);
if base.has_pointers(self.tys) {
clobbered_aliases.push(0);
}
} else if value.ty.has_pointers(self.tys) {
clobbered_aliases.push(0);
}
}
fn append_clobbers(&mut self, inps: &mut Vc, clobbered_aliases: &[usize]) {
for &clobbered in clobbered_aliases.iter() {
let aclass = &mut self.ci.scope.aclasses[clobbered];
self.ci.nodes.load_loop_aclass(clobbered, aclass, &mut self.ci.loops);
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]) {
for &clobbered in clobbered_aliases.iter() {
if clobbered == DEFAULT_ACLASS {
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);
}
}
fn struct_op( fn struct_op(
&mut self, &mut self,
pos: Pos, pos: Pos,