mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
nak: Use the builder in some lowering passes
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24998>
This commit is contained in:
parent
2d69a2c1d7
commit
82f0c6cf77
3 changed files with 89 additions and 143 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue