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_wait_states(program.get());
|
||||||
aco::insert_NOPs(program.get());
|
aco::insert_NOPs(program.get());
|
||||||
|
|
||||||
|
if (program->chip_class >= GFX10)
|
||||||
|
aco::form_hard_clauses(program.get());
|
||||||
|
|
||||||
if (program->collect_statistics)
|
if (program->collect_statistics)
|
||||||
aco::collect_preasm_stats(program.get());
|
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 spill(Program* program, live& live_vars);
|
||||||
void insert_wait_states(Program* program);
|
void insert_wait_states(Program* program);
|
||||||
void insert_NOPs(Program* program);
|
void insert_NOPs(Program* program);
|
||||||
|
void form_hard_clauses(Program *program);
|
||||||
unsigned emit_program(Program* program, std::vector<uint32_t>& code);
|
unsigned emit_program(Program* program, std::vector<uint32_t>& code);
|
||||||
bool print_asm(Program *program, std::vector<uint32_t>& binary,
|
bool print_asm(Program *program, std::vector<uint32_t>& binary,
|
||||||
unsigned exec_size, FILE *output);
|
unsigned exec_size, FILE *output);
|
||||||
|
|
|
@ -64,6 +64,7 @@ libaco_files = files(
|
||||||
'aco_ir.cpp',
|
'aco_ir.cpp',
|
||||||
'aco_ir.h',
|
'aco_ir.h',
|
||||||
'aco_assembler.cpp',
|
'aco_assembler.cpp',
|
||||||
|
'aco_form_hard_clauses.cpp',
|
||||||
'aco_insert_exec_mask.cpp',
|
'aco_insert_exec_mask.cpp',
|
||||||
'aco_insert_NOPs.cpp',
|
'aco_insert_NOPs.cpp',
|
||||||
'aco_insert_waitcnt.cpp',
|
'aco_insert_waitcnt.cpp',
|
||||||
|
|
Loading…
Reference in New Issue