aco: Add ABI and Pseudo CALL format
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34531>
This commit is contained in:
@@ -578,6 +578,7 @@ formats = [("pseudo", [Format.PSEUDO], list(itertools.product(range(5), range(7)
|
||||
("branch", [Format.PSEUDO_BRANCH], [(0, 0), (0, 1)]),
|
||||
("barrier", [Format.PSEUDO_BARRIER], [(0, 0)]),
|
||||
("reduction", [Format.PSEUDO_REDUCTION], [(3, 3)]),
|
||||
("call", [Format.PSEUDO_CALL], [(0, 0)]),
|
||||
("vop1", [Format.VOP1], [(0, 0), (1, 1), (1, 2), (2, 2)]),
|
||||
("vop1_sdwa", [Format.VOP1, Format.SDWA], [(1, 1)]),
|
||||
("vop2", [Format.VOP2], itertools.product([1, 2], [2, 3])),
|
||||
|
||||
@@ -1704,6 +1704,7 @@ get_instr_data_size(Format format)
|
||||
case Format::PSEUDO_BARRIER: return sizeof(Pseudo_barrier_instruction);
|
||||
case Format::PSEUDO_REDUCTION: return sizeof(Pseudo_reduction_instruction);
|
||||
case Format::PSEUDO_BRANCH: return sizeof(Pseudo_branch_instruction);
|
||||
case Format::PSEUDO_CALL: return sizeof(Pseudo_call_instruction);
|
||||
case Format::DS: return sizeof(DS_instruction);
|
||||
case Format::FLAT:
|
||||
case Format::GLOBAL:
|
||||
|
||||
+104
-2
@@ -11,6 +11,7 @@
|
||||
#include "aco_shader_info.h"
|
||||
#include "aco_util.h"
|
||||
|
||||
#include "util/bitset.h"
|
||||
#include "util/compiler.h"
|
||||
#include "util/shader_stats.h"
|
||||
|
||||
@@ -1114,6 +1115,74 @@ struct RegisterDemand {
|
||||
}
|
||||
};
|
||||
|
||||
struct ABI {
|
||||
struct GPRRange {
|
||||
uint16_t sgpr;
|
||||
uint16_t vgpr;
|
||||
};
|
||||
|
||||
struct RegisterBlock {
|
||||
GPRRange clobbered_size;
|
||||
GPRRange preserved_size;
|
||||
bool clobbered_first;
|
||||
};
|
||||
|
||||
RegisterBlock block_size;
|
||||
/* Maximum number of registers allowed to be used by parameters */
|
||||
RegisterDemand max_param_demand;
|
||||
|
||||
void preservedRegisters(BITSET_DECLARE(regs, 512),
|
||||
RegisterDemand reg_limit = RegisterDemand(256, 256)) const
|
||||
{
|
||||
unsigned size = DIV_ROUND_UP(512, BITSET_WORDBITS) * sizeof(BITSET_WORD);
|
||||
memset(regs, 0, size);
|
||||
|
||||
/* Fill out preserved ranges by repeating the register block across the register file */
|
||||
|
||||
/* SGPR ranges */
|
||||
unsigned gpr_offset = block_size.clobbered_first ? block_size.clobbered_size.sgpr : 0;
|
||||
while (gpr_offset < (unsigned)reg_limit.sgpr) {
|
||||
unsigned end = MIN2((unsigned)reg_limit.sgpr, gpr_offset + block_size.preserved_size.sgpr);
|
||||
BITSET_SET_RANGE(regs, gpr_offset, end - 1);
|
||||
gpr_offset = end + block_size.clobbered_size.sgpr;
|
||||
}
|
||||
/* VGPR ranges */
|
||||
gpr_offset = block_size.clobbered_first ? block_size.clobbered_size.vgpr : 0;
|
||||
while (gpr_offset < (unsigned)reg_limit.vgpr) {
|
||||
unsigned end = MIN2((unsigned)reg_limit.vgpr, gpr_offset + block_size.preserved_size.vgpr);
|
||||
BITSET_SET_RANGE(regs, 256 + gpr_offset, 256 + end - 1);
|
||||
gpr_offset = end + block_size.clobbered_size.vgpr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr ABI rtRaygenABI = {
|
||||
ABI::RegisterBlock{
|
||||
ABI::GPRRange{128u, 256u}, /* clobbered_size */
|
||||
ABI::GPRRange{0u, 0u}, /* preserved_size */
|
||||
true, /* preserved_first */
|
||||
},
|
||||
RegisterDemand(32, 32), /* max_param_demand */
|
||||
};
|
||||
|
||||
static constexpr ABI rtTraversalABI = {
|
||||
ABI::RegisterBlock{
|
||||
ABI::GPRRange{128u, 256u}, /* clobbered_size */
|
||||
ABI::GPRRange{0u, 0u}, /* preserved_size */
|
||||
true, /* preserved_first */
|
||||
},
|
||||
RegisterDemand(32, 32), /* max_param_demand */
|
||||
};
|
||||
|
||||
static constexpr ABI rtAnyHitABI = {
|
||||
ABI::RegisterBlock{
|
||||
ABI::GPRRange{128u, 256u}, /* clobbered_size */
|
||||
ABI::GPRRange{80u, 80u}, /* preserved_size */
|
||||
false, /* preserved_first */
|
||||
},
|
||||
RegisterDemand(32, 32), /* max_param_demand */
|
||||
};
|
||||
|
||||
struct Block;
|
||||
struct Instruction;
|
||||
struct Pseudo_instruction;
|
||||
@@ -1129,6 +1198,7 @@ struct FLAT_instruction;
|
||||
struct Pseudo_branch_instruction;
|
||||
struct Pseudo_barrier_instruction;
|
||||
struct Pseudo_reduction_instruction;
|
||||
struct Pseudo_call_instruction;
|
||||
struct VALU_instruction;
|
||||
struct VINTERP_inreg_instruction;
|
||||
struct VINTRP_instruction;
|
||||
@@ -1329,6 +1399,17 @@ struct Instruction {
|
||||
return *(Pseudo_reduction_instruction*)this;
|
||||
}
|
||||
constexpr bool isReduction() const noexcept { return format == Format::PSEUDO_REDUCTION; }
|
||||
Pseudo_call_instruction& call() noexcept
|
||||
{
|
||||
assert(isCall());
|
||||
return *(Pseudo_call_instruction*)this;
|
||||
}
|
||||
const Pseudo_call_instruction& call() const noexcept
|
||||
{
|
||||
assert(isCall());
|
||||
return *(Pseudo_call_instruction*)this;
|
||||
}
|
||||
constexpr bool isCall() const noexcept { return format == Format::PSEUDO_CALL; }
|
||||
constexpr bool isVOP3P() const noexcept { return (uint16_t)format & (uint16_t)Format::VOP3P; }
|
||||
VINTERP_inreg_instruction& vinterp_inreg() noexcept
|
||||
{
|
||||
@@ -1816,6 +1897,27 @@ struct Pseudo_reduction_instruction : public Instruction {
|
||||
static_assert(sizeof(Pseudo_reduction_instruction) == sizeof(Instruction) + 4,
|
||||
"Unexpected padding");
|
||||
|
||||
struct Pseudo_call_instruction : public Instruction {
|
||||
/* The amount of "free" preserved registers we can use to stash caller-owned temporaries instead
|
||||
* of needing to spill them. This is equal to the amount of preserved registers given by the ABI,
|
||||
* minus the amount of preserved registers already occupied by call parameters.
|
||||
*/
|
||||
RegisterDemand callee_preserved_limit;
|
||||
/* Register demand of caller-owned temporaries we need to preserve a copy of throughout the
|
||||
* callee. This includes all live variables not used by the call instruction as well as clobbered
|
||||
* Operand temporaries (unless the call kills the operand - we don't need to preserve a copy in
|
||||
* that case). Non-clobbered Operand temporaries are not included in this demand - they occupy a
|
||||
* preserved register, which is accounted for in the calculation of callee_preserved_limit
|
||||
* already.
|
||||
*
|
||||
* Iff this demand is higher than callee_preserved_limit, some of the temporaries need to be
|
||||
* spilled to scratch.
|
||||
*/
|
||||
RegisterDemand caller_preserved_demand;
|
||||
|
||||
ABI abi;
|
||||
};
|
||||
|
||||
inline bool
|
||||
Instruction::accessesLDS() const noexcept
|
||||
{
|
||||
@@ -1894,8 +1996,8 @@ memory_sync_info get_sync_info(const Instruction* instr);
|
||||
inline bool
|
||||
is_dead(const std::vector<uint16_t>& uses, const Instruction* instr)
|
||||
{
|
||||
if (instr->definitions.empty() || instr->isBranch() || instr->opcode == aco_opcode::p_startpgm ||
|
||||
instr->opcode == aco_opcode::p_init_scratch ||
|
||||
if (instr->definitions.empty() || instr->isBranch() || instr->isCall() ||
|
||||
instr->opcode == aco_opcode::p_startpgm || instr->opcode == aco_opcode::p_init_scratch ||
|
||||
instr->opcode == aco_opcode::p_dual_src_export_gfx11)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ class Format(IntEnum):
|
||||
PSEUDO_BRANCH = auto()
|
||||
PSEUDO_BARRIER = auto()
|
||||
PSEUDO_REDUCTION = auto()
|
||||
PSEUDO_CALL = auto()
|
||||
# Scalar ALU & Control Formats
|
||||
SOP1 = auto()
|
||||
SOP2 = auto()
|
||||
@@ -93,7 +94,7 @@ class Format(IntEnum):
|
||||
return "salu"
|
||||
elif self in [Format.FLAT, Format.GLOBAL, Format.SCRATCH]:
|
||||
return "flatlike"
|
||||
elif self in [Format.PSEUDO_BRANCH, Format.PSEUDO_REDUCTION, Format.PSEUDO_BARRIER]:
|
||||
elif self in [Format.PSEUDO_BRANCH, Format.PSEUDO_REDUCTION, Format.PSEUDO_BARRIER, Format.PSEUDO_CALL]:
|
||||
return self.name.split("_")[-1].lower()
|
||||
else:
|
||||
return self.name.lower()
|
||||
@@ -163,6 +164,8 @@ class Format(IntEnum):
|
||||
elif self == Format.PSEUDO_BARRIER:
|
||||
return [('memory_sync_info', 'sync', None),
|
||||
('sync_scope', 'exec_scope', 'scope_invocation')]
|
||||
elif self == Format.PSEUDO_CALL:
|
||||
return [('ABI', 'abi', None)]
|
||||
elif self == Format.VINTRP:
|
||||
return [('unsigned', 'attribute', None),
|
||||
('unsigned', 'component', None),
|
||||
@@ -376,6 +379,8 @@ insn("p_cbranch_nz", format=Format.PSEUDO_BRANCH)
|
||||
|
||||
insn("p_barrier", format=Format.PSEUDO_BARRIER)
|
||||
|
||||
insn("p_call", format=Format.PSEUDO_CALL)
|
||||
|
||||
# Primitive Ordered Pixel Shading pseudo-instructions.
|
||||
|
||||
# For querying whether the current wave can enter the ordered section on GFX9-10.3, doing
|
||||
|
||||
Reference in New Issue
Block a user