regalloc bug: mark locals as used when value already has locals, e.g. for function param

This commit is contained in:
Chris Fallin 2022-11-30 00:07:32 -08:00
parent 52db5b4a4e
commit 92a7486bf3
No known key found for this signature in database
GPG key ID: 31649E4FE65EB465

View file

@ -137,6 +137,10 @@ impl<'a> Context<'a> {
// If there is already an allocation (e.g. for a // If there is already an allocation (e.g. for a
// function parameter), return. // function parameter), return.
if !results.values[u].is_empty() { if !results.values[u].is_empty() {
// Ensure the local(s) are marked as live.
for &local in &results.values[u] {
live_locals.insert(local);
}
return; return;
} }
@ -170,10 +174,17 @@ impl<'a> Context<'a> {
.tys() .tys()
.iter() .iter()
.map(|&ty| { .map(|&ty| {
log::trace!(
"looking for location for {} can_reuse {} with live_locals {:?}",
u,
can_reuse,
live_locals,
);
let reused = if can_reuse { let reused = if can_reuse {
// Try to find a local of the right type that is not live. // Try to find a local of the right type that is not live.
let affinities = let affinities =
affinities.get(&u).map(|v| &v[..]).unwrap_or(&[]); affinities.get(&u).map(|v| &v[..]).unwrap_or(&[]);
log::trace!(" -> affinities: {:?}", affinities);
let mut try_list = affinities let mut try_list = affinities
.iter() .iter()
.filter_map(|&aff_val| { .filter_map(|&aff_val| {
@ -189,16 +200,23 @@ impl<'a> Context<'a> {
try_list try_list
.find(|&(local, local_ty)| { .find(|&(local, local_ty)| {
log::trace!(
" -> considering {} ty {:?}",
local,
local_ty
);
local_ty == ty && live_locals.insert(local) local_ty == ty && live_locals.insert(local)
}) })
.map(|(local, _)| local) .map(|(local, _)| local)
} else { } else {
None None
}; };
log::trace!(" -> reused: {:?}", reused);
reused.unwrap_or_else(|| { reused.unwrap_or_else(|| {
let local = results.locals.push(ty); let local = results.locals.push(ty);
live_locals.insert(local); live_locals.insert(local);
log::trace!(" -> new allocation: {}", local);
local local
}) })
}) })