summaryrefslogtreecommitdiff
path: root/lib/mesa/src/gallium
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2023-01-28 08:13:08 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2023-01-28 08:13:08 +0000
commitee52993c44af63caaa2f544a9e4020ba4eb37d39 (patch)
treea209c970e0bf59c4819241f601794eb83ad6b8d0 /lib/mesa/src/gallium
parentc663cb4f7e657194076d58f6a11b422a21271ccd (diff)
Import Mesa 22.3.4
Diffstat (limited to 'lib/mesa/src/gallium')
-rw-r--r--lib/mesa/src/gallium/drivers/r600/sfn/sfn_optimizer.cpp270
1 files changed, 50 insertions, 220 deletions
diff --git a/lib/mesa/src/gallium/drivers/r600/sfn/sfn_optimizer.cpp b/lib/mesa/src/gallium/drivers/r600/sfn/sfn_optimizer.cpp
index 06d2ebd64..a3ad4922a 100644
--- a/lib/mesa/src/gallium/drivers/r600/sfn/sfn_optimizer.cpp
+++ b/lib/mesa/src/gallium/drivers/r600/sfn/sfn_optimizer.cpp
@@ -32,11 +32,8 @@
#include "sfn_instr_export.h"
#include "sfn_instr_fetch.h"
#include "sfn_instr_lds.h"
-#include "sfn_instr_mem.h"
#include "sfn_instr_tex.h"
#include "sfn_peephole.h"
-#include "sfn_valuefactory.h"
-#include "sfn_virtualvalues.h"
#include <sstream>
@@ -238,7 +235,7 @@ DCEVisitor::visit(Block *block)
class CopyPropFwdVisitor : public InstrVisitor {
public:
- CopyPropFwdVisitor(ValueFactory& vf);
+ CopyPropFwdVisitor();
void visit(AluInstr *instr) override;
void visit(AluGroup *instr) override;
@@ -252,7 +249,7 @@ public:
void visit(StreamOutInstr *instr) override { (void)instr; }
void visit(MemRingOutInstr *instr) override { (void)instr; }
void visit(EmitVertexInstr *instr) override { (void)instr; }
- void visit(GDSInstr *instr) override;
+ void visit(GDSInstr *instr) override { (void)instr; };
void visit(WriteTFInstr *instr) override { (void)instr; };
void visit(RatInstr *instr) override { (void)instr; };
@@ -261,9 +258,7 @@ public:
void visit(LDSReadInstr *instr) override { (void)instr; };
void propagate_to(RegisterVec4& src, Instr *instr);
- bool assigned_register_direct(PRegister reg);
- ValueFactory& value_factory;
bool progress;
};
@@ -296,7 +291,7 @@ bool
copy_propagation_fwd(Shader& shader)
{
auto& root = shader.func();
- CopyPropFwdVisitor copy_prop(shader.value_factory());
+ CopyPropFwdVisitor copy_prop;
do {
copy_prop.progress = false;
@@ -335,9 +330,8 @@ copy_propagation_backward(Shader& shader)
return copy_prop.progress;
}
-CopyPropFwdVisitor::CopyPropFwdVisitor(ValueFactory& vf):
- value_factory(vf),
- progress(false)
+CopyPropFwdVisitor::CopyPropFwdVisitor():
+ progress(false)
{
}
@@ -360,16 +354,6 @@ CopyPropFwdVisitor::visit(AluInstr *instr)
auto src = instr->psrc(0);
auto dest = instr->dest();
- /* Don't propagate an indirect load to more than one
- * instruction, because we may have to split the address loads
- * creating more instructions */
- if (dest->uses().size() > 1) {
- auto [addr, is_for_dest, index] = instr->indirect_addr();
- if (addr && !is_for_dest)
- return;
- }
-
-
auto ii = dest->uses().begin();
auto ie = dest->uses().end();
@@ -378,7 +362,7 @@ CopyPropFwdVisitor::visit(AluInstr *instr)
++ii;
/* SSA can always be propagated, registers only in the same block
* and only if they are assigned in the same block */
- bool can_propagate = dest->has_flag(Register::ssa);
+ bool can_propagate = dest->is_ssa();
if (!can_propagate) {
@@ -407,11 +391,7 @@ CopyPropFwdVisitor::visit(AluInstr *instr)
if (can_propagate) {
sfn_log << SfnLog::opt << " Try replace in " << i->block_id() << ":"
<< i->index() << *i << "\n";
-
- if (i->as_alu() && i->as_alu()->parent_group()) {
- progress |= i->as_alu()->parent_group()->replace_source(dest, src);
- } else
- progress |= i->replace_source(dest, src);
+ progress |= i->replace_source(dest, src);
}
}
if (instr->dest()) {
@@ -432,190 +412,67 @@ CopyPropFwdVisitor::visit(TexInstr *instr)
propagate_to(instr->src(), instr);
}
-void CopyPropFwdVisitor::visit(GDSInstr *instr)
-{
- propagate_to(instr->src(), instr);
-}
-
void
CopyPropFwdVisitor::visit(ExportInstr *instr)
{
propagate_to(instr->value(), instr);
}
-static bool register_sel_can_change(Pin pin)
-{
- return pin == pin_free || pin == pin_none;
-}
-
-static bool register_chan_is_pinned(Pin pin)
-{
- return pin == pin_chan ||
- pin == pin_fully ||
- pin == pin_chgr;
-}
-
-
void
-CopyPropFwdVisitor::propagate_to(RegisterVec4& value, Instr *instr)
+CopyPropFwdVisitor::propagate_to(RegisterVec4& src, Instr *instr)
{
- /* Collect parent instructions - only ALU move without modifiers
- * and without indirect access are allowed. */
AluInstr *parents[4] = {nullptr};
- bool have_candidates = false;
for (int i = 0; i < 4; ++i) {
- if (value[i]->chan() < 4 && value[i]->has_flag(Register::ssa)) {
+ if (src[i]->chan() < 4 && src[i]->is_ssa()) {
/* We have a pre-define value, so we can't propagate a copy */
- if (value[i]->parents().empty())
+ if (src[i]->parents().empty())
return;
- if (value[i]->uses().size() > 1)
- return;
-
- assert(value[i]->parents().size() == 1);
- parents[i] = (*value[i]->parents().begin())->as_alu();
-
- /* Parent op is not an ALU instruction, so we can't
- copy-propagate */
- if (!parents[i])
- return;
-
-
- if ((parents[i]->opcode() != op1_mov) ||
- parents[i]->has_alu_flag(alu_src0_neg) ||
- parents[i]->has_alu_flag(alu_src0_abs) ||
- parents[i]->has_alu_flag(alu_dst_clamp) ||
- parents[i]->has_alu_flag(alu_src0_rel) ||
- std::get<0>(parents[i]->indirect_addr()))
- return;
- have_candidates = true;
+ assert(src[i]->parents().size() == 1);
+ parents[i] = (*src[i]->parents().begin())->as_alu();
}
}
-
- if (!have_candidates)
- return;
-
- /* Collect the new source registers. We may have to move all registers
- * to a new virtual sel index. */
-
PRegister new_src[4] = {0};
- int new_chan[4] = {0,0,0,0};
-
- uint8_t used_chan_mask = 0;
- int new_sel = -1;
- bool all_sel_can_change = true;
-
- bool is_ssa = true;
+ int sel = -1;
for (int i = 0; i < 4; ++i) {
-
- /* No parent means we either ignore the channel or insert 0 or 1.*/
if (!parents[i])
continue;
-
- unsigned allowed_mask = 0xf & ~used_chan_mask;
-
- auto src = parents[i]->src(0).as_register();
- if (!src)
- return;
-
- /* Don't accept an array element for now, we would need extra checking
- * that the value is not overwritten by an indirect access */
- if (src->pin() == pin_array)
- return;
-
- /* Is this check still needed ? */
- if (!src->has_flag(Register::ssa) &&
- !assigned_register_direct(src)) {
+ if ((parents[i]->opcode() != op1_mov) || parents[i]->has_alu_flag(alu_src0_neg) ||
+ parents[i]->has_alu_flag(alu_src0_abs) ||
+ parents[i]->has_alu_flag(alu_dst_clamp) ||
+ parents[i]->has_alu_flag(alu_src0_rel)) {
return;
- }
-
- /* If the channel chan't switch we have to update the channel mask
- * TODO: assign channel pinned registers first might give more
- * opportunities for this optimization */
- if (register_chan_is_pinned(src->pin()))
- allowed_mask = 1 << src->chan();
-
- /* Update the possible channel mask based on the sourcee's parent
- * instruction(s) */
- for (auto p : src->parents()) {
- auto alu = p->as_alu();
- if (alu)
- allowed_mask &= alu->allowed_dest_chan_mask();
- }
-
- for (auto u : src->uses()) {
- auto alu = u->as_alu();
- if (alu)
- allowed_mask &= alu->allowed_src_chan_mask();
- }
-
- if (!allowed_mask)
- return;
-
- /* Prefer keeping the channel, but if that's not possible
- * i.e. if the sel has to change, then pick the next free channel
- * (see below) */
- new_chan[i] = src->chan();
-
- if (new_sel < 0) {
- new_sel = src->sel();
- is_ssa = src->has_flag(Register::ssa);
- } else if (new_sel != src->sel()) {
- /* If we have to assign a new register sel index do so only
- * if all already assigned source can get a new register index,
- * and all registers are either SSA or registers.
- * TODO: check whether this last restriction is required */
- if (all_sel_can_change &&
- register_sel_can_change(src->pin()) &&
- (is_ssa == src->has_flag(Register::ssa))) {
- new_sel = value_factory.new_register_index();
- new_chan[i] = u_bit_scan(&allowed_mask);
- } else /* Sources can't be combined to a vec4 so bail out */
+ } else {
+ auto src = parents[i]->src(0).as_register();
+ if (!src)
return;
+ else if (!src->is_ssa())
+ return;
+ else if (sel < 0)
+ sel = src->sel();
+ else if (sel != src->sel())
+ return;
+ new_src[i] = src;
}
-
- new_src[i] = src;
- used_chan_mask |= 1 << new_chan[i];
- if (!register_sel_can_change(src->pin()))
- all_sel_can_change = false;
}
- /* Apply the changes to the vec4 source */
- value.del_use(instr);
for (int i = 0; i < 4; ++i) {
if (parents[i]) {
- new_src[i]->set_sel(new_sel);
- if (is_ssa)
- new_src[i]->set_flag(Register::ssa);
- new_src[i]->set_chan(new_chan[i]);
-
- value.set_value(i, new_src[i]);
-
+ src.del_use(instr);
+ src.set_value(i, new_src[i]);
if (new_src[i]->pin() != pin_fully) {
if (new_src[i]->pin() == pin_chan)
new_src[i]->set_pin(pin_chgr);
else
new_src[i]->set_pin(pin_group);
}
+ src.add_use(instr);
progress |= true;
}
}
- value.add_use(instr);
if (progress)
- value.validate();
-}
-
-bool CopyPropFwdVisitor::assigned_register_direct(PRegister reg)
-{
- for (auto p: reg->parents()) {
- if (p->as_alu()) {
- auto [addr, is_regoffs, is_index] = p->as_alu()->indirect_addr();
- if (addr)
- return false;
- }
- }
- return true;
+ src.validate();
}
void
@@ -661,7 +518,7 @@ CopyPropBackVisitor::visit(AluInstr *instr)
return;
}
- if (!dest->has_flag(Register::ssa) && dest->parents().size() > 1)
+ if (!dest->is_ssa() && dest->parents().size() > 1)
return;
for (auto& i : src_reg->parents()) {
@@ -743,36 +600,6 @@ public:
bool progress;
};
-class HasVecDestVisitor : public ConstInstrVisitor {
-public:
- HasVecDestVisitor():
- has_group_dest(false)
- {
- }
-
- void visit(const AluInstr& instr) override { (void)instr; }
- void visit(const AluGroup& instr) override { (void)instr; }
- void visit(const TexInstr& instr) override { (void)instr; has_group_dest = true; };
- void visit(const ExportInstr& instr) override { (void)instr; }
- void visit(const FetchInstr& instr) override { (void)instr; has_group_dest = true; };
- void visit(const Block& instr) override { (void)instr; };
- void visit(const ControlFlowInstr& instr) override{ (void)instr; }
- void visit(const IfInstr& instr) override{ (void)instr; }
- void visit(const ScratchIOInstr& instr) override { (void)instr; };
- void visit(const StreamOutInstr& instr) override { (void)instr; }
- void visit(const MemRingOutInstr& instr) override { (void)instr; }
- void visit(const EmitVertexInstr& instr) override { (void)instr; }
- void visit(const GDSInstr& instr) override { (void)instr; }
- void visit(const WriteTFInstr& instr) override { (void)instr; };
- void visit(const LDSAtomicInstr& instr) override { (void)instr; };
- void visit(const LDSReadInstr& instr) override { (void)instr; };
- void visit(const RatInstr& instr) override { (void)instr; };
-
- bool has_group_dest;
-};
-
-
-
bool
simplify_source_vectors(Shader& sh)
{
@@ -798,16 +625,6 @@ SimplifySourceVecVisitor::visit(TexInstr *instr)
if (nvals == 1) {
for (int i = 0; i < 4; ++i)
if (src[i]->chan() < 4) {
- HasVecDestVisitor check_dests;
- for (auto p : src[i]->parents()) {
- p->accept(check_dests);
- if (check_dests.has_group_dest)
- break;
- }
-
- if (check_dests.has_group_dest)
- break;
-
if (src[i]->pin() == pin_group)
src[i]->set_pin(pin_free);
else if (src[i]->pin() == pin_chgr)
@@ -861,7 +678,7 @@ SimplifySourceVecVisitor::replace_src(Instr *instr, RegisterVec4& reg4)
if (s->chan() > 3)
continue;
- if (!s->has_flag(Register::ssa))
+ if (!s->is_ssa())
continue;
/* Cayman trans ops have more then one parent for
@@ -905,10 +722,23 @@ ReplaceConstSource::visit(AluInstr *alu)
int override_chan = -1;
- if (value_is_const_uint(*src, 0)) {
- override_chan = 4;
- } else if (value_is_const_float(*src, 1.0f)) {
- override_chan = 5;
+ 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 (override_chan >= 0) {