r600/sfn: Simlify check for zero and one

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19729>
This commit is contained in:
Gert Wollny
2022-10-28 18:42:34 +02:00
parent a81c50a214
commit 307b81747e
4 changed files with 75 additions and 52 deletions
+4 -17
View File
@@ -717,23 +717,10 @@ ReplaceConstSource::visit(AluInstr *alu)
int override_chan = -1;
auto ic = src->as_inline_const();
if (ic) {
if (ic->sel() == ALU_SRC_0)
override_chan = 4;
if (ic->sel() == ALU_SRC_1)
override_chan = 5;
}
auto literal = src->as_literal();
if (literal) {
if (literal->value() == 0)
override_chan = 4;
if (literal->value() == 0x3F800000)
override_chan = 5;
if (value_is_const_uint(*src, 0)) {
override_chan = 4;
} else if (value_is_const_float(*src, 1.0f)) {
override_chan = 5;
}
if (override_chan >= 0) {
+7 -35
View File
@@ -48,9 +48,6 @@ public:
void visit(LDSReadInstr *instr) override { (void)instr; };
void visit(RatInstr *instr) override { (void)instr; };
bool src_is_zero(PVirtualValue value);
bool src_is_one(PVirtualValue value);
void convert_to_mov(AluInstr *alu, int src_idx);
bool progress{false};
@@ -86,25 +83,25 @@ PeepholeVisitor::visit(AluInstr *instr)
switch (instr->opcode()) {
case op2_add:
case op2_add_int:
if (src_is_zero(instr->psrc(0)))
if (value_is_const_uint(instr->src(0), 0))
convert_to_mov(instr, 1);
else if (src_is_zero(instr->psrc(1)))
else if (value_is_const_uint(instr->src(1), 0))
convert_to_mov(instr, 0);
break;
case op2_mul:
case op2_mul_ieee:
if (src_is_one(instr->psrc(0)))
if (value_is_const_float(instr->src(0), 1.0f))
convert_to_mov(instr, 1);
else if (src_is_one(instr->psrc(1)))
else if (value_is_const_float(instr->src(1), 1.0f))
convert_to_mov(instr, 0);
break;
case op3_muladd:
case op3_muladd_ieee:
if (src_is_zero(instr->psrc(0)) || src_is_zero(instr->psrc(1)))
if (value_is_const_uint(instr->src(0), 0) || value_is_const_uint(instr->src(1), 0))
convert_to_mov(instr, 2);
break;
case op2_killne_int:
if (src_is_zero(instr->psrc(1))) {
if (value_is_const_uint(instr->src(1), 0)) {
auto src0 = instr->psrc(0)->as_register();
if (src0 && src0->is_ssa()) {
auto parent = *src0->parents().begin();
@@ -113,35 +110,10 @@ PeepholeVisitor::visit(AluInstr *instr)
progress |= visitor.success;
}
}
default:;
}
}
bool
PeepholeVisitor::src_is_zero(PVirtualValue value)
{
if (value->as_inline_const() && value->as_inline_const()->sel() == ALU_SRC_0)
return true;
if (value->as_literal() && value->as_literal()->value() == 0)
return true;
return false;
}
bool
PeepholeVisitor::src_is_one(PVirtualValue value)
{
if (value->as_inline_const() && value->as_inline_const()->sel() == ALU_SRC_1)
return true;
if (value->as_literal() && value->as_literal()->value() == 0x3f800000)
return true;
return false;
}
void
PeepholeVisitor::convert_to_mov(AluInstr *alu, int src_idx)
{
@@ -169,7 +141,7 @@ PeepholeVisitor::visit(IfInstr *instr)
auto pred = instr->predicate();
auto& src1 = pred->src(1);
if (src1.as_inline_const() && src1.as_inline_const()->sel() == ALU_SRC_0) {
if (value_is_const_uint(src1, 0)) {
auto src0 = pred->src(0).as_register();
if (src0 && src0->is_ssa() && !src0->parents().empty()) {
assert(src0->parents().size() == 1);
@@ -31,6 +31,7 @@
#include "sfn_instr.h"
#include "sfn_valuefactory.h"
#include "util/macros.h"
#include "util/u_math.h"
#include <iomanip>
#include <iostream>
@@ -1205,4 +1206,62 @@ ValueComparer::visit(const InlineConstant& other)
m_result = !!m_inline_constant;
};
class CheckConstValue : public ConstRegisterVisitor {
public:
CheckConstValue(uint32_t _test_value):
test_value(_test_value)
{
}
CheckConstValue(float _test_value):
test_value(fui(_test_value))
{
}
void visit(const Register& value) override { (void)value; }
void visit(const LocalArray& value) override { (void)value; }
void visit(const LocalArrayValue& value) override { (void)value; }
void visit(const UniformValue& value) override { (void)value; }
void visit(const LiteralConstant& value) override
{
result = value.value() == test_value;
}
void visit(const InlineConstant& value) override
{
switch (test_value) {
case 0:
result = value.sel() == ALU_SRC_0;
break;
case 1:
result = value.sel() == ALU_SRC_1_INT;
break;
case 0x3f800000 /* 1.0f */:
result = value.sel() == ALU_SRC_1;
break;
case 0x3f000000 /* 0.5f */:
result = value.sel() == ALU_SRC_0_5;
break;
}
}
uint32_t test_value;
bool result{false};
};
bool
value_is_const_uint(const VirtualValue& val, uint32_t value)
{
CheckConstValue test(value);
val.accept(test);
return test.result;
}
bool
value_is_const_float(const VirtualValue& val, float value)
{
CheckConstValue test(value);
val.accept(test);
return test.result;
}
} // namespace r600
@@ -494,6 +494,11 @@ sfn_value_equal(const T *lhs, const T *rhs)
return true;
}
bool
value_is_const_uint(const VirtualValue& val, uint32_t value);
bool
value_is_const_float(const VirtualValue& val, float value);
class RegisterVisitor {
public:
virtual void visit(Register& value) = 0;