r600/sfn: add register remapping
authorGert Wollny <gert.wollny@collabora.com>
Fri, 27 Dec 2019 16:49:26 +0000 (17:49 +0100)
committerMarge Bot <eric+marge@anholt.net>
Mon, 10 Feb 2020 19:09:08 +0000 (19:09 +0000)
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>

12 files changed:
src/gallium/drivers/r600/sfn/sfn_instruction_alu.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_alu.h
src/gallium/drivers/r600/sfn/sfn_instruction_base.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_base.h
src/gallium/drivers/r600/sfn/sfn_instruction_cf.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_export.h
src/gallium/drivers/r600/sfn/sfn_instruction_fetch.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_fetch.h
src/gallium/drivers/r600/sfn/sfn_instruction_tex.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_tex.h
src/gallium/drivers/r600/sfn/sfn_shader_base.h

index dffc39b916415051ab202b9ee80d4c199fa08cd7..4143b9c52d7d1bf1d5797202ce238ce911806897 100644 (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);
index 67b641511b72bc8e7b5c98e3e04ee0106fb406bd..ea95f72fb0795f2f3c579dfc489287ccb10ead83 100644 (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;
index 4e4e28f1436fd8908ee0eb114ba72c15caf023f4..22dfa5739f52879455c5bc5c2a5af8d0522b55e0 100644 (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)
 {
 
index e44154ebe918cf0dcb7410902eb96753a15a7b44..c655de96ed512ca92bd68bef8206487e96d1583f 100644 (file)
 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;
index 82b0f47403ad70c674eebaecfe3463f7ca96ac0e..0c10e162bee43fc9bfa0fc0916d791038da6f879 100644 (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
index 14ae52f325ee0705cc77127260fb291fb5beb95c..d3a07713fa7094c6f9b31a3d5f31e3cf3c1d95a3 100644 (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)
 {
 }
 
index 0ea493865af6daf153bd715dcefd0917d9f29ee6..1971e3391353ee82eca1b438ed6b14c25b821dc1 100644 (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;
 };
index 9bd23be809cb5adee071fcda63dfa3d96417b99c..c41692639b997283113dd555368acaa7712039a6 100644 (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;
+   }
 }
 
 
index 0ed41316235e77e59155e90871236bb89c5d6f2c..369094edfa7ca3751d350db3581ccda4489de258 100644 (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; }
 
index c0f37009f18a9a07d7ee7a4e6d2fbf28353cc5c6..0e7b63db57024e25ca51a443c94f01a7a5970276 100644 (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);
index ff5ef1ee1f25eb717d633c0032b8489b2e54a81b..d6f353024990ae760ecfb0bf134109be8f82fe5a 100644 (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;
 
index 0a12d1ca83542d204ed800335f0396c486f3c28b..b9184fda2fbfb7ae78f4e50ffe50ebd48d92aac0 100644 (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: