nak: Legalize vector sources

It is possible for a single scalar to show up in any number of vector
components, including twice in the same vector.  Add a bit to the
legalization pass to deal with this possibility.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand
2023-04-20 12:58:18 -05:00
committed by Marge Bot
parent 9ef47c8921
commit 10deb1d62b
+47
View File
@@ -5,6 +5,8 @@
use crate::nak_ir::*;
use std::collections::{HashMap, HashSet};
struct LegalizeInstr<'a> {
ssa_alloc: &'a mut SSAValueAllocator,
instrs: Vec<Instr>,
@@ -168,6 +170,51 @@ impl<'a> LegalizeInstr<'a> {
}
_ => (),
}
let mut vec_src_map: HashMap<SSARef, SSARef> = HashMap::new();
let mut vec_comps = HashSet::new();
let mut pcopy = OpParCopy::new();
for src in instr.srcs_mut() {
if let SrcRef::SSA(vec) = &src.src_ref {
if vec.comps() == 1 {
continue;
}
/* If the same vector shows up twice in one instruction, that's
* okay. Just make it look the same as the previous source we
* fixed up.
*/
if let Some(new_vec) = vec_src_map.get(&vec) {
src.src_ref = (*new_vec).into();
continue;
}
let mut new_vec = *vec;
for c in 0..vec.comps() {
let ssa = vec[usize::from(c)];
/* If the same SSA value shows up in multiple non-identical
* vector sources or as multiple components in the same
* source, we need to make a copy so it can get assigned to
* multiple different registers.
*/
if vec_comps.get(&ssa).is_some() {
let copy = self.ssa_alloc.alloc(ssa.file());
pcopy.push(ssa.into(), copy.into());
new_vec[usize::from(c)] = copy;
} else {
vec_comps.insert(ssa);
}
}
vec_src_map.insert(*vec, new_vec);
src.src_ref = new_vec.into();
}
}
if !pcopy.is_empty() {
self.instrs.push(Instr::new(Op::ParCopy(pcopy)));
}
self.instrs.push(instr);
std::mem::replace(&mut self.instrs, Vec::new())
}