r600/sfn: add register remapping

Make use of the live range evaluation to merge registers. Since the
live ranges are evaluated for register indices, the algorithm is not
optimal, but for most piglits up to glsl-3.3 it does the job.

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3225>
This commit is contained in:
Gert Wollny 2019-12-27 17:49:26 +01:00 committed by Marge Bot
parent 393655d5cb
commit 5c19013904
12 changed files with 171 additions and 0 deletions

View file

@ -62,6 +62,11 @@ AluInstruction::AluInstruction(EAluOp opcode, PValue dest,
if (alu_ops.at(opcode).nsrc == 3)
m_flags.set(alu_op3);
for (auto &s: m_src)
add_remappable_src_value(&s);
add_remappable_dst_value(&m_dest);
}
AluInstruction::AluInstruction(EAluOp opcode, PValue dest, PValue src0,
@ -106,6 +111,30 @@ bool AluInstruction::is_equal_to(const Instruction& lhs) const
return (m_flags == oth.m_flags && m_cf_type == oth.m_cf_type);
}
void AluInstruction::replace_values(const ValueSet& candiates, PValue new_value)
{
for (auto c: candiates) {
if (*c == *m_dest)
m_dest = new_value;
for (auto& s: m_src) {
if (*c == *s)
s = new_value;
}
}
}
PValue AluInstruction::remap_one_registers(PValue reg, std::vector<rename_reg_pair>& map,
ValueMap &values)
{
auto new_index = map[reg->sel()];
if (new_index.valid)
reg = values.get_or_inject(new_index.new_reg, reg->chan());
map[reg->sel()].used = true;
return reg;
}
void AluInstruction::set_flag(AluModifiers flag)
{
m_flags.set(flag);

View file

@ -117,10 +117,14 @@ public:
ECFAluOpCode cf_type() const {return m_cf_type;}
void set_cf_type(ECFAluOpCode cf_type){ m_cf_type = cf_type; }
void replace_values(const ValueSet& candiates, PValue new_value) override;
private:
bool is_equal_to(const Instruction& lhs) const override;
void do_print(std::ostream& os) const override;
PValue remap_one_registers(PValue reg, std::vector<rename_reg_pair>& map,
ValueMap &values);
EAluOp m_opcode;

View file

@ -118,6 +118,26 @@ void Instruction::remap_registers(ValueRemapper& map)
sfn_log << SfnLog::merge << "TO " << *this << "\n\n";
}
void Instruction::add_remappable_src_value(PValue *v)
{
m_mappable_src_registers.push_back(v);
}
void Instruction::add_remappable_src_value(GPRVector *v)
{
m_mappable_src_vectors.push_back(v);
}
void Instruction::add_remappable_dst_value(PValue *v)
{
m_mappable_dst_registers.push_back(v);
}
void Instruction::add_remappable_dst_value(GPRVector *v)
{
m_mappable_dst_vectors.push_back(v);
}
void Instruction::replace_values(UNUSED const ValueSet& candiates, UNUSED PValue new_value)
{

View file

@ -39,8 +39,31 @@
namespace r600 {
struct rename_reg_pair {
bool valid;
bool used;
int new_reg;
};
class LiverangeEvaluator;
class ValueMap;
class ValueRemapper {
public:
ValueRemapper(std::vector<rename_reg_pair>& m,
ValueMap& values);
void remap(PValue& v);
void remap(GPRVector& v);
private:
PValue remap_one_registers(PValue& reg);
std::vector<rename_reg_pair>& m_map;
ValueMap& m_values;
};
using OutputRegisterMap = std::map<unsigned, const GPRVector *>;
class Instruction {
@ -80,8 +103,19 @@ public:
void print(std::ostream& os) const;
virtual void replace_values(const ValueSet& candiates, PValue new_value);
void evalue_liveness(LiverangeEvaluator& eval) const;
void remap_registers(ValueRemapper& map);
protected:
void add_remappable_src_value(PValue *v);
void add_remappable_src_value(GPRVector *v);
void add_remappable_dst_value(PValue *v);
void add_remappable_dst_value(GPRVector *v);
private:
virtual void do_evalue_liveness(LiverangeEvaluator& eval) const;
@ -92,6 +126,10 @@ private:
virtual void do_print(std::ostream& os) const = 0;
std::vector<PValue*> m_mappable_src_registers;
std::vector<GPRVector*> m_mappable_src_vectors;
std::vector<PValue*> m_mappable_dst_registers;
std::vector<GPRVector*> m_mappable_dst_vectors;
};
using PInstruction=Instruction::Pointer;

View file

@ -45,6 +45,7 @@ IfInstruction::IfInstruction(AluInstruction *pred):
m_pred(pred)
{
PValue *v = m_pred->psrc(0);
add_remappable_src_value(v);
}
void IfInstruction::do_evalue_liveness(LiverangeEvaluator& eval) const

View file

@ -34,6 +34,28 @@ namespace r600 {
WriteoutInstruction::WriteoutInstruction(instr_type t, const GPRVector& value):
Instruction(t),
m_value(value)
{
add_remappable_src_value(&m_value);
}
void WriteoutInstruction::replace_values(const ValueSet& candiates, PValue new_value)
{
// I wonder whether we can actually end up here ...
for (auto c: candiates) {
if (*c == *m_value.reg_i(c->chan()))
m_value.set_reg_i(c->chan(), new_value);
}
replace_values_child(candiates, new_value);
}
void WriteoutInstruction::replace_values_child(UNUSED const ValueSet& candiates,
UNUSED PValue new_value)
{
}
void WriteoutInstruction::remap_registers_child(UNUSED std::vector<rename_reg_pair>& map,
UNUSED ValueMap& values)
{
}

View file

@ -33,10 +33,15 @@ namespace r600 {
class WriteoutInstruction: public Instruction {
public:
void replace_values(const ValueSet& candiates, PValue new_value) override;
const GPRVector& gpr() const {return m_value;}
const GPRVector *gpr_ptr() const {return &m_value;}
protected:
WriteoutInstruction(instr_type t, const GPRVector& value);
private:
virtual void replace_values_child(const ValueSet& candiates, PValue new_value);
virtual void remap_registers_child(std::vector<rename_reg_pair>& map,
ValueMap& values);
GPRVector m_value;
};

View file

@ -69,6 +69,10 @@ FetchInstruction::FetchInstruction(EVFetchInstr op,
m_num_format = vtx_nf_scaled;
}
add_remappable_src_value(&m_src);
add_remappable_src_value(&m_buffer_offset);
add_remappable_dst_value(&m_dst);
}
/* Resource query */
@ -115,6 +119,9 @@ FetchInstruction::FetchInstruction(EVFetchInstr vc_opcode,
m_buffer_offset(buffer_offset),
m_dest_swizzle(dest_swizzle)
{
add_remappable_src_value(&m_src);
add_remappable_dst_value(&m_dst);
add_remappable_src_value(&m_buffer_offset);
}
FetchInstruction::FetchInstruction(GPRVector dst,
@ -146,6 +153,10 @@ FetchInstruction::FetchInstruction(GPRVector dst,
m_dest_swizzle({0,1,2,3})
{
m_flags.set(vtx_format_comp_signed);
add_remappable_src_value(&m_src);
add_remappable_dst_value(&m_dst);
add_remappable_src_value(&m_buffer_offset);
}
@ -177,6 +188,9 @@ FetchInstruction::FetchInstruction(GPRVector dst,
m_dest_swizzle({0,1,2,3})
{
m_flags.set(vtx_format_comp_signed);
add_remappable_src_value(&m_src);
add_remappable_dst_value(&m_dst);
add_remappable_src_value(&m_buffer_offset);
}
FetchInstruction::FetchInstruction(GPRVector dst, PValue src, int scratch_size):
@ -212,6 +226,23 @@ FetchInstruction::FetchInstruction(GPRVector dst, PValue src, int scratch_size):
m_indexed = true;
m_array_size = scratch_size - 1;
}
add_remappable_src_value(&m_src);
add_remappable_dst_value(&m_dst);
add_remappable_src_value(&m_buffer_offset);
}
void FetchInstruction::replace_values(const ValueSet& candiates, PValue new_value)
{
if (!m_src)
return;
for (auto c: candiates) {
for (int i = 0; i < 4; ++i) {
if (*c == *m_dst.reg_i(i))
m_dst.set_reg_i(i, new_value);
}
if (*m_src == *c)
m_src = new_value;
}
}

View file

@ -78,6 +78,7 @@ public:
FetchInstruction(GPRVector dst, PValue src, int scratch_size);
void replace_values(const ValueSet& candiates, PValue new_value) override;
EVFetchInstr vc_opcode() const { return m_vc_opcode;}
EVFetchType fetch_type() const { return m_fetch_type;}
@ -111,6 +112,7 @@ public:
void set_buffer_offset(PValue buffer_offset) {
m_buffer_offset = buffer_offset;
add_remappable_src_value(&m_buffer_offset);
}
PValue buffer_offset() const { return m_buffer_offset; }

View file

@ -45,6 +45,10 @@ TexInstruction::TexInstruction(Opcode op, const GPRVector &dest, const GPRVector
{
memset(m_offset, 0, sizeof (m_offset));
add_remappable_src_value(&m_src);
add_remappable_src_value(&m_sampler_offset);
add_remappable_dst_value(&m_dst);
}
void TexInstruction::set_gather_comp(int cmp)
@ -52,6 +56,17 @@ void TexInstruction::set_gather_comp(int cmp)
m_inst_mode = cmp;
}
void TexInstruction::replace_values(const ValueSet& candiates, PValue new_value)
{
// I wonder whether we can actually end up here ...
for (auto c: candiates) {
if (*c == *m_src.reg_i(c->chan()))
m_src.set_reg_i(c->chan(), new_value);
if (*c == *m_dst.reg_i(c->chan()))
m_dst.set_reg_i(c->chan(), new_value);
}
}
void TexInstruction::set_offset(unsigned index, int32_t val)
{
assert(index < 3);

View file

@ -81,6 +81,8 @@ public:
unsigned sampler_id() const {return m_sampler_id;}
unsigned resource_id() const {return m_resource_id;}
void replace_values(const ValueSet& candiates, PValue new_value) override;
void set_offset(unsigned index, int32_t val);
int get_offset(unsigned index) const;

View file

@ -71,6 +71,8 @@ public:
void split_constants(nir_alu_instr* instr);
void load_uniform(const nir_alu_src& src);
void remap_registers();
const nir_variable *get_deref_location(const nir_src& src) const;
protected: