Fix fuzzbug related to bundle priority ordering.

Changes in computation of bundle priorities during review of the initial
PR introduced a possible mis-ordering of priorities: inner-loop bundle
use weights could exceed the weights of 1_000_000 and 2_000_000 used for
minimal bundles without and with fixed uses (respectively). These two
kinds of minimal bundle are meant to be the highest-priority bundles,
evicting any other bundle they need to, because they can't be split
further. This PR introduces two special bundle weights for these two
kinds of bundles, and clamps all other bundle weights to just below
them.

Thanks to @Amanieu for reporting the issue! Fixes #19.
This commit is contained in:
Chris Fallin
2021-11-30 14:27:35 -08:00
parent c7bc6c941c
commit c53fbb4a5c
3 changed files with 17 additions and 8 deletions

View File

@@ -13,11 +13,15 @@
//! Main allocation loop that processes bundles.
use super::{
spill_weight_from_constraint, CodeRange, Env, LiveBundleIndex, LiveBundleVec, LiveRangeFlag,
spill_weight_from_constraint, Env, LiveBundleIndex, LiveBundleVec, LiveRangeFlag,
LiveRangeIndex, LiveRangeKey, LiveRangeList, LiveRangeListEntry, PRegIndex, RegTraversalIter,
Requirement, SpillWeight, UseList,
};
use crate::{
ion::data_structures::{
CodeRange, BUNDLE_MAX_NORMAL_SPILL_WEIGHT, MINIMAL_BUNDLE_SPILL_WEIGHT,
MINIMAL_FIXED_BUNDLE_SPILL_WEIGHT,
},
Allocation, Function, Inst, InstPosition, OperandConstraint, OperandKind, PReg, ProgPoint,
RegAllocError,
};
@@ -302,11 +306,11 @@ impl<'a, F: Function> Env<'a, F> {
let spill_weight = if minimal {
if fixed {
log::trace!(" -> fixed and minimal: spill weight 2000000");
2_000_000
log::trace!(" -> fixed and minimal");
MINIMAL_FIXED_BUNDLE_SPILL_WEIGHT
} else {
log::trace!(" -> non-fixed and minimal: spill weight 1000000");
1_000_000
log::trace!(" -> non-fixed and minimal");
MINIMAL_BUNDLE_SPILL_WEIGHT
}
} else {
let mut total = SpillWeight::zero();
@@ -326,7 +330,7 @@ impl<'a, F: Function> Env<'a, F> {
self.bundles[bundle.index()].prio,
final_weight
);
final_weight
std::cmp::min(BUNDLE_MAX_NORMAL_SPILL_WEIGHT, final_weight)
} else {
0
}