Cache HashSet in try_to_allocate_bundle_to_reg (#90)

Keep `conflict_set` allocated in `Env` instead of allocating a new one
on every call. This improves register allocation performance by about
2%.
This commit is contained in:
Amanieu d'Antras
2022-09-27 00:14:43 +01:00
committed by GitHub
parent 67f5c167a8
commit 227a9fde91
3 changed files with 10 additions and 3 deletions

View File

@@ -20,6 +20,7 @@ use crate::{
define_index, Allocation, Block, Edit, Function, Inst, MachineEnv, Operand, PReg, ProgPoint, define_index, Allocation, Block, Edit, Function, Inst, MachineEnv, Operand, PReg, ProgPoint,
RegClass, VReg, RegClass, VReg,
}; };
use fxhash::FxHashSet;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
@@ -430,6 +431,10 @@ pub struct Env<'a, F: Function> {
// ProgPoint to insert into the final allocated program listing. // ProgPoint to insert into the final allocated program listing.
pub debug_annotations: std::collections::HashMap<ProgPoint, Vec<String>>, pub debug_annotations: std::collections::HashMap<ProgPoint, Vec<String>>,
pub annotations_enabled: bool, pub annotations_enabled: bool,
// Cached allocation for `try_to_allocate_bundle_to_reg` to avoid allocating
// a new HashSet on every call.
pub conflict_set: FxHashSet<LiveBundleIndex>,
} }
impl<'a, F: Function> Env<'a, F> { impl<'a, F: Function> Env<'a, F> {

View File

@@ -87,6 +87,8 @@ impl<'a, F: Function> Env<'a, F> {
debug_annotations: std::collections::HashMap::new(), debug_annotations: std::collections::HashMap::new(),
annotations_enabled, annotations_enabled,
conflict_set: Default::default(),
} }
} }

View File

@@ -61,7 +61,7 @@ impl<'a, F: Function> Env<'a, F> {
) -> AllocRegResult { ) -> AllocRegResult {
trace!("try_to_allocate_bundle_to_reg: {:?} -> {:?}", bundle, reg); trace!("try_to_allocate_bundle_to_reg: {:?} -> {:?}", bundle, reg);
let mut conflicts = smallvec![]; let mut conflicts = smallvec![];
let mut conflict_set = FxHashSet::default(); self.conflict_set.clear();
let mut max_conflict_weight = 0; let mut max_conflict_weight = 0;
// Traverse the BTreeMap in order by requesting the whole // Traverse the BTreeMap in order by requesting the whole
// range spanned by the bundle and iterating over that // range spanned by the bundle and iterating over that
@@ -157,9 +157,9 @@ impl<'a, F: Function> Env<'a, F> {
// conflicts list. // conflicts list.
let conflict_bundle = self.ranges[preg_range.index()].bundle; let conflict_bundle = self.ranges[preg_range.index()].bundle;
trace!(" -> conflict bundle {:?}", conflict_bundle); trace!(" -> conflict bundle {:?}", conflict_bundle);
if !conflict_set.contains(&conflict_bundle) { if !self.conflict_set.contains(&conflict_bundle) {
conflicts.push(conflict_bundle); conflicts.push(conflict_bundle);
conflict_set.insert(conflict_bundle); self.conflict_set.insert(conflict_bundle);
max_conflict_weight = std::cmp::max( max_conflict_weight = std::cmp::max(
max_conflict_weight, max_conflict_weight,
self.bundles[conflict_bundle.index()].cached_spill_weight(), self.bundles[conflict_bundle.index()].cached_spill_weight(),