• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mesa-c++  -*-
2  *
3  * Copyright (c) 2022 Collabora LTD
4  *
5  * Author: Gert Wollny <gert.wollny@collabora.com>
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * on the rights to use, copy, modify, merge, publish, distribute, sub
11  * license, and/or sell copies of the Software, and to permit persons to whom
12  * the Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the next
15  * paragraph) shall be included in all copies or substantial portions of the
16  * Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 
27 #ifndef INSTRALU_H
28 #define INSTRALU_H
29 
30 #include "sfn_instr.h"
31 
32 #include <unordered_set>
33 
34 struct nir_alu_instr;
35 
36 namespace r600 {
37 
38 class Shader;
39 class ValueFactory;
40 
41 class AluInstr : public Instr {
42 public:
43 
44    using SrcValues = std::vector<PVirtualValue, Allocator<PVirtualValue>>;
45 
46    enum Op2Options {
47       op2_opt_none = 0,
48       op2_opt_reverse = 1,
49       op2_opt_neg_src1 = 1 << 1,
50       op2_opt_abs_src0 = 1 << 2
51    };
52 
53    static constexpr const AluBankSwizzle bs[6] = {
54       alu_vec_012,
55       alu_vec_021,
56       alu_vec_120,
57       alu_vec_102,
58       alu_vec_201,
59       alu_vec_210
60    };
61 
62    static const AluModifiers src_abs_flags[2];
63    static const AluModifiers src_neg_flags[3];
64    static const AluModifiers src_rel_flags[3];
65 
66    AluInstr(EAluOp opcode);
67    AluInstr(EAluOp opcode, int chan);
68    AluInstr(EAluOp opcode, PRegister dest,
69             SrcValues src0,
70             const std::set<AluModifiers>& flags, int alu_slot);
71 
72    AluInstr(EAluOp opcode, PRegister dest, PVirtualValue src0,
73             const std::set<AluModifiers>& flags);
74 
75    AluInstr(EAluOp opcode, PRegister dest,
76             PVirtualValue src0, PVirtualValue src1,
77             const std::set<AluModifiers>& flags);
78 
79    AluInstr(EAluOp opcode, PRegister dest, PVirtualValue src0, PVirtualValue src1,
80             PVirtualValue src2,
81             const std::set<AluModifiers>& flags);
82 
83    AluInstr(ESDOp op, PVirtualValue src0, PVirtualValue src1, PVirtualValue address);
84    AluInstr(ESDOp op, const SrcValues& src, const std::set<AluModifiers>& flags);
85 
86    void accept(ConstInstrVisitor& visitor) const override;
87    void accept(InstrVisitor& visitor) override;
88 
opcode()89    auto opcode() const {assert(!has_alu_flag(alu_is_lds)); return m_opcode;}
lds_opcode()90    auto lds_opcode() const {assert(has_alu_flag(alu_is_lds)); return m_lds_opcode;}
91 
92    bool can_propagate_src() const;
93    bool can_propagate_dest() const;
94 
95    bool replace_source(PRegister old_src, PVirtualValue new_src) override;
96    bool replace_dest(PRegister new_dest, AluInstr *move_instr) override;
97 
set_op(EAluOp op)98    void set_op(EAluOp op) {m_opcode = op;}
99 
dest()100    PRegister dest() const {return m_dest;}
n_sources()101    unsigned n_sources() const {return m_src.size();}
102 
dest_chan()103    int dest_chan() const {return m_dest ? m_dest->chan() : m_fallback_chan;}
104 
psrc(unsigned i)105    PVirtualValue psrc(unsigned i) {return i < m_src.size() ? m_src[i] : nullptr;}
src(unsigned i)106    VirtualValue& src(unsigned i) {assert(i < m_src.size() && m_src[i]); return *m_src[i];}
src(unsigned i)107    const VirtualValue& src(unsigned i) const {assert(i < m_src.size() && m_src[i]); return *m_src[i];}
108 
109    void set_sources(SrcValues src);
sources()110    const SrcValues& sources() const {return m_src;}
111    void pin_sources_to_chan();
112 
113    int register_priority() const;
114 
reset_alu_flag(AluModifiers flag)115    void reset_alu_flag(AluModifiers flag) {m_alu_flags.reset(flag);}
set_alu_flag(AluModifiers flag)116    void set_alu_flag(AluModifiers flag) {m_alu_flags.set(flag);}
has_alu_flag(AluModifiers f)117    bool has_alu_flag(AluModifiers f) const {return m_alu_flags.test(f);}
118 
cf_type()119    ECFAluOpCode cf_type() const {return m_cf_type;}
set_cf_type(ECFAluOpCode cf_type)120    void set_cf_type(ECFAluOpCode cf_type){ m_cf_type = cf_type; }
set_bank_swizzle(AluBankSwizzle swz)121    void set_bank_swizzle(AluBankSwizzle swz) {m_bank_swizzle = swz;}
bank_swizzle()122    AluBankSwizzle bank_swizzle() const {return m_bank_swizzle;}
123 
set_index_offset(unsigned offs)124    void set_index_offset(unsigned offs) {m_idx_offset = offs;}
index_offset()125    auto  index_offset() const {return m_idx_offset;}
126 
127    bool is_equal_to(const AluInstr& lhs) const;
128 
129    bool has_lds_access() const;
130    bool has_lds_queue_read() const;
131 
132    static const std::map<ECFAluOpCode, std::string> cf_map;
133    static const std::map<AluBankSwizzle, std::string> bank_swizzle_map;
134    static Instr::Pointer from_string(std::istream &is, ValueFactory& value_factory, AluGroup *);
135    static bool from_nir(nir_alu_instr *alu, Shader& shader);
136 
alu_slots()137    int alu_slots() const {return m_alu_slots;}
138 
139    AluGroup *split(ValueFactory &vf);
140 
end_group()141    bool end_group() const override { return m_alu_flags.test(alu_last_instr);}
142 
143    static const std::set<AluModifiers> empty;
144    static const std::set<AluModifiers> write;
145    static const std::set<AluModifiers> last;
146    static const std::set<AluModifiers> last_write;
147 
148    std::tuple<PRegister, bool, bool> indirect_addr() const;
149 
150    void add_extra_dependency(PVirtualValue reg);
151 
set_required_slots(int nslots)152    void set_required_slots(int nslots) { m_required_slots = nslots;}
required_slots()153    unsigned  required_slots() const { return m_required_slots;}
154 
add_priority(int priority)155    void add_priority(int priority) { m_priority += priority;}
priority()156    int priority() const { return m_priority;}
inc_priority()157    void inc_priority() { ++m_priority;}
158 
set_parent_group(AluGroup * group)159    void set_parent_group(AluGroup *group) { m_parent_group = group;}
160 
161 private:
162    friend class AluGroup;
163 
164    void update_uses();
165 
166    bool do_ready() const override;
167 
168    bool can_copy_propagate() const;
169 
170    bool check_readport_validation(PRegister old_src, PVirtualValue new_src) const;
171 
set_alu_flags(const AluOpFlags & flags)172    void set_alu_flags(const AluOpFlags& flags) { m_alu_flags = flags; }
173    bool propagate_death() override;
174 
175    void do_print(std::ostream& os) const override;
176 
177    union {
178       EAluOp m_opcode;
179       ESDOp m_lds_opcode;
180    };
181 
182    PRegister m_dest{nullptr};
183    SrcValues m_src;
184 
185    AluOpFlags m_alu_flags;
186    AluBankSwizzle m_bank_swizzle{alu_vec_unknown};
187    ECFAluOpCode m_cf_type{cf_alu};
188    int m_alu_slots{1};
189    int m_fallback_chan{0};
190    unsigned m_idx_offset{0};
191    unsigned m_required_slots{0};
192    int m_priority{0};
193    std::set<PRegister, std::less<PRegister>, Allocator<PRegister>> m_extra_dependencies;
194    AluGroup *m_parent_group{nullptr};
195 };
196 
197 class AluInstrVisitor : public InstrVisitor {
198 public:
199    void visit(AluGroup *instr) override;
200    void visit(Block *instr) override;
201    void visit(IfInstr *instr) override;
202 
visit(TexInstr * instr)203    void visit(TexInstr *instr) override {(void)instr;}
visit(ExportInstr * instr)204    void visit(ExportInstr *instr) override {(void)instr;}
visit(FetchInstr * instr)205    void visit(FetchInstr *instr) override {(void)instr;}
visit(ControlFlowInstr * instr)206    void visit(ControlFlowInstr *instr) override {(void)instr;}
visit(ScratchIOInstr * instr)207    void visit(ScratchIOInstr *instr) override {(void)instr;}
visit(StreamOutInstr * instr)208    void visit(StreamOutInstr *instr) override {(void)instr;}
visit(MemRingOutInstr * instr)209    void visit(MemRingOutInstr *instr) override {(void)instr;}
visit(EmitVertexInstr * instr)210    void visit(EmitVertexInstr *instr) override {(void)instr;}
visit(GDSInstr * instr)211    void visit(GDSInstr *instr) override {(void)instr;};
visit(WriteTFInstr * instr)212    void visit(WriteTFInstr *instr) override {(void)instr;};
visit(LDSAtomicInstr * instr)213    void visit(LDSAtomicInstr *instr) override {(void)instr;};
visit(LDSReadInstr * instr)214    void visit(LDSReadInstr *instr) override {(void)instr;};
visit(RatInstr * instr)215    void visit(RatInstr *instr) override {(void)instr;};
216 };
217 
218 
219 }
220 #endif // INSTRALU_H
221