nak: Make Dst its own type
Instead of having Src::src_ref and Dst share a type, make them separate enums. We're not really getting any benefit from them being the same enum type anymore and this means we avoid things like immediates in destinations. We can't make the type system do all our work for us but this seems tractable. While we're reworking things we also implement From<> for stuff instead of having quite as many new_*() constructor variants. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:

committed by
Marge Bot

parent
ea2c6c8ebe
commit
495b64be2b
@@ -66,14 +66,6 @@ impl TrivialRegAlloc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rewrite_ref(&mut self, r: Ref) -> Ref {
|
|
||||||
if let Ref::SSA(ssa) = r {
|
|
||||||
Ref::Reg(self.rewrite_ssa(ssa))
|
|
||||||
} else {
|
|
||||||
r
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn do_alloc(&mut self, s: &mut Shader) {
|
pub fn do_alloc(&mut self, s: &mut Shader) {
|
||||||
for f in &mut s.functions {
|
for f in &mut s.functions {
|
||||||
for b in &mut f.blocks {
|
for b in &mut f.blocks {
|
||||||
@@ -82,10 +74,14 @@ impl TrivialRegAlloc {
|
|||||||
instr.pred = Pred::Reg(self.rewrite_ssa(ssa));
|
instr.pred = Pred::Reg(self.rewrite_ssa(ssa));
|
||||||
}
|
}
|
||||||
for dst in instr.dsts_mut() {
|
for dst in instr.dsts_mut() {
|
||||||
*dst = self.rewrite_ref(*dst);
|
if let Dst::SSA(ssa) = dst {
|
||||||
|
*dst = self.rewrite_ssa(*ssa).into();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for src in instr.srcs_mut() {
|
for src in instr.srcs_mut() {
|
||||||
src.src_ref = self.rewrite_ref(src.src_ref);
|
if let SrcRef::SSA(ssa) = src.src_ref {
|
||||||
|
src.src_ref = self.rewrite_ssa(ssa).into();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -200,7 +200,7 @@ impl CalcDelay {
|
|||||||
.dsts()
|
.dsts()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|dst| match dst {
|
.map(|dst| match dst {
|
||||||
Dst::Zero => 0,
|
Dst::None => 0,
|
||||||
Dst::Reg(reg) => self.reg_ready(reg),
|
Dst::Reg(reg) => self.reg_ready(reg),
|
||||||
_ => panic!("Should be run after RA"),
|
_ => panic!("Should be run after RA"),
|
||||||
})
|
})
|
||||||
|
@@ -31,7 +31,7 @@ enum ALUSrc {
|
|||||||
impl ALUSrc {
|
impl ALUSrc {
|
||||||
fn from_nonzero_src(src: &Src) -> ALUSrc {
|
fn from_nonzero_src(src: &Src) -> ALUSrc {
|
||||||
match src.src_ref {
|
match src.src_ref {
|
||||||
Ref::Reg(reg) => {
|
SrcRef::Reg(reg) => {
|
||||||
assert!(reg.comps() == 1);
|
assert!(reg.comps() == 1);
|
||||||
let alu_ref = ALURegRef {
|
let alu_ref = ALURegRef {
|
||||||
reg: reg,
|
reg: reg,
|
||||||
@@ -44,11 +44,11 @@ impl ALUSrc {
|
|||||||
_ => panic!("Invalid ALU register file"),
|
_ => panic!("Invalid ALU register file"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ref::Imm(i) => {
|
SrcRef::Imm(i) => {
|
||||||
assert!(src.src_mod.is_none());
|
assert!(src.src_mod.is_none());
|
||||||
ALUSrc::Imm(i)
|
ALUSrc::Imm(i)
|
||||||
}
|
}
|
||||||
Ref::CBuf(cb) => {
|
SrcRef::CBuf(cb) => {
|
||||||
let alu_ref = ALUCBufRef {
|
let alu_ref = ALUCBufRef {
|
||||||
cb: cb,
|
cb: cb,
|
||||||
abs: src.src_mod.has_abs(),
|
abs: src.src_mod.has_abs(),
|
||||||
@@ -62,7 +62,7 @@ impl ALUSrc {
|
|||||||
|
|
||||||
fn zero(file: RegFile) -> ALUSrc {
|
fn zero(file: RegFile) -> ALUSrc {
|
||||||
let src = Src {
|
let src = Src {
|
||||||
src_ref: Ref::Reg(RegRef::zero(file, 1)),
|
src_ref: SrcRef::Reg(RegRef::zero(file, 1)),
|
||||||
/* Modifiers don't matter for zero */
|
/* Modifiers don't matter for zero */
|
||||||
src_mod: SrcMod::None,
|
src_mod: SrcMod::None,
|
||||||
};
|
};
|
||||||
@@ -71,7 +71,7 @@ impl ALUSrc {
|
|||||||
|
|
||||||
pub fn from_src(src: &Src) -> ALUSrc {
|
pub fn from_src(src: &Src) -> ALUSrc {
|
||||||
match src.src_ref {
|
match src.src_ref {
|
||||||
Ref::Zero => ALUSrc::zero(RegFile::GPR),
|
SrcRef::Zero => ALUSrc::zero(RegFile::GPR),
|
||||||
_ => ALUSrc::from_nonzero_src(src),
|
_ => ALUSrc::from_nonzero_src(src),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ impl ALUSrc {
|
|||||||
pub fn from_usrc(src: &Src) -> ALUSrc {
|
pub fn from_usrc(src: &Src) -> ALUSrc {
|
||||||
assert!(src.is_uniform());
|
assert!(src.is_uniform());
|
||||||
match src.src_ref {
|
match src.src_ref {
|
||||||
Ref::Zero => ALUSrc::zero(RegFile::UGPR),
|
SrcRef::Zero => ALUSrc::zero(RegFile::UGPR),
|
||||||
_ => ALUSrc::from_nonzero_src(src),
|
_ => ALUSrc::from_nonzero_src(src),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,15 +140,15 @@ impl SM75Instr {
|
|||||||
fn set_reg_src(&mut self, range: Range<usize>, src: Src) {
|
fn set_reg_src(&mut self, range: Range<usize>, src: Src) {
|
||||||
assert!(src.src_mod.is_none());
|
assert!(src.src_mod.is_none());
|
||||||
match src.src_ref {
|
match src.src_ref {
|
||||||
Ref::Zero => self.set_reg(range, RegRef::zero(RegFile::GPR, 1)),
|
SrcRef::Zero => self.set_reg(range, RegRef::zero(RegFile::GPR, 1)),
|
||||||
Ref::Reg(reg) => self.set_reg(range, reg),
|
SrcRef::Reg(reg) => self.set_reg(range, reg),
|
||||||
_ => panic!("Not a register"),
|
_ => panic!("Not a register"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_pred_dst(&mut self, range: Range<usize>, dst: Dst) {
|
fn set_pred_dst(&mut self, range: Range<usize>, dst: Dst) {
|
||||||
match dst {
|
match dst {
|
||||||
Dst::Zero => {
|
Dst::None => {
|
||||||
self.set_pred_reg(range, RegRef::zero(RegFile::Pred, 1));
|
self.set_pred_reg(range, RegRef::zero(RegFile::Pred, 1));
|
||||||
}
|
}
|
||||||
Dst::Reg(reg) => self.set_pred_reg(range, reg),
|
Dst::Reg(reg) => self.set_pred_reg(range, reg),
|
||||||
@@ -158,10 +158,10 @@ impl SM75Instr {
|
|||||||
|
|
||||||
fn set_pred_src(&mut self, range: Range<usize>, not_bit: isize, src: Src) {
|
fn set_pred_src(&mut self, range: Range<usize>, not_bit: isize, src: Src) {
|
||||||
match src.src_ref {
|
match src.src_ref {
|
||||||
Ref::Zero => {
|
SrcRef::Zero => {
|
||||||
self.set_pred_reg(range, RegRef::zero(RegFile::Pred, 1));
|
self.set_pred_reg(range, RegRef::zero(RegFile::Pred, 1));
|
||||||
}
|
}
|
||||||
Ref::Reg(reg) => self.set_pred_reg(range, reg),
|
SrcRef::Reg(reg) => self.set_pred_reg(range, reg),
|
||||||
_ => panic!("Not a register"),
|
_ => panic!("Not a register"),
|
||||||
}
|
}
|
||||||
if not_bit >= 0 {
|
if not_bit >= 0 {
|
||||||
|
@@ -33,27 +33,27 @@ impl<'a> ShaderFromNir<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_ssa(&mut self, file: RegFile, comps: u8) -> Ref {
|
pub fn alloc_ssa(&mut self, file: RegFile, comps: u8) -> SSAValue {
|
||||||
self.func.as_mut().unwrap().alloc_ssa(file, comps)
|
self.func.as_mut().unwrap().alloc_ssa(file, comps)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ref_for_nir_def(&self, def: &nir_def) -> Ref {
|
fn get_ssa(&self, def: &nir_def) -> SSAValue {
|
||||||
if def.bit_size == 1 {
|
if def.bit_size == 1 {
|
||||||
Ref::new_ssa(RegFile::Pred, def.index, def.num_components)
|
SSAValue::new(RegFile::Pred, def.index, def.num_components)
|
||||||
} else {
|
} else {
|
||||||
assert!(def.bit_size == 32 || def.bit_size == 64);
|
assert!(def.bit_size == 32 || def.bit_size == 64);
|
||||||
let dwords = (def.bit_size / 32) * def.num_components;
|
let dwords = (def.bit_size / 32) * def.num_components;
|
||||||
//Src::new_ssa(def.index, dwords, !def.divergent)
|
//Src::new_ssa(def.index, dwords, !def.divergent)
|
||||||
Ref::new_ssa(RegFile::GPR, def.index, dwords)
|
SSAValue::new(RegFile::GPR, def.index, dwords)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_src(&self, src: &nir_src) -> Src {
|
fn get_src(&self, src: &nir_src) -> Src {
|
||||||
self.ref_for_nir_def(&src.as_def()).into()
|
self.get_ssa(&src.as_def()).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_dst(&self, def: &nir_def) -> Dst {
|
fn get_dst(&self, dst: &nir_def) -> Dst {
|
||||||
self.ref_for_nir_def(def).as_dst()
|
self.get_ssa(dst).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_alu_src(&mut self, alu_src: &nir_alu_src) -> Src {
|
fn get_alu_src(&mut self, alu_src: &nir_alu_src) -> Src {
|
||||||
@@ -67,9 +67,9 @@ impl<'a> ShaderFromNir<'a> {
|
|||||||
let mut dsts = Vec::new();
|
let mut dsts = Vec::new();
|
||||||
for c in 0..alu_src.src.num_components() {
|
for c in 0..alu_src.src.num_components() {
|
||||||
if c == alu_src.swizzle[0] {
|
if c == alu_src.swizzle[0] {
|
||||||
dsts.push(comp.as_dst());
|
dsts.push(comp.into());
|
||||||
} else {
|
} else {
|
||||||
dsts.push(Dst::Zero);
|
dsts.push(Dst::None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.instrs.push(Instr::new_split(&dsts, vec_src));
|
self.instrs.push(Instr::new_split(&dsts, vec_src));
|
||||||
@@ -157,7 +157,7 @@ impl<'a> ShaderFromNir<'a> {
|
|||||||
nir_op_fsign => {
|
nir_op_fsign => {
|
||||||
let lz = self.alloc_ssa(RegFile::GPR, 1);
|
let lz = self.alloc_ssa(RegFile::GPR, 1);
|
||||||
self.instrs.push(Instr::new_fset(
|
self.instrs.push(Instr::new_fset(
|
||||||
lz,
|
lz.into(),
|
||||||
FloatCmpOp::OrdLt,
|
FloatCmpOp::OrdLt,
|
||||||
srcs[0],
|
srcs[0],
|
||||||
Src::new_zero(),
|
Src::new_zero(),
|
||||||
@@ -165,7 +165,7 @@ impl<'a> ShaderFromNir<'a> {
|
|||||||
|
|
||||||
let gz = self.alloc_ssa(RegFile::GPR, 1);
|
let gz = self.alloc_ssa(RegFile::GPR, 1);
|
||||||
self.instrs.push(Instr::new_fset(
|
self.instrs.push(Instr::new_fset(
|
||||||
gz,
|
gz.into(),
|
||||||
FloatCmpOp::OrdGt,
|
FloatCmpOp::OrdGt,
|
||||||
srcs[0],
|
srcs[0],
|
||||||
Src::new_zero(),
|
Src::new_zero(),
|
||||||
@@ -416,7 +416,7 @@ impl<'a> ShaderFromNir<'a> {
|
|||||||
for c in 0..intrin.num_components {
|
for c in 0..intrin.num_components {
|
||||||
let tmp = self.alloc_ssa(RegFile::GPR, 1);
|
let tmp = self.alloc_ssa(RegFile::GPR, 1);
|
||||||
self.fs_out_regs[(base + c) as usize] = tmp.into();
|
self.fs_out_regs[(base + c) as usize] = tmp.into();
|
||||||
dsts.push(tmp);
|
dsts.push(Dst::from(tmp));
|
||||||
}
|
}
|
||||||
self.instrs.push(Instr::new_split(&dsts, data))
|
self.instrs.push(Instr::new_split(&dsts, data))
|
||||||
} else {
|
} else {
|
||||||
@@ -432,7 +432,7 @@ impl<'a> ShaderFromNir<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_load_const(&mut self, load_const: &nir_load_const_instr) {
|
fn parse_load_const(&mut self, load_const: &nir_load_const_instr) {
|
||||||
let dst = self.ref_for_nir_def(&load_const.def);
|
let dst = self.get_dst(&load_const.def);
|
||||||
let mut srcs = Vec::new();
|
let mut srcs = Vec::new();
|
||||||
for c in 0..load_const.def.num_components {
|
for c in 0..load_const.def.num_components {
|
||||||
assert!(load_const.def.bit_size == 32);
|
assert!(load_const.def.bit_size == 32);
|
||||||
|
@@ -202,6 +202,52 @@ impl fmt::Display for RegRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub enum Dst {
|
||||||
|
None,
|
||||||
|
SSA(SSAValue),
|
||||||
|
Reg(RegRef),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Dst {
|
||||||
|
pub fn as_reg(&self) -> Option<&RegRef> {
|
||||||
|
match self {
|
||||||
|
Dst::Reg(r) => Some(r),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_ssa(&self) -> Option<&SSAValue> {
|
||||||
|
match self {
|
||||||
|
Dst::SSA(r) => Some(r),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RegRef> for Dst {
|
||||||
|
fn from(reg: RegRef) -> Dst {
|
||||||
|
Dst::Reg(reg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SSAValue> for Dst {
|
||||||
|
fn from(ssa: SSAValue) -> Dst {
|
||||||
|
Dst::SSA(ssa)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Dst {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Dst::None => write!(f, "NULL")?,
|
||||||
|
Dst::SSA(v) => v.fmt(f)?,
|
||||||
|
Dst::Reg(r) => r.fmt(f)?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum CBuf {
|
pub enum CBuf {
|
||||||
Binding(u8),
|
Binding(u8),
|
||||||
@@ -216,7 +262,7 @@ pub struct CBufRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum Ref {
|
pub enum SrcRef {
|
||||||
Zero,
|
Zero,
|
||||||
Imm(Immediate),
|
Imm(Immediate),
|
||||||
CBuf(CBufRef),
|
CBuf(CBufRef),
|
||||||
@@ -224,62 +270,62 @@ pub enum Ref {
|
|||||||
Reg(RegRef),
|
Reg(RegRef),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ref {
|
impl SrcRef {
|
||||||
pub fn new_ssa(file: RegFile, idx: u32, comps: u8) -> Ref {
|
|
||||||
Ref::SSA(SSAValue::new(file, idx, comps))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_reg(file: RegFile, idx: u8, comps: u8) -> Ref {
|
|
||||||
Ref::Reg(RegRef::new(file, idx, comps))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_dst(&self) -> Dst {
|
|
||||||
*self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_reg(&self) -> Option<&RegRef> {
|
pub fn as_reg(&self) -> Option<&RegRef> {
|
||||||
match self {
|
match self {
|
||||||
Ref::Reg(r) => Some(r),
|
SrcRef::Reg(r) => Some(r),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_ssa(&self) -> Option<&SSAValue> {
|
pub fn as_ssa(&self) -> Option<&SSAValue> {
|
||||||
match self {
|
match self {
|
||||||
Ref::SSA(r) => Some(r),
|
SrcRef::SSA(r) => Some(r),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_reg(&self) -> Option<&RegRef> {
|
pub fn get_reg(&self) -> Option<&RegRef> {
|
||||||
match self {
|
match self {
|
||||||
Ref::Zero | Ref::Imm(_) | Ref::SSA(_) => None,
|
SrcRef::Zero | SrcRef::Imm(_) | SrcRef::SSA(_) => None,
|
||||||
Ref::CBuf(cb) => match &cb.buf {
|
SrcRef::CBuf(cb) => match &cb.buf {
|
||||||
CBuf::Binding(_) | CBuf::BindlessSSA(_) => None,
|
CBuf::Binding(_) | CBuf::BindlessSSA(_) => None,
|
||||||
CBuf::BindlessGPR(reg) => Some(reg),
|
CBuf::BindlessGPR(reg) => Some(reg),
|
||||||
},
|
},
|
||||||
Ref::Reg(reg) => Some(reg),
|
SrcRef::Reg(reg) => Some(reg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ssa(&self) -> Option<&SSAValue> {
|
pub fn get_ssa(&self) -> Option<&SSAValue> {
|
||||||
match self {
|
match self {
|
||||||
Ref::Zero | Ref::Imm(_) | Ref::Reg(_) => None,
|
SrcRef::Zero | SrcRef::Imm(_) | SrcRef::Reg(_) => None,
|
||||||
Ref::CBuf(cb) => match &cb.buf {
|
SrcRef::CBuf(cb) => match &cb.buf {
|
||||||
CBuf::Binding(_) | CBuf::BindlessGPR(_) => None,
|
CBuf::Binding(_) | CBuf::BindlessGPR(_) => None,
|
||||||
CBuf::BindlessSSA(ssa) => Some(ssa),
|
CBuf::BindlessSSA(ssa) => Some(ssa),
|
||||||
},
|
},
|
||||||
Ref::SSA(ssa) => Some(ssa),
|
SrcRef::SSA(ssa) => Some(ssa),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Ref {
|
impl From<RegRef> for SrcRef {
|
||||||
|
fn from(reg: RegRef) -> SrcRef {
|
||||||
|
SrcRef::Reg(reg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SSAValue> for SrcRef {
|
||||||
|
fn from(ssa: SSAValue) -> SrcRef {
|
||||||
|
SrcRef::SSA(ssa)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for SrcRef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Ref::Zero => write!(f, "ZERO")?,
|
SrcRef::Zero => write!(f, "ZERO")?,
|
||||||
Ref::Imm(x) => write!(f, "{:#x}", x.u)?,
|
SrcRef::Imm(x) => write!(f, "{:#x}", x.u)?,
|
||||||
Ref::CBuf(r) => {
|
SrcRef::CBuf(r) => {
|
||||||
match r.buf {
|
match r.buf {
|
||||||
CBuf::Binding(idx) => write!(f, "c[{:#x}]", idx)?,
|
CBuf::Binding(idx) => write!(f, "c[{:#x}]", idx)?,
|
||||||
CBuf::BindlessSSA(v) => write!(f, "cx[{}]", v)?,
|
CBuf::BindlessSSA(v) => write!(f, "cx[{}]", v)?,
|
||||||
@@ -287,15 +333,13 @@ impl fmt::Display for Ref {
|
|||||||
}
|
}
|
||||||
write!(f, "[{:#x}]", r.offset)?;
|
write!(f, "[{:#x}]", r.offset)?;
|
||||||
}
|
}
|
||||||
Ref::SSA(v) => v.fmt(f)?,
|
SrcRef::SSA(v) => v.fmt(f)?,
|
||||||
Ref::Reg(r) => r.fmt(f)?,
|
SrcRef::Reg(r) => r.fmt(f)?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Dst = Ref;
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum SrcMod {
|
pub enum SrcMod {
|
||||||
None,
|
None,
|
||||||
@@ -367,21 +411,21 @@ impl SrcMod {
|
|||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Src {
|
pub struct Src {
|
||||||
pub src_ref: Ref,
|
pub src_ref: SrcRef,
|
||||||
pub src_mod: SrcMod,
|
pub src_mod: SrcMod,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Src {
|
impl Src {
|
||||||
pub fn new_zero() -> Src {
|
pub fn new_zero() -> Src {
|
||||||
Ref::Zero.into()
|
SrcRef::Zero.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_imm_u32(u: u32) -> Src {
|
pub fn new_imm_u32(u: u32) -> Src {
|
||||||
Ref::Imm(Immediate { u: u }).into()
|
SrcRef::Imm(Immediate { u: u }).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_cbuf(idx: u8, offset: u16) -> Src {
|
pub fn new_cbuf(idx: u8, offset: u16) -> Src {
|
||||||
Ref::CBuf(CBufRef {
|
SrcRef::CBuf(CBufRef {
|
||||||
buf: CBuf::Binding(idx),
|
buf: CBuf::Binding(idx),
|
||||||
offset: offset,
|
offset: offset,
|
||||||
})
|
})
|
||||||
@@ -419,29 +463,29 @@ impl Src {
|
|||||||
|
|
||||||
pub fn is_uniform(&self) -> bool {
|
pub fn is_uniform(&self) -> bool {
|
||||||
match self.src_ref {
|
match self.src_ref {
|
||||||
Ref::Zero | Ref::Imm(_) | Ref::CBuf(_) => true,
|
SrcRef::Zero | SrcRef::Imm(_) | SrcRef::CBuf(_) => true,
|
||||||
Ref::SSA(ssa) => ssa.is_uniform(),
|
SrcRef::SSA(ssa) => ssa.is_uniform(),
|
||||||
Ref::Reg(reg) => reg.is_uniform(),
|
SrcRef::Reg(reg) => reg.is_uniform(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_zero(&self) -> bool {
|
pub fn is_zero(&self) -> bool {
|
||||||
match self.src_ref {
|
match self.src_ref {
|
||||||
Ref::Zero => true,
|
SrcRef::Zero => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_reg_or_zero(&self) -> bool {
|
pub fn is_reg_or_zero(&self) -> bool {
|
||||||
match self.src_ref {
|
match self.src_ref {
|
||||||
Ref::Zero | Ref::SSA(_) | Ref::Reg(_) => true,
|
SrcRef::Zero | SrcRef::SSA(_) | SrcRef::Reg(_) => true,
|
||||||
Ref::Imm(_) | Ref::CBuf(_) => false,
|
SrcRef::Imm(_) | SrcRef::CBuf(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Ref> for Src {
|
impl From<SrcRef> for Src {
|
||||||
fn from(src_ref: Ref) -> Src {
|
fn from(src_ref: SrcRef) -> Src {
|
||||||
Src {
|
Src {
|
||||||
src_ref: src_ref,
|
src_ref: src_ref,
|
||||||
src_mod: SrcMod::None,
|
src_mod: SrcMod::None,
|
||||||
@@ -449,6 +493,18 @@ impl From<Ref> for Src {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<RegRef> for Src {
|
||||||
|
fn from(reg: RegRef) -> Src {
|
||||||
|
SrcRef::from(reg).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SSAValue> for Src {
|
||||||
|
fn from(ssa: SSAValue) -> Src {
|
||||||
|
SrcRef::from(ssa).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Src {
|
impl fmt::Display for Src {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self.src_mod {
|
match self.src_mod {
|
||||||
@@ -1291,14 +1347,6 @@ pub enum Pred {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Pred {
|
impl Pred {
|
||||||
pub fn new_ssa(file: RegFile, idx: u32, comps: u8) -> Pred {
|
|
||||||
Pred::SSA(SSAValue::new(file, idx, comps))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_reg(file: RegFile, idx: u8, comps: u8) -> Pred {
|
|
||||||
Pred::Reg(RegRef::new(file, idx, comps))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_reg(&self) -> Option<&RegRef> {
|
pub fn as_reg(&self) -> Option<&RegRef> {
|
||||||
match self {
|
match self {
|
||||||
Pred::Reg(r) => Some(r),
|
Pred::Reg(r) => Some(r),
|
||||||
@@ -1476,7 +1524,7 @@ impl Instr {
|
|||||||
pub fn new_iadd(dst: Dst, x: Src, y: Src) -> Instr {
|
pub fn new_iadd(dst: Dst, x: Src, y: Src) -> Instr {
|
||||||
Instr::new(Op::IAdd3(OpIAdd3 {
|
Instr::new(Op::IAdd3(OpIAdd3 {
|
||||||
dst: dst,
|
dst: dst,
|
||||||
overflow: Dst::Zero,
|
overflow: Dst::None,
|
||||||
srcs: [Src::new_zero(), x, y],
|
srcs: [Src::new_zero(), x, y],
|
||||||
carry: Src::new_zero(),
|
carry: Src::new_zero(),
|
||||||
}))
|
}))
|
||||||
@@ -1734,10 +1782,10 @@ impl Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_ssa(&mut self, file: RegFile, comps: u8) -> Ref {
|
pub fn alloc_ssa(&mut self, file: RegFile, comps: u8) -> SSAValue {
|
||||||
let idx = self.ssa_count;
|
let idx = self.ssa_count;
|
||||||
self.ssa_count += 1;
|
self.ssa_count += 1;
|
||||||
Ref::new_ssa(file, idx, comps)
|
SSAValue::new(file, idx, comps)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_instrs<F: Fn(Instr) -> Vec<Instr>>(&mut self, map: &F) {
|
pub fn map_instrs<F: Fn(Instr) -> Vec<Instr>>(&mut self, map: &F) {
|
||||||
@@ -1789,7 +1837,7 @@ impl Shader {
|
|||||||
Op::IMov(mov) => {
|
Op::IMov(mov) => {
|
||||||
vec![Instr::new(Op::IAdd3(OpIAdd3 {
|
vec![Instr::new(Op::IAdd3(OpIAdd3 {
|
||||||
dst: mov.dst,
|
dst: mov.dst,
|
||||||
overflow: Dst::Zero,
|
overflow: Dst::None,
|
||||||
srcs: [Src::new_zero(), mov.src, Src::new_zero()],
|
srcs: [Src::new_zero(), mov.src, Src::new_zero()],
|
||||||
carry: Src::new_zero(),
|
carry: Src::new_zero(),
|
||||||
}))]
|
}))]
|
||||||
@@ -1823,12 +1871,12 @@ impl Shader {
|
|||||||
let vec_src = split.src.src_ref.as_reg().unwrap();
|
let vec_src = split.src.src_ref.as_reg().unwrap();
|
||||||
assert!(comps == vec_src.comps());
|
assert!(comps == vec_src.comps());
|
||||||
for i in 0..comps {
|
for i in 0..comps {
|
||||||
let src = Dst::Reg(vec_src.as_comp(i).unwrap());
|
let src = vec_src.as_comp(i).unwrap();
|
||||||
let dst = split.dsts[usize::from(i)];
|
let dst = split.dsts[usize::from(i)];
|
||||||
if let Dst::Zero = dst {
|
if let Dst::None = dst {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
instrs.push(Instr::new_mov(dst, src.into()));
|
instrs.push(Instr::new_mov(dst.into(), src.into()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
instrs
|
instrs
|
||||||
@@ -1836,12 +1884,9 @@ impl Shader {
|
|||||||
Op::FSOut(out) => {
|
Op::FSOut(out) => {
|
||||||
let mut instrs = Vec::new();
|
let mut instrs = Vec::new();
|
||||||
for (i, src) in out.srcs.iter().enumerate() {
|
for (i, src) in out.srcs.iter().enumerate() {
|
||||||
let dst = Ref::new_reg(
|
let dst =
|
||||||
RegFile::GPR,
|
RegRef::new(RegFile::GPR, i.try_into().unwrap(), 1);
|
||||||
i.try_into().unwrap(),
|
instrs.push(Instr::new_mov(dst.into(), *src));
|
||||||
1,
|
|
||||||
);
|
|
||||||
instrs.push(Instr::new_mov(dst, *src));
|
|
||||||
}
|
}
|
||||||
instrs
|
instrs
|
||||||
}
|
}
|
||||||
|
@@ -54,14 +54,14 @@ impl CopyPropPass {
|
|||||||
if let Pred::SSA(src_ssa) = &instr.pred {
|
if let Pred::SSA(src_ssa) = &instr.pred {
|
||||||
if let Some(src_vec) = self.get_copy(&src_ssa) {
|
if let Some(src_vec) = self.get_copy(&src_ssa) {
|
||||||
assert!(src_vec[0].src_mod.is_none());
|
assert!(src_vec[0].src_mod.is_none());
|
||||||
if let Ref::SSA(ssa) = src_vec[0].src_ref {
|
if let SrcRef::SSA(ssa) = src_vec[0].src_ref {
|
||||||
instr.pred = Pred::SSA(ssa);
|
instr.pred = Pred::SSA(ssa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for src in instr.srcs_mut() {
|
for src in instr.srcs_mut() {
|
||||||
if let Ref::SSA(src_ssa) = src.src_ref {
|
if let SrcRef::SSA(src_ssa) = src.src_ref {
|
||||||
if src_ssa.comps() == 1 {
|
if src_ssa.comps() == 1 {
|
||||||
if let Some(src_vec) = self.get_copy(&src_ssa) {
|
if let Some(src_vec) = self.get_copy(&src_ssa) {
|
||||||
assert!(src_vec[0].src_mod.is_none());
|
assert!(src_vec[0].src_mod.is_none());
|
||||||
|
@@ -28,7 +28,7 @@ impl DeadCodePass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for src in instr.srcs() {
|
for src in instr.srcs() {
|
||||||
if let Ref::SSA(ssa) = &src.src_ref {
|
if let SrcRef::SSA(ssa) = &src.src_ref {
|
||||||
self.mark_ssa_live(ssa);
|
self.mark_ssa_live(ssa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,8 +36,8 @@ impl DeadCodePass {
|
|||||||
|
|
||||||
fn is_dst_live(&self, dst: &Dst) -> bool {
|
fn is_dst_live(&self, dst: &Dst) -> bool {
|
||||||
match dst {
|
match dst {
|
||||||
Ref::SSA(ssa) => self.live_ssa.get(ssa).is_some(),
|
Dst::SSA(ssa) => self.live_ssa.get(ssa).is_some(),
|
||||||
Ref::Zero => false,
|
Dst::None => false,
|
||||||
_ => panic!("Invalid SSA destination"),
|
_ => panic!("Invalid SSA destination"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user