aco: create s_clause on GFX10+
This seems to give no measurable benefit to Strange Brigade or Shadow of Mordor, but it's simple to do, helps in theory and all other compilers do it. Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5919>
This commit is contained in:
parent
f4c090a3b3
commit
3dfbed2a87
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright © 2020 Valve Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "aco_ir.h"
|
||||
#include "aco_builder.h"
|
||||
|
||||
namespace aco {
|
||||
namespace {
|
||||
|
||||
/* there can also be LDS and VALU clauses, but I don't see how those are interesting */
|
||||
enum clause_type
|
||||
{
|
||||
clause_vmem,
|
||||
clause_flat,
|
||||
clause_smem,
|
||||
clause_other,
|
||||
};
|
||||
|
||||
void emit_clause(Builder& bld, unsigned num_instrs, aco_ptr<Instruction> *instrs)
|
||||
{
|
||||
unsigned start = 0;
|
||||
|
||||
/* skip any stores at the start */
|
||||
for (; (start < num_instrs) && instrs[start]->definitions.empty(); start++)
|
||||
bld.insert(std::move(instrs[start]));
|
||||
|
||||
unsigned end = start;
|
||||
for (; (end < num_instrs) && !instrs[end]->definitions.empty(); end++)
|
||||
;
|
||||
unsigned clause_size = end - start;
|
||||
|
||||
if (clause_size > 1)
|
||||
bld.sopp(aco_opcode::s_clause, -1, clause_size - 1);
|
||||
|
||||
for (unsigned i = start; i < num_instrs; i++)
|
||||
bld.insert(std::move(instrs[i]));
|
||||
}
|
||||
|
||||
} /* end namespace */
|
||||
|
||||
void form_hard_clauses(Program *program)
|
||||
{
|
||||
for (Block& block : program->blocks) {
|
||||
unsigned num_instrs = 0;
|
||||
aco_ptr<Instruction> current_instrs[64];
|
||||
clause_type current_type = clause_other;
|
||||
unsigned current_resource = 0;
|
||||
|
||||
std::vector<aco_ptr<Instruction>> new_instructions;
|
||||
new_instructions.reserve(block.instructions.size());
|
||||
Builder bld(program, &new_instructions);
|
||||
|
||||
for (unsigned i = 0; i < block.instructions.size(); i++) {
|
||||
aco_ptr<Instruction>& instr = block.instructions[i];
|
||||
|
||||
unsigned resource = 0;
|
||||
clause_type type = clause_other;
|
||||
if (instr->isVMEM() && !instr->operands.empty()) {
|
||||
resource = instr->operands[0].tempId();
|
||||
type = clause_vmem;
|
||||
} else if (instr->format == Format::SCRATCH || instr->format == Format::GLOBAL) {
|
||||
type = clause_vmem;
|
||||
} else if (instr->format == Format::FLAT) {
|
||||
type = clause_flat;
|
||||
} else if (instr->format == Format::SMEM && !instr->operands.empty()) {
|
||||
type = clause_smem;
|
||||
if (instr->operands[0].bytes() == 16)
|
||||
resource = instr->operands[0].tempId();
|
||||
}
|
||||
|
||||
if (type != current_type || resource != current_resource || num_instrs == 64) {
|
||||
emit_clause(bld, num_instrs, current_instrs);
|
||||
num_instrs = 0;
|
||||
current_type = type;
|
||||
current_resource = resource;
|
||||
}
|
||||
|
||||
if (type == clause_other) {
|
||||
bld.insert(std::move(instr));
|
||||
continue;
|
||||
}
|
||||
|
||||
current_instrs[num_instrs++] = std::move(instr);
|
||||
}
|
||||
|
||||
emit_clause(bld, num_instrs, current_instrs);
|
||||
|
||||
block.instructions = std::move(new_instructions);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -156,6 +156,9 @@ void aco_compile_shader(unsigned shader_count,
|
|||
aco::insert_wait_states(program.get());
|
||||
aco::insert_NOPs(program.get());
|
||||
|
||||
if (program->chip_class >= GFX10)
|
||||
aco::form_hard_clauses(program.get());
|
||||
|
||||
if (program->collect_statistics)
|
||||
aco::collect_preasm_stats(program.get());
|
||||
|
||||
|
|
|
@ -1746,6 +1746,7 @@ void schedule_program(Program* program, live& live_vars);
|
|||
void spill(Program* program, live& live_vars);
|
||||
void insert_wait_states(Program* program);
|
||||
void insert_NOPs(Program* program);
|
||||
void form_hard_clauses(Program *program);
|
||||
unsigned emit_program(Program* program, std::vector<uint32_t>& code);
|
||||
bool print_asm(Program *program, std::vector<uint32_t>& binary,
|
||||
unsigned exec_size, FILE *output);
|
||||
|
|
|
@ -64,6 +64,7 @@ libaco_files = files(
|
|||
'aco_ir.cpp',
|
||||
'aco_ir.h',
|
||||
'aco_assembler.cpp',
|
||||
'aco_form_hard_clauses.cpp',
|
||||
'aco_insert_exec_mask.cpp',
|
||||
'aco_insert_NOPs.cpp',
|
||||
'aco_insert_waitcnt.cpp',
|
||||
|
|
Loading…
Reference in New Issue