nak: Fix delay insertion missing WaR

Current code clears register writes after a register read is
encountered, this handles the first WaR but hides the write from the
reads that will succeed the first one. Ignoring subtle WaRaR hazards.
To fix this, we don't clear writes when a register read is encountered.

Thanks to Karol Herbst for finding and distilling this issue.

Signed-off-by: Lorenzo Rossi <git@rossilorenzo.dev>
Reviewed-by: Mel Henning <mhenning@darkrefraction.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37108>
This commit is contained in:
Lorenzo Rossi 2025-10-30 13:42:41 +01:00 committed by Marge Bot
parent 7c39f69871
commit fa2c8c9d39

View file

@ -72,13 +72,15 @@ enum RegReadWrite {
/// Maps each register read/write to a value /// Maps each register read/write to a value
/// a register can have multiple reads AND multiple writes at the same /// a register can have multiple reads AND multiple writes at the same
/// point in time if it comes from a merge. /// point in time if it comes from a merge.
/// For edits inside a CFG block, a RegUseMap will always be either /// For edits inside a CFG block, a RegUseMap will never contain multiple
/// empty, with a single write or with one or multiple reads. /// writes.
/// ///
/// We need to track multiple reads as we don't know which one can cause /// We need to track multiple reads as we don't know which one can cause
/// the highest latency for the interfering instruction (in RaW). For the /// the highest latency for the interfering instruction (in RaW). For the
/// same reason we might need to track both reads and writes in the case of /// same reason we might need to track both reads and writes in the case of
/// a CFG block with multiple successors. /// a CFG block with multiple successors.
/// We cannot flush writes after a read operation since we can still
/// encounter other, slower reads that could interfere with the write.
#[derive(Clone, PartialEq, Eq, Default)] #[derive(Clone, PartialEq, Eq, Default)]
struct RegUseMap<K: Hash + Eq, V> { struct RegUseMap<K: Hash + Eq, V> {
map: FxHashMap<(RegReadWrite, K), V>, map: FxHashMap<(RegReadWrite, K), V>,
@ -90,8 +92,6 @@ where
V: Clone, V: Clone,
{ {
pub fn add_read(&mut self, k: K, v: V) { pub fn add_read(&mut self, k: K, v: V) {
// Reads wait on previous writes (RaR don't exist)
self.map.retain(|k, _v| k.0 != RegReadWrite::Write);
self.map.insert((RegReadWrite::Read, k), v); self.map.insert((RegReadWrite::Read, k), v);
} }