Fuzzbug fix re: new requirements computation and multi-fixed-reg fixup.
This commit is contained in:
@@ -946,21 +946,26 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
}));
|
}));
|
||||||
let weight = spill_weight_from_policy(policy, is_hot, operand.kind() != OperandKind::Use);
|
let weight = spill_weight_from_policy(policy, is_hot, operand.kind() != OperandKind::Use);
|
||||||
u.weight = u16::try_from(weight).expect("weight too large for u16 field");
|
u.weight = u16::try_from(weight).expect("weight too large for u16 field");
|
||||||
|
let req = Requirement::from_operand(u.operand);
|
||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"insert use {:?} into lr {:?} with weight {}",
|
"insert use {:?} into lr {:?} with weight {} req {:?}",
|
||||||
u,
|
u,
|
||||||
into,
|
into,
|
||||||
weight,
|
weight,
|
||||||
|
req,
|
||||||
);
|
);
|
||||||
|
|
||||||
let req = Requirement::from_operand(u.operand);
|
|
||||||
self.ranges[into.index()].uses.push(u);
|
self.ranges[into.index()].uses.push(u);
|
||||||
self.ranges[into.index()].requirement = self.ranges[into.index()].requirement.merge(req);
|
self.ranges[into.index()].requirement = self.ranges[into.index()].requirement.merge(req);
|
||||||
|
|
||||||
// Update stats.
|
// Update stats.
|
||||||
self.ranges[into.index()].uses_spill_weight_and_flags += weight;
|
self.ranges[into.index()].uses_spill_weight_and_flags += weight;
|
||||||
log::debug!(" -> now {}", self.ranges[into.index()].uses_spill_weight());
|
log::debug!(
|
||||||
|
" -> now range has weight {} req {:?}",
|
||||||
|
self.ranges[into.index()].uses_spill_weight(),
|
||||||
|
self.ranges[into.index()].requirement
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_vreg_liverange_for_pos(
|
fn find_vreg_liverange_for_pos(
|
||||||
@@ -1904,6 +1909,7 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut req = Requirement::Unknown;
|
||||||
for u in &mut self.ranges[range.index()].uses {
|
for u in &mut self.ranges[range.index()].uses {
|
||||||
let pos = u.pos;
|
let pos = u.pos;
|
||||||
let slot = u.slot as usize;
|
let slot = u.slot as usize;
|
||||||
@@ -1913,7 +1919,9 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
&mut u.operand,
|
&mut u.operand,
|
||||||
&mut self.multi_fixed_reg_fixups,
|
&mut self.multi_fixed_reg_fixups,
|
||||||
);
|
);
|
||||||
|
req = req.merge(Requirement::from_operand(u.operand));
|
||||||
}
|
}
|
||||||
|
self.ranges[range.index()].requirement = req;
|
||||||
|
|
||||||
for &(clobber, inst) in &extra_clobbers {
|
for &(clobber, inst) in &extra_clobbers {
|
||||||
let range = CodeRange {
|
let range = CodeRange {
|
||||||
@@ -2407,9 +2415,10 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
log::debug!("Bundles:");
|
log::debug!("Bundles:");
|
||||||
for (i, b) in self.bundles.iter().enumerate() {
|
for (i, b) in self.bundles.iter().enumerate() {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"bundle{}: spillset={:?} alloc={:?}",
|
"bundle{}: spillset={:?} req={:?} alloc={:?}",
|
||||||
i,
|
i,
|
||||||
b.spillset,
|
b.spillset,
|
||||||
|
b.requirement,
|
||||||
b.allocation
|
b.allocation
|
||||||
);
|
);
|
||||||
for entry in &b.ranges {
|
for entry in &b.ranges {
|
||||||
@@ -2436,11 +2445,12 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
log::debug!("Ranges:");
|
log::debug!("Ranges:");
|
||||||
for (i, r) in self.ranges.iter().enumerate() {
|
for (i, r) in self.ranges.iter().enumerate() {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
concat!("range{}: range={:?} vreg={:?} bundle={:?} ", "weight={}"),
|
"range{}: range={:?} vreg={:?} bundle={:?} req={:?} weight={}",
|
||||||
i,
|
i,
|
||||||
r.range,
|
r.range,
|
||||||
r.vreg,
|
r.vreg,
|
||||||
r.bundle,
|
r.bundle,
|
||||||
|
r.requirement,
|
||||||
r.uses_spill_weight(),
|
r.uses_spill_weight(),
|
||||||
);
|
);
|
||||||
for u in &r.uses {
|
for u in &r.uses {
|
||||||
@@ -2449,26 +2459,6 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_requirement(&self, bundle: LiveBundleIndex) -> Requirement {
|
|
||||||
log::debug!("compute_requirement: bundle {:?}", bundle);
|
|
||||||
|
|
||||||
let mut needed = Requirement::Unknown;
|
|
||||||
for entry in &self.bundles[bundle.index()].ranges {
|
|
||||||
let range = &self.ranges[entry.index.index()];
|
|
||||||
log::debug!(
|
|
||||||
" -> range LR {} ({:?}): {:?}",
|
|
||||||
entry.index.index(),
|
|
||||||
entry.index,
|
|
||||||
entry.range
|
|
||||||
);
|
|
||||||
needed = needed.merge(range.requirement);
|
|
||||||
log::debug!(" -> needed {:?}", needed);
|
|
||||||
}
|
|
||||||
|
|
||||||
log::debug!(" -> final needed: {:?}", needed);
|
|
||||||
needed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_to_allocate_bundle_to_reg(
|
fn try_to_allocate_bundle_to_reg(
|
||||||
&mut self,
|
&mut self,
|
||||||
bundle: LiveBundleIndex,
|
bundle: LiveBundleIndex,
|
||||||
@@ -2713,8 +2703,10 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
let mut req = Requirement::Unknown;
|
let mut req = Requirement::Unknown;
|
||||||
for u in &rangedata.uses {
|
for u in &rangedata.uses {
|
||||||
w += u.weight as u32;
|
w += u.weight as u32;
|
||||||
|
log::debug!("range{}: use {:?}", range.index(), u);
|
||||||
req = req.merge(Requirement::from_operand(u.operand));
|
req = req.merge(Requirement::from_operand(u.operand));
|
||||||
}
|
}
|
||||||
|
log::debug!("range{}: recomputed req = {:?}", range.index(), req);
|
||||||
rangedata.uses_spill_weight_and_flags = w;
|
rangedata.uses_spill_weight_and_flags = w;
|
||||||
rangedata.requirement = req;
|
rangedata.requirement = req;
|
||||||
if rangedata.uses.len() > 0 && rangedata.uses[0].operand.kind() == OperandKind::Def {
|
if rangedata.uses.len() > 0 && rangedata.uses[0].operand.kind() == OperandKind::Def {
|
||||||
@@ -2916,9 +2908,10 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
bundle: LiveBundleIndex,
|
bundle: LiveBundleIndex,
|
||||||
reg_hint: PReg,
|
reg_hint: PReg,
|
||||||
) -> Result<(), RegAllocError> {
|
) -> Result<(), RegAllocError> {
|
||||||
// Find any requirements: for every LR, for every def/use, gather
|
// The requirement is kept up-to-date as bundles are merged
|
||||||
// requirements (fixed-reg, any-reg, any) and merge them.
|
// and split, and indicates what sort of allocation we need.
|
||||||
let req = self.compute_requirement(bundle);
|
let req = self.bundles[bundle.index()].requirement;
|
||||||
|
|
||||||
// Grab a hint from either the queue or our spillset, if any.
|
// Grab a hint from either the queue or our spillset, if any.
|
||||||
let hint_reg = if reg_hint != PReg::invalid() {
|
let hint_reg = if reg_hint != PReg::invalid() {
|
||||||
reg_hint
|
reg_hint
|
||||||
|
|||||||
Reference in New Issue
Block a user