nak: Switch most Hash{Set,Map} uses to rustc-hash

We shouldn't need to worry about HashDoS attacks because:
 1. All of these keys are compiler-assigned IDs which makes it very
    difficult to force collitions, and
 2. Anyone who can hit the NAK compiler backend can already use CPU
    power by spamming shader compiles or using O(n^2) behavior in
    shader opt loops
As a result, we can afford to use a weaker hash function without
randomization.

This decreases total compile times by around 12% on shaderdb
(from 8113.74 user to 7115.47 user) on my machine.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34865>
This commit is contained in:
Mel Henning
2025-05-07 17:03:29 -04:00
committed by Marge Bot
parent c1f979d84a
commit 43c3f5a8db
21 changed files with 103 additions and 96 deletions
+8 -8
View File
@@ -7,11 +7,11 @@ use crate::liveness::{BlockLiveness, Liveness, SimpleLiveness};
use crate::union_find::UnionFind;
use compiler::bitset::BitSet;
use rustc_hash::{FxHashMap, FxHashSet};
use std::cmp::{max, min, Ordering};
use std::collections::{HashMap, HashSet};
struct KillSet {
set: HashSet<SSAValue>,
set: FxHashSet<SSAValue>,
vec: Vec<SSAValue>,
}
@@ -83,7 +83,7 @@ enum SSAUse {
}
struct SSAUseMap {
ssa_map: HashMap<SSAValue, Vec<(usize, SSAUse)>>,
ssa_map: FxHashMap<SSAValue, Vec<(usize, SSAUse)>>,
}
impl SSAUseMap {
@@ -165,7 +165,7 @@ impl SSAUseMap {
/// Taiwan, 2011, pp. 45-54, doi: 10.1145/2038698.2038708.
struct PhiWebs {
uf: UnionFind<SSAValue>,
assignments: HashMap<SSAValue, u32>,
assignments: FxHashMap<SSAValue, u32>,
}
impl PhiWebs {
@@ -181,7 +181,7 @@ impl PhiWebs {
let Some(phi_dsts) = f.blocks[b_idx].phi_dsts() else {
continue;
};
let dsts: HashMap<u32, &SSARef> = phi_dsts
let dsts: FxHashMap<u32, &SSARef> = phi_dsts
.dsts
.iter()
.map(|(idx, dst)| {
@@ -263,7 +263,7 @@ struct RegAllocator {
used: BitSet,
pinned: BitSet,
reg_ssa: Vec<Option<SSAValue>>,
ssa_reg: HashMap<SSAValue, u32>,
ssa_reg: FxHashMap<SSAValue, u32>,
}
impl RegAllocator {
@@ -486,7 +486,7 @@ struct VecRegAllocator<'a> {
ra: &'a mut RegAllocator,
pcopy: OpParCopy,
pinned: BitSet,
evicted: HashMap<SSAValue, u32>,
evicted: FxHashMap<SSAValue, u32>,
}
impl<'a> VecRegAllocator<'a> {
@@ -922,7 +922,7 @@ struct AssignRegsBlock {
ra: PerRegFile<RegAllocator>,
pcopy_tmp_gprs: u8,
live_in: Vec<LiveValue>,
phi_out: HashMap<u32, SrcRef>,
phi_out: FxHashMap<u32, SrcRef>,
}
impl AssignRegsBlock {
+4 -4
View File
@@ -5,8 +5,8 @@ use crate::api::{GetDebugFlags, DEBUG};
use crate::ir::*;
use crate::reg_tracker::RegTracker;
use rustc_hash::{FxHashMap, FxHashSet};
use std::cmp::max;
use std::collections::{HashMap, HashSet};
use std::slice;
#[derive(Clone)]
@@ -65,9 +65,9 @@ struct DepNode {
struct DepGraph {
deps: Vec<DepNode>,
instr_deps: HashMap<(usize, usize), (usize, usize)>,
instr_waits: HashMap<(usize, usize), Vec<usize>>,
active: HashSet<usize>,
instr_deps: FxHashMap<(usize, usize), (usize, usize)>,
instr_waits: FxHashMap<(usize, usize), Vec<usize>>,
active: FxHashSet<usize>,
}
impl DepGraph {
+2 -2
View File
@@ -3,10 +3,10 @@
use crate::ir::*;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
pub struct ConstTracker {
map: HashMap<SSAValue, SrcRef>,
map: FxHashMap<SSAValue, SrcRef>,
}
/// A tracker struct for finding re-materializable constants
+7 -7
View File
@@ -15,8 +15,8 @@ use compiler::bindings::*;
use compiler::cfg::CFGBuilder;
use compiler::nir::*;
use compiler::nir_instr_printer::NirInstrPrinter;
use rustc_hash::{FxHashMap, FxHashSet};
use std::cmp::max;
use std::collections::{HashMap, HashSet};
use std::ops::Index;
fn init_info_from_nir(nak: &nak_compiler, nir: &nir_shader) -> ShaderInfo {
@@ -192,7 +192,7 @@ fn alloc_ssa_for_nir(b: &mut impl SSABuilder, ssa: &nir_def) -> Vec<SSAValue> {
struct PhiAllocMap<'a> {
alloc: &'a mut PhiAllocator,
map: HashMap<(u32, u8), u32>,
map: FxHashMap<(u32, u8), u32>,
}
impl<'a> PhiAllocMap<'a> {
@@ -321,14 +321,14 @@ struct ShaderFromNir<'a> {
float_ctl: ShaderFloatControls,
cfg: CFGBuilder<u32, BasicBlock>,
label_alloc: LabelAllocator,
block_label: HashMap<u32, Label>,
bar_label: HashMap<u32, Label>,
sync_blocks: HashSet<u32>,
block_label: FxHashMap<u32, Label>,
bar_label: FxHashMap<u32, Label>,
sync_blocks: FxHashSet<u32>,
crs: Vec<(u32, SyncType)>,
fs_out_regs: [Option<SSAValue>; 34],
end_block_id: u32,
ssa_map: HashMap<u32, Vec<SSAValue>>,
saturated: HashSet<*const nir_def>,
ssa_map: FxHashMap<u32, Vec<SSAValue>>,
saturated: FxHashSet<*const nir_def>,
nir_instr_printer: NirInstrPrinter,
}
+5 -5
View File
@@ -5,7 +5,7 @@ use crate::api::{GetDebugFlags, DEBUG};
use crate::ir::*;
use crate::liveness::{BlockLiveness, Liveness, SimpleLiveness};
use std::collections::{HashMap, HashSet};
use rustc_hash::{FxHashMap, FxHashSet};
pub type LegalizeBuilder<'a> = SSAInstrBuilder<'a>;
@@ -345,7 +345,7 @@ fn legalize_instr(
b: &mut LegalizeBuilder,
bl: &impl BlockLiveness,
block_uniform: bool,
pinned: &HashSet<SSARef>,
pinned: &FxHashSet<SSARef>,
ip: usize,
instr: &mut Instr,
) {
@@ -439,8 +439,8 @@ fn legalize_instr(
sm.legalize_op(b, &mut instr.op);
let mut vec_src_map: HashMap<SSARef, SSARef> = Default::default();
let mut vec_comps = HashSet::new();
let mut vec_src_map: FxHashMap<SSARef, SSARef> = Default::default();
let mut vec_comps: FxHashSet<_> = Default::default();
for src in instr.srcs_mut() {
if let SrcRef::SSA(vec) = &src.src_ref {
if vec.comps() == 1 {
@@ -482,7 +482,7 @@ impl Shader<'_> {
let sm = self.sm;
for f in &mut self.functions {
let live = SimpleLiveness::for_function(f);
let mut pinned = HashSet::new();
let mut pinned: FxHashSet<_> = Default::default();
for (bi, b) in f.blocks.iter_mut().enumerate() {
let bl = live.block_live(bi);
+7 -7
View File
@@ -4,14 +4,14 @@
use crate::ir::*;
use compiler::bitset::BitSet;
use rustc_hash::{FxHashMap, FxHashSet};
use std::cell::RefCell;
use std::cmp::{max, Ord, Ordering};
use std::collections::{hash_set, HashMap, HashSet};
#[derive(Clone)]
pub struct LiveSet {
live: PerRegFile<u32>,
set: HashSet<SSAValue>,
set: FxHashSet<SSAValue>,
}
impl LiveSet {
@@ -39,7 +39,7 @@ impl LiveSet {
}
}
pub fn iter(&self) -> hash_set::Iter<SSAValue> {
pub fn iter(&self) -> impl Iterator<Item = &SSAValue> {
self.set.iter()
}
@@ -151,7 +151,7 @@ pub trait BlockLiveness {
let vec_dst_live = live;
// Use a hash set because sources may occur more than once
let mut killed = HashSet::new();
let mut killed: FxHashSet<_> = Default::default();
instr.for_each_ssa_use(|ssa| {
if !self.is_live_after_ip(ssa, ip) {
killed.insert(*ssa);
@@ -230,7 +230,7 @@ pub trait Liveness {
pub struct SimpleBlockLiveness {
defs: BitSet,
uses: BitSet,
last_use: HashMap<u32, usize>,
last_use: FxHashMap<u32, usize>,
live_in: BitSet,
live_out: BitSet,
}
@@ -277,7 +277,7 @@ impl BlockLiveness for SimpleBlockLiveness {
}
pub struct SimpleLiveness {
ssa_block_ip: HashMap<SSAValue, (usize, usize)>,
ssa_block_ip: FxHashMap<SSAValue, (usize, usize)>,
blocks: Vec<SimpleBlockLiveness>,
}
@@ -399,7 +399,7 @@ impl SSAUseDef {
pub struct NextUseBlockLiveness {
num_instrs: usize,
ssa_map: HashMap<SSAValue, SSAUseDef>,
ssa_map: FxHashMap<SSAValue, SSAUseDef>,
}
impl NextUseBlockLiveness {
+2 -2
View File
@@ -6,7 +6,7 @@ use crate::{
ir::*,
};
use std::collections::HashMap;
use rustc_hash::FxHashMap;
struct CopyNode {
num_reads: usize,
@@ -93,7 +93,7 @@ fn cycle_use_swap(pc: &OpParCopy, file: RegFile) -> bool {
fn lower_par_copy(pc: OpParCopy, sm: &dyn ShaderModel) -> MappedInstrs {
let mut graph = CopyGraph::new();
let mut vals = Vec::new();
let mut reg_to_idx = HashMap::new();
let mut reg_to_idx = FxHashMap::default();
for (i, (dst, _)) in pc.dsts_srcs.iter().enumerate() {
// Destinations must be pairwise unique
+4 -4
View File
@@ -5,11 +5,11 @@ use crate::api::{GetDebugFlags, DEBUG};
use crate::ir::*;
use compiler::bitset::BitSet;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
struct PhiMap {
phi_ssa: HashMap<u32, Vec<SSAValue>>,
ssa_phi: HashMap<SSAValue, u32>,
phi_ssa: FxHashMap<u32, Vec<SSAValue>>,
ssa_phi: FxHashMap<SSAValue, u32>,
}
impl PhiMap {
@@ -49,7 +49,7 @@ impl PhiMap {
}
struct BarPropPass {
ssa_map: HashMap<SSAValue, SSAValue>,
ssa_map: FxHashMap<SSAValue, SSAValue>,
phi_is_bar: BitSet,
phi_is_not_bar: BitSet,
}
+2 -2
View File
@@ -3,7 +3,7 @@
use crate::ir::*;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
enum CBufRule {
Yes,
@@ -61,7 +61,7 @@ enum CopyPropEntry {
struct CopyPropPass<'a> {
sm: &'a dyn ShaderModel,
ssa_map: HashMap<SSAValue, CopyPropEntry>,
ssa_map: FxHashMap<SSAValue, CopyPropEntry>,
}
impl<'a> CopyPropPass<'a> {
+3 -2
View File
@@ -2,10 +2,11 @@
// SPDX-License-Identifier: MIT
use crate::ir::*;
use std::collections::HashSet;
use rustc_hash::FxHashSet;
fn opt_crs(f: &mut Function) {
let mut live_targets = HashSet::new();
let mut live_targets: FxHashSet<Label> = Default::default();
for b in f.blocks.iter() {
let Some(instr) = b.instrs.last() else {
continue;
+3 -2
View File
@@ -2,8 +2,9 @@
// SPDX-License-Identifier: MIT
use crate::ir::*;
use compiler::cfg::CFGBuilder;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
fn clone_branch(op: &Op) -> Op {
match op {
@@ -31,7 +32,7 @@ fn jump_thread(func: &mut Function) -> bool {
let mut progress = false;
// A branch to label can be replaced with Op
let mut replacements: HashMap<Label, Op> = Default::default();
let mut replacements: FxHashMap<Label, Op> = Default::default();
// Invariant 1: At the end of each loop iteration,
// every trivial block with an index in [i, blocks.len())
+4 -4
View File
@@ -3,7 +3,7 @@
use crate::ir::*;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use std::slice;
struct LopEntry {
@@ -13,8 +13,8 @@ struct LopEntry {
}
struct LopPass {
use_counts: HashMap<SSAValue, u32>,
ssa_lop: HashMap<SSAValue, LopEntry>,
use_counts: FxHashMap<SSAValue, u32>,
ssa_lop: FxHashMap<SSAValue, LopEntry>,
}
fn src_as_bool(src: &Src) -> Option<bool> {
@@ -28,7 +28,7 @@ fn src_as_bool(src: &Src) -> Option<bool> {
impl LopPass {
fn new(f: &Function) -> LopPass {
let mut use_counts = HashMap::new();
let mut use_counts = FxHashMap::default();
for b in &f.blocks {
for instr in &b.instrs {
if let PredRef::SSA(ssa) = instr.pred.pred_ref {
+3 -3
View File
@@ -3,10 +3,10 @@
* SPDX-License-Identifier: MIT
*/
use std::collections::HashMap;
use crate::ir::*;
use rustc_hash::FxHashMap;
struct PrmtSrcs {
srcs: [SrcRef; 2],
num_srcs: usize,
@@ -82,7 +82,7 @@ struct PrmtEntry {
}
struct PrmtPass {
ssa_prmt: HashMap<SSAValue, PrmtEntry>,
ssa_prmt: FxHashMap<SSAValue, PrmtEntry>,
}
impl PrmtPass {
@@ -2,12 +2,13 @@
// SPDX-License-Identifier: MIT
use crate::ir::*;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
fn should_lower_to_warp(
sm: &dyn ShaderModel,
instr: &Instr,
r2ur: &HashMap<SSAValue, SSAValue>,
r2ur: &FxHashMap<SSAValue, SSAValue>,
) -> bool {
if !sm.op_can_be_uniform(&instr.op) {
return true;
@@ -25,7 +26,7 @@ fn should_lower_to_warp(
fn propagate_r2ur(
instr: &mut Instr,
r2ur: &HashMap<SSAValue, SSAValue>,
r2ur: &FxHashMap<SSAValue, SSAValue>,
) -> bool {
let mut progress = false;
+5 -4
View File
@@ -5,21 +5,22 @@ use crate::ir::*;
use crate::union_find::UnionFind;
use compiler::bitset::BitSet;
use rustc_hash::FxHashMap;
use std::cell::RefCell;
use std::cmp::Reverse;
use std::collections::{BinaryHeap, HashMap};
use std::collections::BinaryHeap;
struct Phi {
idx: u32,
orig: SSAValue,
dst: SSAValue,
srcs: HashMap<usize, SSAValue>,
srcs: FxHashMap<usize, SSAValue>,
}
struct DefTrackerBlock {
pred: Vec<usize>,
succ: Vec<usize>,
defs: RefCell<HashMap<SSAValue, SSAValue>>,
defs: RefCell<FxHashMap<SSAValue, SSAValue>>,
phis: RefCell<Vec<Phi>>,
}
@@ -161,7 +162,7 @@ impl Function {
// us to skip any SSA values which only have a single definition in
// later passes.
let mut has_mult_defs = false;
let mut num_defs = HashMap::new();
let mut num_defs = FxHashMap::default();
for b in &self.blocks {
for instr in &b.instrs {
instr.for_each_ssa_def(|ssa| {
+4 -3
View File
@@ -10,8 +10,9 @@ use bitview::{
SetFieldU64,
};
use rustc_hash::FxHashMap;
use std::fmt;
use std::{collections::HashMap, ops::Range};
use std::ops::Range;
pub struct ShaderModel20 {
sm: u8,
@@ -191,7 +192,7 @@ trait SM20Op {
struct SM20Encoder<'a> {
sm: &'a ShaderModel20,
ip: usize,
labels: &'a HashMap<Label, usize>,
labels: &'a FxHashMap<Label, usize>,
inst: [u32; 2],
}
@@ -2691,7 +2692,7 @@ fn encode_sm20_shader(sm: &ShaderModel20, s: &Shader<'_>) -> Vec<u32> {
let func = &s.functions[0];
let mut ip = 0_usize;
let mut labels = HashMap::new();
let mut labels = FxHashMap::default();
for b in &func.blocks {
// We ensure blocks will have groups of 7 instructions with a
// schedule instruction before each groups. As we should never jump
+5 -4
View File
@@ -10,7 +10,8 @@ use bitview::{
SetFieldU64,
};
use std::{collections::HashMap, ops::Range};
use rustc_hash::FxHashMap;
use std::ops::Range;
pub struct ShaderModel32 {
sm: u8,
@@ -154,7 +155,7 @@ fn true_reg() -> RegRef {
struct SM32Encoder<'a> {
sm: &'a ShaderModel32,
ip: usize,
labels: &'a HashMap<Label, usize>,
labels: &'a FxHashMap<Label, usize>,
inst: [u32; 2],
sched: u8,
}
@@ -3056,7 +3057,7 @@ fn as_sm32_op_mut(op: &mut Op) -> &mut dyn SM32Op {
fn encode_instr(
instr: Option<&Box<Instr>>,
sm: &ShaderModel32,
labels: &HashMap<Label, usize>,
labels: &FxHashMap<Label, usize>,
encoded: &mut Vec<u32>,
) -> u8 {
let mut e = SM32Encoder {
@@ -3088,7 +3089,7 @@ fn encode_sm32_shader(sm: &ShaderModel32, s: &Shader<'_>) -> Vec<u32> {
let func = &s.functions[0];
let mut ip = 0_usize;
let mut labels = HashMap::new();
let mut labels = FxHashMap::default();
for b in &func.blocks {
// We ensure blocks will have groups of 7 instructions with a
// schedule instruction before each groups. As we should never jump
+4 -4
View File
@@ -7,7 +7,7 @@ use crate::legalize::{
};
use bitview::*;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use std::ops::Range;
pub fn instr_latency(_sm: u8, op: &Op, dst_idx: usize) -> u32 {
@@ -179,7 +179,7 @@ trait SM50Op {
struct SM50Encoder<'a> {
sm: &'a ShaderModel50,
ip: usize,
labels: &'a HashMap<Label, usize>,
labels: &'a FxHashMap<Label, usize>,
inst: [u32; 2],
sched: u32,
}
@@ -3349,7 +3349,7 @@ fn encode_instr(
instr_index: usize,
instr: Option<&Box<Instr>>,
sm: &ShaderModel50,
labels: &HashMap<Label, usize>,
labels: &FxHashMap<Label, usize>,
ip: &mut usize,
sched_instr: &mut [u32; 2],
) -> [u32; 2] {
@@ -3385,7 +3385,7 @@ fn encode_sm50_shader(sm: &ShaderModel50, s: &Shader<'_>) -> Vec<u32> {
let func = &s.functions[0];
let mut num_instrs = 0_usize;
let mut labels = HashMap::new();
let mut labels = FxHashMap::default();
for b in &func.blocks {
// We ensure blocks will have groups of 3 instructions with a
// schedule instruction before each groups. As we should never jump
+3 -3
View File
@@ -8,7 +8,7 @@ use crate::legalize::{
};
use bitview::*;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use std::ops::Range;
/// A per-op trait that implements Volta+ opcode semantics
@@ -20,7 +20,7 @@ trait SM70Op {
struct SM70Encoder<'a> {
sm: u8,
ip: usize,
labels: &'a HashMap<Label, usize>,
labels: &'a FxHashMap<Label, usize>,
inst: [u32; 4],
}
@@ -3778,7 +3778,7 @@ pub fn encode_sm70_shader(sm: &dyn ShaderModel, s: &Shader<'_>) -> Vec<u32> {
let func = &s.functions[0];
let mut ip = 0_usize;
let mut labels = HashMap::new();
let mut labels = FxHashMap::default();
for b in &func.blocks {
labels.insert(b.label, ip);
for instr in &b.instrs {
+21 -20
View File
@@ -9,12 +9,13 @@ use crate::liveness::{
};
use compiler::bitset::BitSet;
use rustc_hash::{FxHashMap, FxHashSet};
use std::cell::RefCell;
use std::cmp::{max, Ordering, Reverse};
use std::collections::{BinaryHeap, HashMap, HashSet};
use std::collections::BinaryHeap;
struct PhiDstMap {
ssa_phi: HashMap<SSAValue, u32>,
ssa_phi: FxHashMap<SSAValue, u32>,
}
impl PhiDstMap {
@@ -46,7 +47,7 @@ impl PhiDstMap {
}
struct PhiSrcMap {
phi_src: HashMap<u32, SSAValue>,
phi_src: FxHashMap<u32, SSAValue>,
}
impl PhiSrcMap {
@@ -283,7 +284,7 @@ struct SpillCache<'a, S: Spill> {
alloc: &'a mut SSAValueAllocator,
spill: S,
const_tracker: ConstTracker,
val_spill: HashMap<SSAValue, SSAValue>,
val_spill: FxHashMap<SSAValue, SSAValue>,
}
impl<'a, S: Spill> SpillCache<'a, S> {
@@ -346,7 +347,7 @@ impl<'a, S: Spill> SpillCache<'a, S> {
struct SpillChooser<'a> {
bl: &'a NextUseBlockLiveness,
pinned: &'a HashSet<SSAValue>,
pinned: &'a FxHashSet<SSAValue>,
ip: usize,
count: usize,
spills: BinaryHeap<Reverse<SSANextUse>>,
@@ -360,7 +361,7 @@ struct SpillChoiceIter {
impl<'a> SpillChooser<'a> {
pub fn new(
bl: &'a NextUseBlockLiveness,
pinned: &'a HashSet<SSAValue>,
pinned: &'a FxHashSet<SSAValue>,
ip: usize,
count: usize,
) -> Self {
@@ -429,9 +430,9 @@ struct SSAState {
w: LiveSet,
// The set of variables which have already been spilled. These don't need
// to be spilled again.
s: HashSet<SSAValue>,
s: FxHashSet<SSAValue>,
// The set of pinned variables
p: HashSet<SSAValue>,
p: FxHashSet<SSAValue>,
}
fn spill_values<S: Spill>(
@@ -447,7 +448,7 @@ fn spill_values<S: Spill>(
// Record the set of SSA values used within each loop
let mut phi_dst_maps = Vec::new();
let mut phi_src_maps = Vec::new();
let mut loop_uses = HashMap::new();
let mut loop_uses = FxHashMap::default();
for b_idx in 0..blocks.len() {
phi_dst_maps.push(PhiDstMap::from_block(&blocks[b_idx]));
phi_src_maps.push(PhiSrcMap::from_block(&blocks[b_idx]));
@@ -455,8 +456,8 @@ fn spill_values<S: Spill>(
if let Some(lh_idx) = blocks.loop_header_index(b_idx) {
let uses = loop_uses
.entry(lh_idx)
.or_insert_with(|| RefCell::new(HashSet::new()));
let uses = uses.get_mut();
.or_insert_with(|| RefCell::new(Default::default()));
let uses: &mut FxHashSet<_> = uses.get_mut();
for instr in &blocks[b_idx].instrs {
instr.for_each_ssa_use(|ssa| {
@@ -533,8 +534,8 @@ fn spill_values<S: Spill>(
debug_assert!(w.count(file) <= limit);
w
} else if blocks.is_loop_header(b_idx) {
let mut i_b: HashSet<SSAValue> =
HashSet::from_iter(bl.iter_live_in().cloned());
let mut i_b: FxHashSet<SSAValue> =
FxHashSet::from_iter(bl.iter_live_in().cloned());
if let Some(phi) = blocks[b_idx].phi_dsts() {
for (_, dst) in phi.dsts.iter() {
@@ -592,7 +593,7 @@ fn spill_values<S: Spill>(
num_preds: usize,
next_use: usize,
}
let mut live: HashMap<SSAValue, SSAPredInfo> = Default::default();
let mut live: FxHashMap<SSAValue, SSAPredInfo> = Default::default();
for p_idx in &preds {
let phi_src_map = &phi_src_maps[*p_idx];
@@ -637,14 +638,14 @@ fn spill_values<S: Spill>(
};
let s = if preds.is_empty() {
HashSet::new()
Default::default()
} else if preds.len() == 1 {
let p_s = &ssa_state_out[preds[0]].s;
HashSet::from_iter(
FxHashSet::from_iter(
p_s.iter().filter(|ssa| bl.is_live_in(ssa)).cloned(),
)
} else {
let mut s = HashSet::new();
let mut s: FxHashSet<_> = Default::default();
for p_idx in &preds {
if *p_idx >= b_idx {
continue;
@@ -676,7 +677,7 @@ fn spill_values<S: Spill>(
s
};
let mut p = HashSet::new();
let mut p: FxHashSet<_> = Default::default();
for p_idx in &preds {
if *p_idx < b_idx {
let p_p = &ssa_state_out[*p_idx].p;
@@ -786,8 +787,8 @@ fn spill_values<S: Spill>(
}
}
let spills: HashSet<SSAValue> =
HashSet::from_iter(spills);
let spills: FxHashSet<SSAValue> =
FxHashSet::from_iter(spills);
for (dst, src) in pcopy.dsts_srcs.iter_mut() {
let dst_ssa = &dst.as_ssa().unwrap()[0];
+3 -3
View File
@@ -6,7 +6,7 @@ use crate::ir::*;
use crate::liveness::{BlockLiveness, Liveness, SimpleLiveness};
use compiler::cfg::CFG;
use std::collections::HashMap;
use rustc_hash::FxHashMap;
use std::iter::Peekable;
struct MergedIter<I: Iterator> {
@@ -72,8 +72,8 @@ struct CoalesceGraph<'a> {
live: &'a SimpleLiveness,
nodes: Vec<CoalesceNode>,
sets: Vec<CoalesceSet>,
ssa_node: HashMap<SSAValue, usize>,
phi_node_file: HashMap<u32, (usize, RegFile)>,
ssa_node: FxHashMap<SSAValue, usize>,
phi_node_file: FxHashMap<u32, (usize, RegFile)>,
}
impl<'a> CoalesceGraph<'a> {