pco, pygen: validate phases and io allocations for ops
Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33998>
This commit is contained in:
committed by
Marge Bot
parent
c201332fff
commit
765e9d837d
@@ -58,6 +58,28 @@ const struct pco_op_info pco_op_info[_PCO_OP_COUNT] = {
|
||||
% endfor
|
||||
},
|
||||
% endif
|
||||
#ifndef NDEBUG
|
||||
% if op.bname in encode_maps:
|
||||
.grp_dest_maps = {
|
||||
% for phase, dests, _ in encode_maps[op.bname].op_ref_maps:
|
||||
[${phase}] = {
|
||||
% for dest in dests:
|
||||
[${loop.index}] = ${dest},
|
||||
% endfor
|
||||
},
|
||||
% endfor
|
||||
},
|
||||
.grp_src_maps = {
|
||||
% for phase, _, srcs in encode_maps[op.bname].op_ref_maps:
|
||||
[${phase}] = {
|
||||
% for src in srcs:
|
||||
[${loop.index}] = ${src},
|
||||
% endfor
|
||||
},
|
||||
% endfor
|
||||
},
|
||||
% endif
|
||||
#endif /* NDEBUG */
|
||||
},
|
||||
% endfor
|
||||
};
|
||||
@@ -104,7 +126,7 @@ const struct pco_ref_mod_info pco_ref_mod_info[_PCO_REF_MOD_COUNT] = {
|
||||
|
||||
def main():
|
||||
try:
|
||||
print(Template(template).render(BaseType=BaseType, ops=ops, op_mods=op_mods, ref_mods=ref_mods, group_maps=group_maps))
|
||||
print(Template(template).render(BaseType=BaseType, ops=ops, op_mods=op_mods, ref_mods=ref_mods, group_maps=group_maps, encode_maps=encode_maps))
|
||||
except:
|
||||
raise Exception(exceptions.text_error_template().render())
|
||||
|
||||
|
||||
@@ -362,8 +362,14 @@ struct pco_op_info {
|
||||
bool has_target_cf_node; /** Set if op has a cf-node as a target. */
|
||||
uint8_t dest_intrn_map[_PCO_OP_MAX_DESTS];
|
||||
uint8_t src_intrn_map[_PCO_OP_MAX_SRCS];
|
||||
#ifndef NDEBUG
|
||||
uint32_t grp_dest_maps[_PCO_OP_PHASE_COUNT][_PCO_OP_MAX_DESTS];
|
||||
uint32_t grp_src_maps[_PCO_OP_PHASE_COUNT][_PCO_OP_MAX_SRCS];
|
||||
#endif /* NDEBUG */
|
||||
};
|
||||
extern const struct pco_op_info pco_op_info[_PCO_OP_COUNT];
|
||||
static_assert(_PCO_REF_MAP_COUNT <= 32,
|
||||
"enum pco_ref_map must fit into an uint32_t");
|
||||
|
||||
/** Op mod info. */
|
||||
struct pco_op_mod_info {
|
||||
@@ -2164,5 +2170,8 @@ void pco_print_instr(pco_shader *shader, pco_instr *instr);
|
||||
void pco_print_igrp(pco_shader *shader, pco_igrp *igrp);
|
||||
void pco_print_cf_node_name(pco_shader *shader, pco_cf_node *cf_node);
|
||||
void pco_print_shader_info(pco_shader *shader);
|
||||
void pco_print_phase(pco_shader *shader,
|
||||
enum pco_alutype alutype,
|
||||
enum pco_op_phase phase);
|
||||
|
||||
#endif /* PCO_INTERNAL_H */
|
||||
|
||||
@@ -37,6 +37,7 @@ REF_MAP = enum_type('ref_map', [
|
||||
('ftt', 'ftt'),
|
||||
|
||||
('p0', 'p0'),
|
||||
('pe', 'pe'),
|
||||
|
||||
('imm', 'imm'),
|
||||
('drc', 'drc'),
|
||||
|
||||
@@ -95,8 +95,6 @@ IO = enum_type('io', [
|
||||
('ftt', 'ftt'),
|
||||
|
||||
('cout', 'cout'),
|
||||
|
||||
('p0', 'p0'),
|
||||
])
|
||||
|
||||
PRED = enum_type('pred', [
|
||||
|
||||
@@ -528,9 +528,9 @@ static void _pco_print_instr(pco_print_state *state, pco_instr *instr)
|
||||
* \param[in] alutype ALU type.
|
||||
* \param[in] phase Phase.
|
||||
*/
|
||||
static void pco_print_phase(pco_print_state *state,
|
||||
enum pco_alutype alutype,
|
||||
enum pco_op_phase phase)
|
||||
static void _pco_print_phase(pco_print_state *state,
|
||||
enum pco_alutype alutype,
|
||||
enum pco_op_phase phase)
|
||||
{
|
||||
switch (alutype) {
|
||||
case PCO_ALUTYPE_MAIN:
|
||||
@@ -567,7 +567,7 @@ static void pco_print_igrp_phases(pco_print_state *state, pco_igrp *igrp)
|
||||
if (printed)
|
||||
pco_printf(state, ",");
|
||||
|
||||
pco_print_phase(state, igrp->hdr.alutype, phase);
|
||||
_pco_print_phase(state, igrp->hdr.alutype, phase);
|
||||
|
||||
printed = true;
|
||||
}
|
||||
@@ -772,13 +772,13 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp)
|
||||
else if (printed)
|
||||
pco_printf(state, " ");
|
||||
|
||||
pco_print_phase(state, igrp->hdr.alutype, phase);
|
||||
_pco_print_phase(state, igrp->hdr.alutype, phase);
|
||||
pco_printf(state, ": ");
|
||||
_pco_print_instr(state, igrp->instrs[phase]);
|
||||
|
||||
if (state->verbose) {
|
||||
pco_printf(state, " /* ");
|
||||
pco_print_phase(state, igrp->hdr.alutype, phase);
|
||||
_pco_print_phase(state, igrp->hdr.alutype, phase);
|
||||
pco_printf(state, " bytes: %u */\n", igrp->enc.len.instrs[phase]);
|
||||
}
|
||||
|
||||
@@ -1233,3 +1233,25 @@ void pco_print_shader_info(pco_shader *shader)
|
||||
};
|
||||
return _pco_print_shader_info(&state, shader);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Print the name of a phase(wrapper).
|
||||
*
|
||||
* \param[in] shader PCO shader.
|
||||
* \param[in] alutype ALU type.
|
||||
* \param[in] phase Phase.
|
||||
*/
|
||||
void pco_print_phase(pco_shader *shader,
|
||||
enum pco_alutype alutype,
|
||||
enum pco_op_phase phase)
|
||||
{
|
||||
pco_print_state state = {
|
||||
.fp = stdout,
|
||||
.shader = shader,
|
||||
.indent = 0,
|
||||
.is_grouped = shader->is_grouped,
|
||||
.verbose = false,
|
||||
};
|
||||
|
||||
return _pco_print_phase(&state, alutype, phase);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
enum ref_cursor {
|
||||
REF_CURSOR_NONE,
|
||||
REF_CURSOR_INSTR_DEST,
|
||||
@@ -58,7 +60,12 @@ static void pco_assert(struct val_state *state,
|
||||
if (cond)
|
||||
return;
|
||||
|
||||
printf("PCO validation failed with assertion \"%s\" - ", cond_str);
|
||||
printf("PCO validation failed ");
|
||||
|
||||
if (state->when)
|
||||
printf("%s ", state->when);
|
||||
|
||||
printf("with assertion \"%s\" - ", cond_str);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
@@ -77,6 +84,18 @@ static void pco_assert(struct val_state *state,
|
||||
printf(" instr src #%" PRIuPTR, state->ref - state->instr->src);
|
||||
break;
|
||||
|
||||
case REF_CURSOR_IGRP_DEST:
|
||||
printf(" igrp dest #%" PRIuPTR, state->ref - state->igrp->srcs.s);
|
||||
break;
|
||||
|
||||
case REF_CURSOR_IGRP_ISS:
|
||||
printf(" igrp iss #%" PRIuPTR, state->ref - state->igrp->iss.is);
|
||||
break;
|
||||
|
||||
case REF_CURSOR_IGRP_SRC:
|
||||
printf(" igrp src #%" PRIuPTR, state->ref - state->igrp->srcs.s);
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable();
|
||||
}
|
||||
@@ -98,6 +117,14 @@ static void pco_assert(struct val_state *state,
|
||||
|
||||
if (state->instr) {
|
||||
printf(" instr ");
|
||||
if (state->shader->is_grouped) {
|
||||
printf("(phase ");
|
||||
pco_print_phase(state->shader,
|
||||
state->instr->parent_igrp->hdr.alutype,
|
||||
state->instr->phase);
|
||||
printf(") ");
|
||||
}
|
||||
|
||||
pco_print_instr(state->shader, state->instr);
|
||||
}
|
||||
|
||||
@@ -108,13 +135,13 @@ static void pco_assert(struct val_state *state,
|
||||
|
||||
printf(".\n");
|
||||
|
||||
pco_print_shader_info(state->shader);
|
||||
pco_print_shader(state->shader, stdout, state->when);
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
#define PCO_ASSERT(state, cond, fmt, ...) \
|
||||
pco_assert(state, cond, #cond, fmt, ##__VA_ARGS__)
|
||||
# define PCO_ASSERT(state, cond, fmt, ...) \
|
||||
pco_assert(state, cond, #cond, fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* \brief Validates SSA assignments and uses.
|
||||
@@ -234,15 +261,175 @@ static void pco_validate_src_maps(struct val_state *state)
|
||||
}
|
||||
}
|
||||
|
||||
# define CHECK_IO(io, ref) \
|
||||
case PCO_REF_MAP_##io: \
|
||||
if (pco_ref_is_io(ref) && pco_ref_get_io(ref) == PCO_IO_##io) \
|
||||
return true; \
|
||||
break;
|
||||
|
||||
/**
|
||||
* \brief Checks whether a ref type corresponds to a supported mapping.
|
||||
*
|
||||
* \param[in] ref Src/dest reference.
|
||||
* \param[in] ref_maps Supported mappings.
|
||||
* \return True if the ref type corresponds to a supported mapping.
|
||||
*/
|
||||
static inline bool ref_is_in_map(pco_ref ref, enum pco_ref_map ref_maps)
|
||||
{
|
||||
u_foreach_bit (_ref_map, ref_maps) {
|
||||
enum pco_ref_map ref_map = _ref_map;
|
||||
switch (ref_map) {
|
||||
case PCO_REF_MAP__:
|
||||
if (pco_ref_is_null(ref))
|
||||
return true;
|
||||
break;
|
||||
|
||||
CHECK_IO(S0, ref)
|
||||
CHECK_IO(S1, ref)
|
||||
CHECK_IO(S2, ref)
|
||||
CHECK_IO(S3, ref)
|
||||
CHECK_IO(S4, ref)
|
||||
CHECK_IO(S5, ref)
|
||||
|
||||
CHECK_IO(W0, ref)
|
||||
CHECK_IO(W1, ref)
|
||||
|
||||
CHECK_IO(IS0, ref)
|
||||
CHECK_IO(IS1, ref)
|
||||
CHECK_IO(IS2, ref)
|
||||
CHECK_IO(IS3, ref)
|
||||
CHECK_IO(IS4, ref)
|
||||
CHECK_IO(IS5, ref)
|
||||
|
||||
CHECK_IO(FT0, ref)
|
||||
CHECK_IO(FT1, ref)
|
||||
CHECK_IO(FT2, ref)
|
||||
CHECK_IO(FTE, ref)
|
||||
CHECK_IO(FT3, ref)
|
||||
CHECK_IO(FT4, ref)
|
||||
CHECK_IO(FT5, ref)
|
||||
|
||||
CHECK_IO(FTT, ref)
|
||||
|
||||
case PCO_REF_MAP_P0:
|
||||
if (pco_ref_is_pred(ref) && ref.val == PCO_PRED_P0)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case PCO_REF_MAP_PE:
|
||||
if (pco_ref_is_pred(ref) && ref.val == PCO_PRED_PE)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case PCO_REF_MAP_IMM:
|
||||
if (pco_ref_is_imm(ref))
|
||||
return true;
|
||||
break;
|
||||
|
||||
case PCO_REF_MAP_DRC:
|
||||
if (pco_ref_is_drc(ref))
|
||||
return true;
|
||||
break;
|
||||
|
||||
case PCO_REF_MAP_TEMP:
|
||||
if ((pco_ref_is_reg(ref) || pco_ref_is_idx_reg(ref)) &&
|
||||
pco_ref_get_reg_class(ref) == PCO_REG_CLASS_TEMP)
|
||||
return true;
|
||||
break;
|
||||
|
||||
case PCO_REF_MAP_COEFF:
|
||||
if ((pco_ref_is_reg(ref) || pco_ref_is_idx_reg(ref)) &&
|
||||
pco_ref_get_reg_class(ref) == PCO_REG_CLASS_COEFF)
|
||||
return true;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# undef CHECK_IO
|
||||
|
||||
/**
|
||||
* \brief Validates I/O references for igrps.
|
||||
*
|
||||
* \param[in,out] state Validation state.
|
||||
*/
|
||||
static void pco_validate_ref_maps(struct val_state *state)
|
||||
{
|
||||
bool needs_s124;
|
||||
pco_foreach_func_in_shader (func, state->shader) {
|
||||
state->func = func;
|
||||
|
||||
pco_foreach_igrp_in_func (igrp, func) {
|
||||
state->cf_node = &igrp->parent_block->cf_node;
|
||||
state->igrp = igrp;
|
||||
|
||||
/* Igrp source mappings. */
|
||||
state->ref_cursor = REF_CURSOR_IGRP_SRC;
|
||||
for (unsigned s = 0; s < ARRAY_SIZE(igrp->srcs.s); ++s) {
|
||||
state->ref = &igrp->srcs.s[s];
|
||||
pco_ref src = igrp->srcs.s[s];
|
||||
|
||||
if (pco_ref_is_null(src))
|
||||
continue;
|
||||
|
||||
bool valid = ref_src_map_valid(src, PCO_IO_S0 + s, &needs_s124);
|
||||
PCO_ASSERT(state,
|
||||
valid,
|
||||
"HW register reference should be mapped to %s",
|
||||
needs_s124 ? "S1/S2/S4" : "S0/S2/S3");
|
||||
}
|
||||
|
||||
pco_foreach_instr_in_igrp (instr, igrp) {
|
||||
const struct pco_op_info *info = &pco_op_info[instr->op];
|
||||
enum pco_op_phase phase = instr->phase;
|
||||
state->instr = instr;
|
||||
|
||||
/* Instruction dests. */
|
||||
state->ref_cursor = REF_CURSOR_INSTR_DEST;
|
||||
for (unsigned d = 0; d < instr->num_dests; ++d) {
|
||||
state->ref = &instr->dest[d];
|
||||
PCO_ASSERT(state,
|
||||
ref_is_in_map(instr->dest[d],
|
||||
info->grp_dest_maps[phase][d]),
|
||||
"Invalid dest assignment.");
|
||||
}
|
||||
|
||||
/* Instruction sources. */
|
||||
state->ref_cursor = REF_CURSOR_INSTR_SRC;
|
||||
for (unsigned s = 0; s < instr->num_srcs; ++s) {
|
||||
state->ref = &instr->src[s];
|
||||
PCO_ASSERT(state,
|
||||
ref_is_in_map(instr->src[s],
|
||||
info->grp_src_maps[phase][s]),
|
||||
"Invalid src assignment.");
|
||||
}
|
||||
|
||||
state->instr = NULL;
|
||||
}
|
||||
|
||||
state->igrp = NULL;
|
||||
state->cf_node = NULL;
|
||||
}
|
||||
|
||||
state->func = NULL;
|
||||
state->ref = NULL;
|
||||
state->ref_cursor = REF_CURSOR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Validates a PCO shader.
|
||||
*
|
||||
* \param[in] shader PCO shader.
|
||||
* \param[in] when When the validation check is being run.
|
||||
*/
|
||||
void pco_validate_shader(UNUSED pco_shader *shader, UNUSED const char *when)
|
||||
void pco_validate_shader(pco_shader *shader, const char *when)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (PCO_DEBUG(VAL_SKIP))
|
||||
return;
|
||||
|
||||
@@ -255,8 +442,13 @@ void pco_validate_shader(UNUSED pco_shader *shader, UNUSED const char *when)
|
||||
if (!shader->is_grouped) {
|
||||
pco_validate_ssa(&state);
|
||||
pco_validate_src_maps(&state);
|
||||
} else {
|
||||
PCO_ASSERT(&state,
|
||||
shader->is_legalized,
|
||||
"Legalize pass should have been run before grouping");
|
||||
pco_validate_ref_maps(&state);
|
||||
}
|
||||
|
||||
puts("finishme: pco_validate_shader");
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
#else /* NDEBUG */
|
||||
void pco_validate_shader(UNUSED pco_shader *shader, UNUSED const char *when) {}
|
||||
#endif /* NDEBUG */
|
||||
|
||||
Reference in New Issue
Block a user