From 43c3f5a8db202f22197b7d7d2b97273e0c5eeade Mon Sep 17 00:00:00 2001 From: Mel Henning Date: Wed, 7 May 2025 17:03:29 -0400 Subject: [PATCH] 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: --- src/nouveau/compiler/nak/assign_regs.rs | 16 ++++---- src/nouveau/compiler/nak/calc_instr_deps.rs | 8 ++-- src/nouveau/compiler/nak/const_tracker.rs | 4 +- src/nouveau/compiler/nak/from_nir.rs | 14 +++---- src/nouveau/compiler/nak/legalize.rs | 10 ++--- src/nouveau/compiler/nak/liveness.rs | 14 +++---- src/nouveau/compiler/nak/lower_par_copies.rs | 4 +- src/nouveau/compiler/nak/opt_bar_prop.rs | 8 ++-- src/nouveau/compiler/nak/opt_copy_prop.rs | 4 +- src/nouveau/compiler/nak/opt_crs.rs | 5 ++- src/nouveau/compiler/nak/opt_jump_thread.rs | 5 ++- src/nouveau/compiler/nak/opt_lop.rs | 8 ++-- src/nouveau/compiler/nak/opt_prmt.rs | 6 +-- .../compiler/nak/opt_uniform_instrs.rs | 7 ++-- src/nouveau/compiler/nak/repair_ssa.rs | 9 ++-- src/nouveau/compiler/nak/sm20.rs | 7 ++-- src/nouveau/compiler/nak/sm32.rs | 9 ++-- src/nouveau/compiler/nak/sm50.rs | 8 ++-- src/nouveau/compiler/nak/sm70_encode.rs | 6 +-- src/nouveau/compiler/nak/spill_values.rs | 41 ++++++++++--------- src/nouveau/compiler/nak/to_cssa.rs | 6 +-- 21 files changed, 103 insertions(+), 96 deletions(-) diff --git a/src/nouveau/compiler/nak/assign_regs.rs b/src/nouveau/compiler/nak/assign_regs.rs index eb6877ee7c4..5c3eee9ff3c 100644 --- a/src/nouveau/compiler/nak/assign_regs.rs +++ b/src/nouveau/compiler/nak/assign_regs.rs @@ -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, + set: FxHashSet, vec: Vec, } @@ -83,7 +83,7 @@ enum SSAUse { } struct SSAUseMap { - ssa_map: HashMap>, + ssa_map: FxHashMap>, } impl SSAUseMap { @@ -165,7 +165,7 @@ impl SSAUseMap { /// Taiwan, 2011, pp. 45-54, doi: 10.1145/2038698.2038708. struct PhiWebs { uf: UnionFind, - assignments: HashMap, + assignments: FxHashMap, } impl PhiWebs { @@ -181,7 +181,7 @@ impl PhiWebs { let Some(phi_dsts) = f.blocks[b_idx].phi_dsts() else { continue; }; - let dsts: HashMap = phi_dsts + let dsts: FxHashMap = phi_dsts .dsts .iter() .map(|(idx, dst)| { @@ -263,7 +263,7 @@ struct RegAllocator { used: BitSet, pinned: BitSet, reg_ssa: Vec>, - ssa_reg: HashMap, + ssa_reg: FxHashMap, } impl RegAllocator { @@ -486,7 +486,7 @@ struct VecRegAllocator<'a> { ra: &'a mut RegAllocator, pcopy: OpParCopy, pinned: BitSet, - evicted: HashMap, + evicted: FxHashMap, } impl<'a> VecRegAllocator<'a> { @@ -922,7 +922,7 @@ struct AssignRegsBlock { ra: PerRegFile, pcopy_tmp_gprs: u8, live_in: Vec, - phi_out: HashMap, + phi_out: FxHashMap, } impl AssignRegsBlock { diff --git a/src/nouveau/compiler/nak/calc_instr_deps.rs b/src/nouveau/compiler/nak/calc_instr_deps.rs index b88938af97c..4c4c67ef558 100644 --- a/src/nouveau/compiler/nak/calc_instr_deps.rs +++ b/src/nouveau/compiler/nak/calc_instr_deps.rs @@ -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, - instr_deps: HashMap<(usize, usize), (usize, usize)>, - instr_waits: HashMap<(usize, usize), Vec>, - active: HashSet, + instr_deps: FxHashMap<(usize, usize), (usize, usize)>, + instr_waits: FxHashMap<(usize, usize), Vec>, + active: FxHashSet, } impl DepGraph { diff --git a/src/nouveau/compiler/nak/const_tracker.rs b/src/nouveau/compiler/nak/const_tracker.rs index a54ddb8a632..32735220fee 100644 --- a/src/nouveau/compiler/nak/const_tracker.rs +++ b/src/nouveau/compiler/nak/const_tracker.rs @@ -3,10 +3,10 @@ use crate::ir::*; -use std::collections::HashMap; +use rustc_hash::FxHashMap; pub struct ConstTracker { - map: HashMap, + map: FxHashMap, } /// A tracker struct for finding re-materializable constants diff --git a/src/nouveau/compiler/nak/from_nir.rs b/src/nouveau/compiler/nak/from_nir.rs index 6cc633fe3ff..76301134bd6 100644 --- a/src/nouveau/compiler/nak/from_nir.rs +++ b/src/nouveau/compiler/nak/from_nir.rs @@ -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 { 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, label_alloc: LabelAllocator, - block_label: HashMap, - bar_label: HashMap, - sync_blocks: HashSet, + block_label: FxHashMap, + bar_label: FxHashMap, + sync_blocks: FxHashSet, crs: Vec<(u32, SyncType)>, fs_out_regs: [Option; 34], end_block_id: u32, - ssa_map: HashMap>, - saturated: HashSet<*const nir_def>, + ssa_map: FxHashMap>, + saturated: FxHashSet<*const nir_def>, nir_instr_printer: NirInstrPrinter, } diff --git a/src/nouveau/compiler/nak/legalize.rs b/src/nouveau/compiler/nak/legalize.rs index dc7909e1593..c6539855e5a 100644 --- a/src/nouveau/compiler/nak/legalize.rs +++ b/src/nouveau/compiler/nak/legalize.rs @@ -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, + pinned: &FxHashSet, 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 = Default::default(); - let mut vec_comps = HashSet::new(); + let mut vec_src_map: FxHashMap = 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); diff --git a/src/nouveau/compiler/nak/liveness.rs b/src/nouveau/compiler/nak/liveness.rs index f94ee8c86f5..2ca1337fa5e 100644 --- a/src/nouveau/compiler/nak/liveness.rs +++ b/src/nouveau/compiler/nak/liveness.rs @@ -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, - set: HashSet, + set: FxHashSet, } impl LiveSet { @@ -39,7 +39,7 @@ impl LiveSet { } } - pub fn iter(&self) -> hash_set::Iter { + pub fn iter(&self) -> impl Iterator { 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, + last_use: FxHashMap, live_in: BitSet, live_out: BitSet, } @@ -277,7 +277,7 @@ impl BlockLiveness for SimpleBlockLiveness { } pub struct SimpleLiveness { - ssa_block_ip: HashMap, + ssa_block_ip: FxHashMap, blocks: Vec, } @@ -399,7 +399,7 @@ impl SSAUseDef { pub struct NextUseBlockLiveness { num_instrs: usize, - ssa_map: HashMap, + ssa_map: FxHashMap, } impl NextUseBlockLiveness { diff --git a/src/nouveau/compiler/nak/lower_par_copies.rs b/src/nouveau/compiler/nak/lower_par_copies.rs index f91aa0ede2f..49d400bf2ff 100644 --- a/src/nouveau/compiler/nak/lower_par_copies.rs +++ b/src/nouveau/compiler/nak/lower_par_copies.rs @@ -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 diff --git a/src/nouveau/compiler/nak/opt_bar_prop.rs b/src/nouveau/compiler/nak/opt_bar_prop.rs index c26e5b6208e..e630ccb84fe 100644 --- a/src/nouveau/compiler/nak/opt_bar_prop.rs +++ b/src/nouveau/compiler/nak/opt_bar_prop.rs @@ -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>, - ssa_phi: HashMap, + phi_ssa: FxHashMap>, + ssa_phi: FxHashMap, } impl PhiMap { @@ -49,7 +49,7 @@ impl PhiMap { } struct BarPropPass { - ssa_map: HashMap, + ssa_map: FxHashMap, phi_is_bar: BitSet, phi_is_not_bar: BitSet, } diff --git a/src/nouveau/compiler/nak/opt_copy_prop.rs b/src/nouveau/compiler/nak/opt_copy_prop.rs index 80917192cac..82d894cdf4a 100644 --- a/src/nouveau/compiler/nak/opt_copy_prop.rs +++ b/src/nouveau/compiler/nak/opt_copy_prop.rs @@ -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, + ssa_map: FxHashMap, } impl<'a> CopyPropPass<'a> { diff --git a/src/nouveau/compiler/nak/opt_crs.rs b/src/nouveau/compiler/nak/opt_crs.rs index d1d579faa4f..d9cc3ef37c6 100644 --- a/src/nouveau/compiler/nak/opt_crs.rs +++ b/src/nouveau/compiler/nak/opt_crs.rs @@ -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