Path: blob/21.2-virgl/src/amd/compiler/aco_form_hard_clauses.cpp
4550 views
/*1* Copyright © 2020 Valve Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*22*/2324#include "aco_builder.h"25#include "aco_ir.h"2627#include <vector>2829namespace aco {30namespace {3132/* there can also be LDS and VALU clauses, but I don't see how those are interesting */33enum clause_type {34clause_vmem,35clause_flat,36clause_smem,37clause_other,38};3940void41emit_clause(Builder& bld, unsigned num_instrs, aco_ptr<Instruction>* instrs)42{43unsigned start = 0;4445/* skip any stores at the start */46for (; (start < num_instrs) && instrs[start]->definitions.empty(); start++)47bld.insert(std::move(instrs[start]));4849unsigned end = start;50for (; (end < num_instrs) && !instrs[end]->definitions.empty(); end++)51;52unsigned clause_size = end - start;5354if (clause_size > 1)55bld.sopp(aco_opcode::s_clause, -1, clause_size - 1);5657for (unsigned i = start; i < num_instrs; i++)58bld.insert(std::move(instrs[i]));59}6061} /* end namespace */6263void64form_hard_clauses(Program* program)65{66for (Block& block : program->blocks) {67unsigned num_instrs = 0;68aco_ptr<Instruction> current_instrs[64];69clause_type current_type = clause_other;7071std::vector<aco_ptr<Instruction>> new_instructions;72new_instructions.reserve(block.instructions.size());73Builder bld(program, &new_instructions);7475for (unsigned i = 0; i < block.instructions.size(); i++) {76aco_ptr<Instruction>& instr = block.instructions[i];7778clause_type type = clause_other;79if (instr->isVMEM() && !instr->operands.empty()) {80if (program->chip_class == GFX10 && instr->isMIMG() &&81get_mimg_nsa_dwords(instr.get()) > 0)82type = clause_other;83else84type = clause_vmem;85} else if (instr->isScratch() || instr->isGlobal()) {86type = clause_vmem;87} else if (instr->isFlat()) {88type = clause_flat;89} else if (instr->isSMEM() && !instr->operands.empty()) {90type = clause_smem;91}9293if (type != current_type || num_instrs == 64 ||94(num_instrs && !should_form_clause(current_instrs[0].get(), instr.get()))) {95emit_clause(bld, num_instrs, current_instrs);96num_instrs = 0;97current_type = type;98}99100if (type == clause_other) {101bld.insert(std::move(instr));102continue;103}104105current_instrs[num_instrs++] = std::move(instr);106}107108emit_clause(bld, num_instrs, current_instrs);109110block.instructions = std::move(new_instructions);111}112}113} // namespace aco114115116