mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 03:08:05 +02:00
nak: Implement phis
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
parent
520ad0f4a7
commit
020a7ba8f5
4 changed files with 157 additions and 11 deletions
|
|
@ -16,6 +16,7 @@ struct TrivialRegAlloc {
|
|||
next_pred: u8,
|
||||
next_upred: u8,
|
||||
reg_map: HashMap<SSAValue, RegRef>,
|
||||
phi_map: HashMap<u32, RegRef>,
|
||||
}
|
||||
|
||||
impl TrivialRegAlloc {
|
||||
|
|
@ -26,6 +27,7 @@ impl TrivialRegAlloc {
|
|||
next_pred: 0,
|
||||
next_upred: 0,
|
||||
reg_map: HashMap::new(),
|
||||
phi_map: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +58,17 @@ impl TrivialRegAlloc {
|
|||
RegRef::new(file, idx, comps)
|
||||
}
|
||||
|
||||
pub fn rewrite_ssa(&mut self, ssa: SSAValue) -> RegRef {
|
||||
fn get_phi_reg(&mut self, phi_id: u32, file: RegFile, comps: u8) -> RegRef {
|
||||
if let Some(reg) = self.phi_map.get(&phi_id) {
|
||||
*reg
|
||||
} else {
|
||||
let reg = self.alloc_reg(file, comps);
|
||||
self.phi_map.insert(phi_id, reg);
|
||||
reg
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_ssa_reg(&mut self, ssa: SSAValue) -> RegRef {
|
||||
if let Some(reg) = self.reg_map.get(&ssa) {
|
||||
*reg
|
||||
} else {
|
||||
|
|
@ -70,17 +82,49 @@ impl TrivialRegAlloc {
|
|||
for f in &mut s.functions {
|
||||
for b in &mut f.blocks {
|
||||
for instr in &mut b.instrs {
|
||||
if let Pred::SSA(ssa) = instr.pred {
|
||||
instr.pred = Pred::Reg(self.rewrite_ssa(ssa));
|
||||
}
|
||||
for dst in instr.dsts_mut() {
|
||||
if let Dst::SSA(ssa) = dst {
|
||||
*dst = self.rewrite_ssa(*ssa).into();
|
||||
match &instr.op {
|
||||
Op::PhiSrc(op) => {
|
||||
let src_ssa = op.src.as_ssa().unwrap();
|
||||
let src = self.get_ssa_reg(*src_ssa);
|
||||
let dst = self.get_phi_reg(
|
||||
op.phi_id,
|
||||
src_ssa.file(),
|
||||
src_ssa.comps(),
|
||||
);
|
||||
instr.op = Op::Mov(OpMov {
|
||||
dst: dst.into(),
|
||||
src: src.into(),
|
||||
quad_lanes: 0xf,
|
||||
});
|
||||
}
|
||||
}
|
||||
for src in instr.srcs_mut() {
|
||||
if let SrcRef::SSA(ssa) = src.src_ref {
|
||||
src.src_ref = self.rewrite_ssa(ssa).into();
|
||||
Op::PhiDst(op) => {
|
||||
let dst_ssa = op.dst.as_ssa().unwrap();
|
||||
let src = self.get_phi_reg(
|
||||
op.phi_id,
|
||||
dst_ssa.file(),
|
||||
dst_ssa.comps(),
|
||||
);
|
||||
let dst = self.get_ssa_reg(*dst_ssa);
|
||||
instr.op = Op::Mov(OpMov {
|
||||
dst: dst.into(),
|
||||
src: src.into(),
|
||||
quad_lanes: 0xf,
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
if let Pred::SSA(ssa) = instr.pred {
|
||||
instr.pred = self.get_ssa_reg(ssa).into();
|
||||
}
|
||||
for dst in instr.dsts_mut() {
|
||||
if let Dst::SSA(ssa) = dst {
|
||||
*dst = self.get_ssa_reg(*ssa).into();
|
||||
}
|
||||
}
|
||||
for src in instr.srcs_mut() {
|
||||
if let SrcRef::SSA(ssa) = src.src_ref {
|
||||
src.src_ref = self.get_ssa_reg(ssa).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ use crate::nir::*;
|
|||
|
||||
use nak_bindings::*;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
struct ShaderFromNir<'a> {
|
||||
nir: &'a nir_shader,
|
||||
func: Option<Function>,
|
||||
|
|
@ -17,6 +19,8 @@ struct ShaderFromNir<'a> {
|
|||
instrs: Vec<Instr>,
|
||||
fs_out_regs: Vec<Src>,
|
||||
end_block_id: u32,
|
||||
num_phis: u32,
|
||||
phis: HashMap<u32, u32>,
|
||||
}
|
||||
|
||||
impl<'a> ShaderFromNir<'a> {
|
||||
|
|
@ -34,6 +38,8 @@ impl<'a> ShaderFromNir<'a> {
|
|||
instrs: Vec::new(),
|
||||
fs_out_regs: fs_out_regs,
|
||||
end_block_id: 0,
|
||||
num_phis: 0,
|
||||
phis: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +87,18 @@ impl<'a> ShaderFromNir<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn get_phi_id(&mut self, phi: &nir_phi_instr) -> u32 {
|
||||
match self.phis.get(&phi.def.index) {
|
||||
Some(id) => *id,
|
||||
None => {
|
||||
let id = self.num_phis;
|
||||
self.num_phis += 1;
|
||||
self.phis.insert(phi.def.index, id);
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn split64(&mut self, ssa: SSAValue) -> [SSAValue; 2] {
|
||||
assert!(ssa.comps() == 2);
|
||||
let split =
|
||||
|
|
@ -509,11 +527,39 @@ impl<'a> ShaderFromNir<'a> {
|
|||
nir_instr_type_undef => {
|
||||
self.parse_undef(ni.as_undef().unwrap())
|
||||
}
|
||||
nir_instr_type_phi => {
|
||||
let phi = ni.as_phi().unwrap();
|
||||
let dst = self.get_dst(&phi.def);
|
||||
let phi_id = self.get_phi_id(phi);
|
||||
self.instrs.push(Instr::new_phi_dst(phi_id, dst));
|
||||
}
|
||||
_ => panic!("Unsupported instruction type"),
|
||||
}
|
||||
}
|
||||
|
||||
let succ = nb.successors();
|
||||
for sb in succ {
|
||||
let sb = match sb {
|
||||
Some(b) => b,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
for i in sb.iter_instr_list() {
|
||||
let phi = match i.as_phi() {
|
||||
Some(phi) => phi,
|
||||
None => break,
|
||||
};
|
||||
|
||||
let phi_id = self.get_phi_id(phi);
|
||||
for ps in phi.iter_srcs() {
|
||||
if ps.pred().index == nb.index {
|
||||
let src = self.get_src(&ps.src);
|
||||
self.instrs.push(Instr::new_phi_src(phi_id, src));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let s0 = succ[0].unwrap();
|
||||
if let Some(s1) = succ[1] {
|
||||
/* Jump to the else. We'll come back and fix up the predicate as
|
||||
|
|
|
|||
|
|
@ -1322,6 +1322,32 @@ impl fmt::Display for OpSplit {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpPhiSrc {
|
||||
pub src: Src,
|
||||
pub phi_id: u32,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpPhiSrc {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "PHI_SRC({}) {}", self.phi_id, self.src)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(SrcsAsSlice, DstsAsSlice)]
|
||||
pub struct OpPhiDst {
|
||||
pub dst: Dst,
|
||||
pub phi_id: u32,
|
||||
}
|
||||
|
||||
impl fmt::Display for OpPhiDst {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "PHI_DST({}) {}", self.phi_id, self.dst)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(DstsAsSlice)]
|
||||
pub struct OpFSOut {
|
||||
|
|
@ -1370,6 +1396,8 @@ pub enum Op {
|
|||
S2R(OpS2R),
|
||||
FMov(OpFMov),
|
||||
IMov(OpIMov),
|
||||
PhiSrc(OpPhiSrc),
|
||||
PhiDst(OpPhiDst),
|
||||
Vec(OpVec),
|
||||
Split(OpSplit),
|
||||
FSOut(OpFSOut),
|
||||
|
|
@ -1701,6 +1729,20 @@ impl Instr {
|
|||
Instr::new(Op::S2R(OpS2R { dst: dst, idx: idx }))
|
||||
}
|
||||
|
||||
pub fn new_phi_src(phi_id: u32, src: Src) -> Instr {
|
||||
Instr::new(Op::PhiSrc(OpPhiSrc {
|
||||
phi_id: phi_id,
|
||||
src: src,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn new_phi_dst(phi_id: u32, dst: Dst) -> Instr {
|
||||
Instr::new(Op::PhiDst(OpPhiDst {
|
||||
phi_id: phi_id,
|
||||
dst: dst,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn new_vec(dst: Dst, srcs: &[Src]) -> Instr {
|
||||
Instr::new(Op::Vec(OpVec {
|
||||
dst: dst,
|
||||
|
|
@ -1775,6 +1817,8 @@ impl Instr {
|
|||
Op::Bra(_) | Op::Exit(_) => Some(15),
|
||||
Op::FMov(_)
|
||||
| Op::IMov(_)
|
||||
| Op::PhiSrc(_)
|
||||
| Op::PhiDst(_)
|
||||
| Op::Vec(_)
|
||||
| Op::Split(_)
|
||||
| Op::FSOut(_) => {
|
||||
|
|
|
|||
|
|
@ -9,12 +9,14 @@ use std::collections::HashSet;
|
|||
|
||||
struct DeadCodePass {
|
||||
live_ssa: HashSet<SSAValue>,
|
||||
live_phi: HashSet<u32>,
|
||||
}
|
||||
|
||||
impl DeadCodePass {
|
||||
pub fn new() -> DeadCodePass {
|
||||
DeadCodePass {
|
||||
live_ssa: HashSet::new(),
|
||||
live_phi: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -23,6 +25,10 @@ impl DeadCodePass {
|
|||
}
|
||||
|
||||
fn mark_instr_live(&mut self, instr: &Instr) {
|
||||
if let Op::PhiDst(op) = &instr.op {
|
||||
self.live_phi.insert(op.phi_id);
|
||||
}
|
||||
|
||||
if let Pred::SSA(ssa) = &instr.pred {
|
||||
self.mark_ssa_live(ssa);
|
||||
}
|
||||
|
|
@ -47,6 +53,12 @@ impl DeadCodePass {
|
|||
return true;
|
||||
}
|
||||
|
||||
if let Op::PhiSrc(op) = &instr.op {
|
||||
if self.live_phi.get(&op.phi_id).is_some() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for dst in instr.dsts() {
|
||||
if self.is_dst_live(dst) {
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue