1bf215546Sopenharmony_ci/* -*- mesa-c++ -*- 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright (c) 2021 Collabora LTD 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Author: Gert Wollny <gert.wollny@collabora.com> 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 10bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub 11bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom 12bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 15bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 16bf215546Sopenharmony_ci * Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 22bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#pragma once 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "sfn_virtualvalues.h" 30bf215546Sopenharmony_ci#include "sfn_alu_defines.h" 31bf215546Sopenharmony_ci#include "sfn_defines.h" 32bf215546Sopenharmony_ci#include <set> 33bf215546Sopenharmony_ci#include <list> 34bf215546Sopenharmony_ci#include <iostream> 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cinamespace r600 { 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ciclass ConstInstrVisitor; 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ciclass InstrVisitor; 41bf215546Sopenharmony_ciclass AluInstr; 42bf215546Sopenharmony_ciclass AluGroup; 43bf215546Sopenharmony_ciclass TexInstr; 44bf215546Sopenharmony_ciclass ExportInstr; 45bf215546Sopenharmony_ciclass FetchInstr; 46bf215546Sopenharmony_ciclass ControlFlowInstr; 47bf215546Sopenharmony_ciclass IfInstr; 48bf215546Sopenharmony_ciclass ScratchIOInstr; 49bf215546Sopenharmony_ciclass StreamOutInstr; 50bf215546Sopenharmony_ciclass MemRingOutInstr; 51bf215546Sopenharmony_ciclass EmitVertexInstr; 52bf215546Sopenharmony_ciclass GDSInstr; 53bf215546Sopenharmony_ciclass WriteTFInstr; 54bf215546Sopenharmony_ciclass LDSAtomicInstr; 55bf215546Sopenharmony_ciclass LDSReadInstr; 56bf215546Sopenharmony_ciclass RatInstr; 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ciint int_from_string_with_prefix(const std::string& str, const std::string& prefix); 60bf215546Sopenharmony_ciint sel_and_szw_from_string(const std::string& str, RegisterVec4::Swizzle& swz, bool& is_ssa); 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ciclass Instr : public Allocate { 63bf215546Sopenharmony_cipublic: 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci enum Flags { 66bf215546Sopenharmony_ci always_keep, 67bf215546Sopenharmony_ci dead, 68bf215546Sopenharmony_ci scheduled, 69bf215546Sopenharmony_ci vpm, 70bf215546Sopenharmony_ci force_cf, 71bf215546Sopenharmony_ci ack_rat_return_write, 72bf215546Sopenharmony_ci nflags 73bf215546Sopenharmony_ci }; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci Instr(); 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci Instr(const Instr& orig) = default; 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci virtual ~Instr(); 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci using Pointer = R600_POINTER_TYPE(Instr); 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci void print(std::ostream& os) const; 84bf215546Sopenharmony_ci bool equal_to(const Instr& lhs) const; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci virtual void accept(ConstInstrVisitor& visitor) const = 0; 87bf215546Sopenharmony_ci virtual void accept(InstrVisitor& visitor) = 0; 88bf215546Sopenharmony_ci virtual bool end_group() const { return true;} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci virtual bool is_last() const; 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci void set_always_keep() {m_instr_flags.set(always_keep);} 93bf215546Sopenharmony_ci bool set_dead(); 94bf215546Sopenharmony_ci virtual void set_scheduled() { m_instr_flags.set(scheduled); forward_set_scheduled();} 95bf215546Sopenharmony_ci void add_use() {++m_use_count;} 96bf215546Sopenharmony_ci void dec_use() {assert(m_use_count > 0); --m_use_count;} 97bf215546Sopenharmony_ci bool is_dead() const {return m_instr_flags.test(dead);} 98bf215546Sopenharmony_ci bool is_scheduled() const {return m_instr_flags.test(scheduled);} 99bf215546Sopenharmony_ci bool keep() const {return m_instr_flags.test(always_keep);} 100bf215546Sopenharmony_ci bool has_uses() const {return m_use_count > 0;} 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci bool has_instr_flag(Flags f) const {return m_instr_flags.test(f);} 103bf215546Sopenharmony_ci void set_instr_flag(Flags f) { m_instr_flags.set(f);} 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci virtual bool replace_source(PRegister old_src, PVirtualValue new_src); 106bf215546Sopenharmony_ci virtual bool replace_dest(PRegister new_dest, AluInstr *move_instr); 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci virtual int nesting_corr() const { return 0;} 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci virtual bool end_block() const { return false;} 111bf215546Sopenharmony_ci virtual int nesting_offset() const { return 0;} 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci void set_blockid(int id, int index); 114bf215546Sopenharmony_ci int block_id() const {return m_block_id;} 115bf215546Sopenharmony_ci int index() const { return m_index;} 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci void add_required_instr(Instr *instr); 118bf215546Sopenharmony_ci void replace_required_instr(Instr *old_instr, Instr *new_instr); 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci bool ready() const; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci virtual uint32_t slots() const {return 0;}; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci using InstrList = std::list<Instr *, Allocator<Instr *>>; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci const InstrList& dependend_instr() { return m_dependend_instr;} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ciprotected: 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci const InstrList& required_instr() const {return m_required_instr; } 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ciprivate: 133bf215546Sopenharmony_ci virtual void forward_set_blockid(int id, int index); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci virtual bool do_ready() const = 0; 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci virtual void do_print(std::ostream& os) const = 0; 138bf215546Sopenharmony_ci virtual bool propagate_death(); 139bf215546Sopenharmony_ci virtual void forward_set_scheduled() {} 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci InstrList m_required_instr; 142bf215546Sopenharmony_ci InstrList m_dependend_instr; 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci int m_use_count; 145bf215546Sopenharmony_ci int m_block_id; 146bf215546Sopenharmony_ci int m_index; 147bf215546Sopenharmony_ci std::bitset<nflags> m_instr_flags{0}; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci}; 150bf215546Sopenharmony_ciusing PInst = Instr::Pointer; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ciclass Block : public Instr { 153bf215546Sopenharmony_cipublic: 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci enum Type { 156bf215546Sopenharmony_ci cf, 157bf215546Sopenharmony_ci alu, 158bf215546Sopenharmony_ci tex, 159bf215546Sopenharmony_ci vtx, 160bf215546Sopenharmony_ci gds, 161bf215546Sopenharmony_ci unknown 162bf215546Sopenharmony_ci }; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci using Instructions = std::list<Instr *, Allocator<Instr *>>; 165bf215546Sopenharmony_ci using Pointer = R600_POINTER_TYPE(Block); 166bf215546Sopenharmony_ci using iterator = Instructions::iterator; 167bf215546Sopenharmony_ci using reverse_iterator = Instructions::reverse_iterator; 168bf215546Sopenharmony_ci using const_iterator = Instructions::const_iterator; 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci Block(int nesting_depth, int id); 171bf215546Sopenharmony_ci Block(const Block& orig) = delete; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci void push_back(PInst instr); 174bf215546Sopenharmony_ci iterator begin() { return m_instructions.begin(); } 175bf215546Sopenharmony_ci iterator end() { return m_instructions.end(); } 176bf215546Sopenharmony_ci reverse_iterator rbegin() { return m_instructions.rbegin(); } 177bf215546Sopenharmony_ci reverse_iterator rend() { return m_instructions.rend(); } 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci const_iterator begin() const { return m_instructions.begin();} 180bf215546Sopenharmony_ci const_iterator end() const { return m_instructions.end();} 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci bool empty() const { return m_instructions.empty();} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci void erase(iterator node); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci bool is_equal_to(const Block& lhs) const; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci void accept(ConstInstrVisitor& visitor) const override; 189bf215546Sopenharmony_ci void accept(InstrVisitor& visitor) override; 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci int nesting_depth() const { return m_nesting_depth;} 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci int id() const {return m_id;} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci auto type() const {return m_blocK_type; } 196bf215546Sopenharmony_ci void set_type(Type t); 197bf215546Sopenharmony_ci uint32_t remaining_slots() const { return m_remaining_slots;} 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci bool try_reserve_kcache(const AluGroup& instr); 200bf215546Sopenharmony_ci bool try_reserve_kcache(const AluInstr& group); 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci auto last_lds_instr() {return m_last_lds_instr;} 203bf215546Sopenharmony_ci void set_last_lds_instr(Instr *instr) {m_last_lds_instr = instr;} 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci void lds_group_start(AluInstr *alu); 206bf215546Sopenharmony_ci void lds_group_end(); 207bf215546Sopenharmony_ci bool lds_group_active() { return m_lds_group_start != nullptr;} 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci size_t size() const { return m_instructions.size();} 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci bool kcache_reservation_failed() const { return m_kcache_alloc_failed;} 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci int inc_rat_emitted() { return ++m_emitted_rat_instr;} 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci static void set_chipclass(r600_chip_class chip_class); 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ciprivate: 218bf215546Sopenharmony_ci bool try_reserve_kcache(const UniformValue& u, 219bf215546Sopenharmony_ci std::array<KCacheLine, 4>& kcache) const; 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci bool do_ready() const override {return true;}; 222bf215546Sopenharmony_ci void do_print(std::ostream& os) const override; 223bf215546Sopenharmony_ci Instructions m_instructions; 224bf215546Sopenharmony_ci int m_nesting_depth; 225bf215546Sopenharmony_ci int m_id; 226bf215546Sopenharmony_ci int m_next_index; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci Type m_blocK_type{unknown}; 229bf215546Sopenharmony_ci uint32_t m_remaining_slots{0xffff}; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci std::array<KCacheLine, 4> m_kcache; 232bf215546Sopenharmony_ci bool m_kcache_alloc_failed{false}; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci Instr *m_last_lds_instr{nullptr}; 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci int m_lds_group_requirement{0}; 237bf215546Sopenharmony_ci AluInstr *m_lds_group_start{nullptr}; 238bf215546Sopenharmony_ci static unsigned s_max_kcache_banks; 239bf215546Sopenharmony_ci int m_emitted_rat_instr{0}; 240bf215546Sopenharmony_ci}; 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ciclass InstrWithVectorResult : public Instr { 243bf215546Sopenharmony_cipublic: 244bf215546Sopenharmony_ci InstrWithVectorResult(const RegisterVec4& dest, const RegisterVec4::Swizzle& dest_swizzle); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci void set_dest_swizzle(const RegisterVec4::Swizzle& swz) {m_dest_swizzle = swz;} 247bf215546Sopenharmony_ci int dest_swizzle(int i) const { return m_dest_swizzle[i];} 248bf215546Sopenharmony_ci const RegisterVec4::Swizzle& all_dest_swizzle() const { return m_dest_swizzle;} 249bf215546Sopenharmony_ci const RegisterVec4& dst() const {return m_dest;} 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ciprotected: 252bf215546Sopenharmony_ci InstrWithVectorResult(const InstrWithVectorResult& orig); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci void print_dest(std::ostream& os) const; 255bf215546Sopenharmony_ci bool comp_dest(const RegisterVec4& dest, const RegisterVec4::Swizzle& dest_swizzle) const; 256bf215546Sopenharmony_ci 257bf215546Sopenharmony_ciprivate: 258bf215546Sopenharmony_ci RegisterVec4 m_dest; 259bf215546Sopenharmony_ci RegisterVec4::Swizzle m_dest_swizzle; 260bf215546Sopenharmony_ci}; 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ciinline bool operator == (const Instr& lhs, const Instr& rhs) { 263bf215546Sopenharmony_ci return lhs.equal_to(rhs); 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ciinline bool operator != (const Instr& lhs, const Instr& rhs) { 267bf215546Sopenharmony_ci return !(lhs == rhs); 268bf215546Sopenharmony_ci} 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ciinline std::ostream& operator << (std::ostream& os, const Instr& instr) 271bf215546Sopenharmony_ci{ 272bf215546Sopenharmony_ci instr.print(os); 273bf215546Sopenharmony_ci return os; 274bf215546Sopenharmony_ci} 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_citemplate <typename T, typename = std::enable_if_t<std::is_base_of_v<Instr, T>>> 277bf215546Sopenharmony_cistd::ostream& operator<<(std::ostream& os, const T& instr) { 278bf215546Sopenharmony_ci instr.print(os); 279bf215546Sopenharmony_ci return os; 280bf215546Sopenharmony_ci} 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ciclass ConstInstrVisitor { 283bf215546Sopenharmony_cipublic: 284bf215546Sopenharmony_ci virtual void visit(const AluInstr& instr) = 0; 285bf215546Sopenharmony_ci virtual void visit(const AluGroup& instr) = 0; 286bf215546Sopenharmony_ci virtual void visit(const TexInstr& instr) = 0; 287bf215546Sopenharmony_ci virtual void visit(const ExportInstr& instr) = 0; 288bf215546Sopenharmony_ci virtual void visit(const FetchInstr& instr) = 0; 289bf215546Sopenharmony_ci virtual void visit(const Block& instr) = 0; 290bf215546Sopenharmony_ci virtual void visit(const ControlFlowInstr& instr) = 0; 291bf215546Sopenharmony_ci virtual void visit(const IfInstr& instr) = 0; 292bf215546Sopenharmony_ci virtual void visit(const ScratchIOInstr& instr) = 0; 293bf215546Sopenharmony_ci virtual void visit(const StreamOutInstr& instr) = 0; 294bf215546Sopenharmony_ci virtual void visit(const MemRingOutInstr& instr) = 0; 295bf215546Sopenharmony_ci virtual void visit(const EmitVertexInstr& instr) = 0; 296bf215546Sopenharmony_ci virtual void visit(const GDSInstr& instr) = 0; 297bf215546Sopenharmony_ci virtual void visit(const WriteTFInstr& instr) = 0; 298bf215546Sopenharmony_ci virtual void visit(const LDSAtomicInstr& instr) = 0; 299bf215546Sopenharmony_ci virtual void visit(const LDSReadInstr& instr) = 0; 300bf215546Sopenharmony_ci virtual void visit(const RatInstr& instr) = 0; 301bf215546Sopenharmony_ci}; 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ciclass InstrVisitor { 304bf215546Sopenharmony_cipublic: 305bf215546Sopenharmony_ci virtual void visit(AluInstr *instr) = 0; 306bf215546Sopenharmony_ci virtual void visit(AluGroup *instr) = 0; 307bf215546Sopenharmony_ci virtual void visit(TexInstr *instr) = 0; 308bf215546Sopenharmony_ci virtual void visit(ExportInstr *instr) = 0; 309bf215546Sopenharmony_ci virtual void visit(FetchInstr *instr) = 0; 310bf215546Sopenharmony_ci virtual void visit(Block *instr) = 0; 311bf215546Sopenharmony_ci virtual void visit(ControlFlowInstr *instr) = 0; 312bf215546Sopenharmony_ci virtual void visit(IfInstr *instr) = 0; 313bf215546Sopenharmony_ci virtual void visit(ScratchIOInstr *instr) = 0; 314bf215546Sopenharmony_ci virtual void visit(StreamOutInstr *instr) = 0; 315bf215546Sopenharmony_ci virtual void visit(MemRingOutInstr *instr) = 0; 316bf215546Sopenharmony_ci virtual void visit(EmitVertexInstr *instr) = 0; 317bf215546Sopenharmony_ci virtual void visit(GDSInstr *instr) = 0; 318bf215546Sopenharmony_ci virtual void visit(WriteTFInstr *instr) = 0; 319bf215546Sopenharmony_ci virtual void visit(LDSAtomicInstr *instr) = 0; 320bf215546Sopenharmony_ci virtual void visit(LDSReadInstr *instr) = 0; 321bf215546Sopenharmony_ci virtual void visit(RatInstr *instr) = 0; 322bf215546Sopenharmony_ci}; 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci} // ns r600 326