nak: Use the builder in some lowering passes

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
Faith Ekstrand 2023-05-25 17:41:16 -05:00 committed by Marge Bot
parent 2d69a2c1d7
commit 82f0c6cf77
3 changed files with 89 additions and 143 deletions

View file

@ -21,6 +21,49 @@ pub trait Builder {
pred: pred, pred: pred,
} }
} }
fn lop2_to(&mut self, dst: Dst, op: LogicOp, x: Src, y: Src) {
/* Only uses x and y */
assert!(!op.src_used(2));
let is_predicate = match dst {
Dst::None => panic!("No LOP destination"),
Dst::SSA(ssa) => ssa.is_predicate(),
Dst::Reg(reg) => reg.is_predicate(),
};
assert!(x.is_predicate() == is_predicate);
assert!(y.is_predicate() == is_predicate);
if is_predicate {
self.push_op(OpPLop3 {
dsts: [dst.into(), Dst::None],
srcs: [x, y, Src::new_imm_bool(true)],
ops: [op, LogicOp::new_const(false)],
});
} else {
self.push_op(OpLop3 {
dst: dst.into(),
srcs: [x, y, Src::new_zero()],
op: op,
});
}
}
fn mov_to(&mut self, dst: Dst, src: Src) {
self.push_op(OpMov {
dst: dst,
src: src,
quad_lanes: 0xf,
});
}
fn swap(&mut self, x: RegRef, y: RegRef) {
assert!(x.file() == y.file());
self.push_op(OpSwap {
dsts: [x.into(), y.into()],
srcs: [y.into(), x.into()],
});
}
} }
pub trait SSABuilder: Builder { pub trait SSABuilder: Builder {
@ -119,36 +162,19 @@ pub trait SSABuilder: Builder {
} }
fn lop2(&mut self, op: LogicOp, x: Src, y: Src) -> SSARef { fn lop2(&mut self, op: LogicOp, x: Src, y: Src) -> SSARef {
/* Only uses x and y */ let dst = if x.is_predicate() {
assert!(op.eval(0x5, 0x3, 0x0) == op.eval(0x5, 0x3, 0xf)); self.alloc_ssa(RegFile::Pred, 1)
assert!(x.is_predicate() == y.is_predicate());
if x.is_predicate() {
let dst = self.alloc_ssa(RegFile::Pred, 1);
self.push_op(OpPLop3 {
dsts: [dst.into(), Dst::None],
srcs: [x, y, Src::new_imm_bool(true)],
ops: [op, LogicOp::new_const(false)],
});
dst
} else { } else {
let dst = self.alloc_ssa(RegFile::GPR, 1); self.alloc_ssa(RegFile::GPR, 1)
self.push_op(OpLop3 { };
dst: dst.into(), self.lop2_to(dst.into(), op, x, y);
srcs: [x, y, Src::new_zero()], dst
op: op,
});
dst
}
} }
fn mov(&mut self, src: Src) -> SSARef { fn mov(&mut self, src: Src) -> SSARef {
assert!(!src.is_predicate()); assert!(!src.is_predicate());
let dst = self.alloc_ssa(RegFile::GPR, 1); let dst = self.alloc_ssa(RegFile::GPR, 1);
self.push_op(OpMov { self.mov_to(dst.into(), src);
dst: dst.into(),
src: src,
quad_lanes: 0xf,
});
dst dst
} }

View file

@ -3242,58 +3242,6 @@ impl Instr {
Box::new(Instr::new(op)) Box::new(Instr::new(op))
} }
pub fn new_isetp(
dst: Dst,
cmp_type: IntCmpType,
cmp_op: IntCmpOp,
x: Src,
y: Src,
) -> Instr {
OpISetP {
dst: dst,
set_op: PredSetOp::And,
cmp_op: cmp_op,
cmp_type: cmp_type,
srcs: [x, y],
accum: SrcRef::True.into(),
}
.into()
}
pub fn new_lop2(dst: Dst, op: LogicOp, x: Src, y: Src) -> Instr {
/* Only uses x and y */
assert!(op.eval(0x5, 0x3, 0x0) == op.eval(0x5, 0x3, 0xf));
let is_predicate = match dst {
Dst::None => panic!("No LOP destination"),
Dst::SSA(ssa) => ssa.is_predicate(),
Dst::Reg(reg) => reg.is_predicate(),
};
assert!(x.src_ref.is_predicate() == is_predicate);
assert!(x.src_ref.is_predicate() == is_predicate);
if is_predicate {
OpPLop3 {
dsts: [dst, Dst::None],
srcs: [x, y, Src::new_imm_bool(true)],
ops: [op, LogicOp::new_const(false)],
}
.into()
} else {
OpLop3 {
dst: dst,
srcs: [x, y, Src::new_zero()],
op: op,
}
.into()
}
}
pub fn new_xor(dst: Dst, x: Src, y: Src) -> Instr {
let xor_lop = LogicOp::new_lut(&|x, y, _| x ^ y);
Instr::new_lop2(dst, xor_lop, x, y)
}
pub fn new_mov(dst: Dst, src: Src) -> Instr { pub fn new_mov(dst: Dst, src: Src) -> Instr {
OpMov { OpMov {
dst: dst, dst: dst,
@ -3303,25 +3251,6 @@ impl Instr {
.into() .into()
} }
pub fn new_plop3(dst: Dst, op: LogicOp, x: Src, y: Src, z: Src) -> Instr {
assert!(x.is_predicate() && y.is_predicate() && z.is_predicate());
OpPLop3 {
dsts: [dst, Dst::None],
srcs: [x, y, z],
ops: [op, LogicOp::new_const(false)],
}
.into()
}
pub fn new_swap(x: RegRef, y: RegRef) -> Instr {
assert!(x.file() == y.file());
OpSwap {
dsts: [x.into(), y.into()],
srcs: [y.into(), x.into()],
}
.into()
}
pub fn dsts(&self) -> &[Dst] { pub fn dsts(&self) -> &[Dst] {
self.op.dsts_as_slice() self.op.dsts_as_slice()
} }
@ -3645,24 +3574,25 @@ impl Shader {
assert!(swap.srcs[1].src_mod.is_none()); assert!(swap.srcs[1].src_mod.is_none());
assert!(*swap.srcs[1].src_ref.as_reg().unwrap() == x); assert!(*swap.srcs[1].src_ref.as_reg().unwrap() == x);
let mut b = InstrBuilder::new();
if x == y { if x == y {
MappedInstrs::None /* Nothing to do */
} else if x.is_predicate() { } else if x.is_predicate() {
MappedInstrs::One(Instr::new_boxed(OpPLop3 { b.push_op(OpPLop3 {
dsts: [x.into(), y.into()], dsts: [x.into(), y.into()],
srcs: [x.into(), y.into(), Src::new_imm_bool(true)], srcs: [x.into(), y.into(), Src::new_imm_bool(true)],
ops: [ ops: [
LogicOp::new_lut(&|_, y, _| y), LogicOp::new_lut(&|_, y, _| y),
LogicOp::new_lut(&|x, _, _| x), LogicOp::new_lut(&|x, _, _| x),
], ],
})) })
} else { } else {
MappedInstrs::Many(vec![ let xor = LogicOp::new_lut(&|x, y, _| x ^ y);
Instr::new_xor(x.into(), x.into(), y.into()).into(), b.lop2_to(x.into(), xor, x.into(), y.into());
Instr::new_xor(y.into(), x.into(), y.into()).into(), b.lop2_to(y.into(), xor, x.into(), y.into());
Instr::new_xor(x.into(), x.into(), y.into()).into(), b.lop2_to(x.into(), xor, x.into(), y.into());
])
} }
b.as_mapped_instrs()
} }
_ => MappedInstrs::One(instr), _ => MappedInstrs::One(instr),
} }
@ -3675,38 +3605,36 @@ impl Shader {
Op::Mov(mov) => { Op::Mov(mov) => {
assert!(mov.src.src_mod.is_none()); assert!(mov.src.src_mod.is_none());
match mov.src.src_ref { match mov.src.src_ref {
SrcRef::True => MappedInstrs::One( SrcRef::True => {
Instr::new_isetp( let mut b = InstrBuilder::new();
b.lop2_to(
mov.dst, mov.dst,
IntCmpType::I32, LogicOp::new_const(true),
IntCmpOp::Eq, Src::new_imm_bool(true),
Src::new_zero(), Src::new_imm_bool(true),
Src::new_zero(), );
) b.as_mapped_instrs()
.into(), }
), SrcRef::False => {
SrcRef::False => MappedInstrs::One( let mut b = InstrBuilder::new();
Instr::new_isetp( b.lop2_to(
mov.dst, mov.dst,
IntCmpType::I32, LogicOp::new_const(false),
IntCmpOp::Ne, Src::new_imm_bool(true),
Src::new_zero(), Src::new_imm_bool(true),
Src::new_zero(), );
) b.as_mapped_instrs()
.into(), }
),
SrcRef::Reg(reg) => { SrcRef::Reg(reg) => {
if reg.is_predicate() { if reg.is_predicate() {
MappedInstrs::One( let mut b = InstrBuilder::new();
Instr::new_plop3( b.lop2_to(
mov.dst, mov.dst,
LogicOp::new_lut(&|x, _, _| x), LogicOp::new_lut(&|x, _, _| x),
mov.src, mov.src,
Src::new_imm_bool(true), Src::new_imm_bool(true),
Src::new_imm_bool(true), );
) b.as_mapped_instrs()
.into(),
)
} else { } else {
MappedInstrs::One(instr) MappedInstrs::One(instr)
} }

View file

@ -110,7 +110,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs {
} }
} }
let mut instrs = Vec::new(); let mut b = InstrBuilder::new();
let mut ready = Vec::new(); let mut ready = Vec::new();
for i in 0..pc.dsts.len() { for i in 0..pc.dsts.len() {
@ -123,7 +123,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs {
if let Some(src_idx) = graph.src(dst_idx) { if let Some(src_idx) = graph.src(dst_idx) {
let dst = *vals[dst_idx].as_reg().unwrap(); let dst = *vals[dst_idx].as_reg().unwrap();
let src = vals[src_idx]; let src = vals[src_idx];
instrs.push(Instr::new_mov(dst.into(), src.into()).into()); b.mov_to(dst.into(), src.into());
if graph.del_edge(dst_idx, src_idx) { if graph.del_edge(dst_idx, src_idx) {
ready.push(src_idx); ready.push(src_idx);
} }
@ -161,15 +161,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs {
if let Some(j) = graph.src(i) { if let Some(j) = graph.src(i) {
/* We're part of a cycle so j also has a source */ /* We're part of a cycle so j also has a source */
let k = graph.src(j).unwrap(); let k = graph.src(j).unwrap();
b.swap(*vals[j].as_reg().unwrap(), *vals[k].as_reg().unwrap());
instrs.push(
Instr::new_swap(
*vals[j].as_reg().unwrap(),
*vals[k].as_reg().unwrap(),
)
.into(),
);
graph.del_edge(i, j); graph.del_edge(i, j);
graph.del_edge(j, k); graph.del_edge(j, k);
if i != k { if i != k {
@ -183,7 +175,7 @@ fn lower_par_copy(pc: OpParCopy) -> MappedInstrs {
} }
} }
MappedInstrs::Many(instrs) b.as_mapped_instrs()
} }
impl Shader { impl Shader {