From bcefeef1d18fb267c83d10bf655a9f33f9771bb4 Mon Sep 17 00:00:00 2001 From: Simon Perretta Date: Sun, 19 Jan 2025 14:43:52 +0000 Subject: [PATCH] pco: add helpers for phase iteration, print more igrp offset info Signed-off-by: Simon Perretta Acked-by: Erik Faye-Lund Part-of: --- src/imagination/.clang-format | 8 ++ src/imagination/pco/pco_binary.c | 5 +- src/imagination/pco/pco_group_instrs.c | 4 +- src/imagination/pco/pco_internal.h | 49 ++++++-- src/imagination/pco/pco_print.c | 151 +++++++++++++++++++------ 5 files changed, 164 insertions(+), 53 deletions(-) diff --git a/src/imagination/.clang-format b/src/imagination/.clang-format index 937b4855461..d660e17a4c1 100644 --- a/src/imagination/.clang-format +++ b/src/imagination/.clang-format @@ -290,6 +290,14 @@ ForEachMacros: [ 'pco_foreach_loop_in_func_from', 'pco_foreach_loop_in_func_from_rev', 'pco_foreach_loop_in_func_rev', + 'pco_foreach_phase', + 'pco_foreach_phase_from', + 'pco_foreach_phase_from_rev', + 'pco_foreach_phase_in_igrp', + 'pco_foreach_phase_in_igrp_from', + 'pco_foreach_phase_in_igrp_from_rev', + 'pco_foreach_phase_in_igrp_rev', + 'pco_foreach_phase_rev', 'pco_foreach_phi_src_in_instr', 'rogue_foreach_block', 'rogue_foreach_block_safe', diff --git a/src/imagination/pco/pco_binary.c b/src/imagination/pco/pco_binary.c index 090d230d870..faded9b8fed 100644 --- a/src/imagination/pco/pco_binary.c +++ b/src/imagination/pco/pco_binary.c @@ -69,10 +69,7 @@ static unsigned pco_encode_igrp(struct util_dynarray *buf, pco_igrp *igrp) bytes_encoded += pco_igrp_hdr_map_encode(ptr, igrp); /* Instructions. */ - for (enum pco_op_phase p = _PCO_OP_PHASE_COUNT; p-- > 0;) { - if (!igrp->enc.len.instrs[p]) - continue; - + pco_foreach_phase_in_igrp_rev (igrp, p) { ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.instrs[p]); bytes_encoded += pco_instr_map_encode(ptr, igrp, p); } diff --git a/src/imagination/pco/pco_group_instrs.c b/src/imagination/pco/pco_group_instrs.c index 21d648f9a03..ae1ec0078ec 100644 --- a/src/imagination/pco/pco_group_instrs.c +++ b/src/imagination/pco/pco_group_instrs.c @@ -34,7 +34,7 @@ static inline unsigned calc_da(pco_igrp *igrp) switch (igrp->hdr.alutype) { case PCO_ALUTYPE_MAIN: case PCO_ALUTYPE_BITWISE: { - for (enum pco_op_phase p = _PCO_OP_PHASE_COUNT; p-- > 0;) { + pco_foreach_phase_rev (p) { if (igrp->hdr.alutype == PCO_ALUTYPE_BITWISE || p > PCO_OP_PHASE_1) da += igrp->enc.len.instrs[p]; } @@ -80,7 +80,7 @@ static inline void calc_lengths(pco_igrp *igrp, unsigned *offset_bytes) igrp->enc.len.dests = pco_dst_bytes(igrp->variant.dest); total_length += igrp->enc.len.dests; - for (enum pco_op_phase phase = 0; phase < _PCO_OP_PHASE_COUNT; ++phase) { + pco_foreach_phase_in_igrp (igrp, phase) { switch (igrp->hdr.alutype) { case PCO_ALUTYPE_MAIN: if (phase == PCO_OP_PHASE_BACKEND) { diff --git a/src/imagination/pco/pco_internal.h b/src/imagination/pco/pco_internal.h index dd7fdb59847..c77ff7423fa 100644 --- a/src/imagination/pco/pco_internal.h +++ b/src/imagination/pco/pco_internal.h @@ -615,6 +615,35 @@ PCO_DEFINE_CAST(pco_cf_node_as_func, pco_foreach_block_in_func (block, func) \ pco_foreach_igrp_in_block (igrp, block) +#define pco_foreach_phase(phase) \ + for (enum pco_op_phase phase = 0; phase < _PCO_OP_PHASE_COUNT; ++phase) + +#define pco_foreach_phase_rev(phase) \ + for (enum pco_op_phase phase = _PCO_OP_PHASE_COUNT; phase-- > 0;) + +#define pco_foreach_phase_from(phase, from) \ + for (enum pco_op_phase phase = from + 1; phase < _PCO_OP_PHASE_COUNT; \ + ++phase) + +#define pco_foreach_phase_from_rev(phase, from) \ + for (enum pco_op_phase phase = from; phase-- > 0;) + +#define pco_foreach_phase_in_igrp(igrp, phase) \ + pco_foreach_phase (phase) \ + if (igrp->instrs[phase]) + +#define pco_foreach_phase_in_igrp_rev(igrp, phase) \ + pco_foreach_phase_rev (phase) \ + if (igrp->instrs[phase]) + +#define pco_foreach_phase_in_igrp_from(igrp, phase, from) \ + pco_foreach_phase_from (phase, from) \ + if (igrp->instrs[phase]) + +#define pco_foreach_phase_in_igrp_from_rev(igrp, phase, from) \ + pco_foreach_phase_from_rev (phase, from) \ + if (igrp->instrs[phase]) + #define pco_foreach_instr_in_igrp(instr, igrp) \ for (pco_instr *instr = pco_igrp_first_instr(igrp); instr != NULL; \ instr = pco_igrp_next_instr(instr)) @@ -1391,9 +1420,8 @@ static inline pco_igrp *pco_prev_igrp(pco_igrp *igrp) */ static inline pco_instr *pco_igrp_first_instr(pco_igrp *igrp) { - for (enum pco_op_phase p = 0; p < _PCO_OP_PHASE_COUNT; ++p) - if (igrp->instrs[p]) - return igrp->instrs[p]; + pco_foreach_phase_in_igrp (igrp, p) + return igrp->instrs[p]; return NULL; } @@ -1406,9 +1434,8 @@ static inline pco_instr *pco_igrp_first_instr(pco_igrp *igrp) */ static inline pco_instr *pco_igrp_last_instr(pco_igrp *igrp) { - for (enum pco_op_phase p = _PCO_OP_PHASE_COUNT; p-- > 0;) - if (igrp->instrs[p]) - return igrp->instrs[p]; + pco_foreach_phase_in_igrp_rev (igrp, p) + return igrp->instrs[p]; return NULL; } @@ -1425,9 +1452,8 @@ static inline pco_instr *pco_igrp_next_instr(pco_instr *instr) return NULL; pco_igrp *igrp = instr->parent_igrp; - for (enum pco_op_phase p = instr->phase + 1; p < _PCO_OP_PHASE_COUNT; ++p) - if (igrp->instrs[p]) - return igrp->instrs[p]; + pco_foreach_phase_in_igrp_from (igrp, p, instr->phase) + return igrp->instrs[p]; return NULL; } @@ -1445,9 +1471,8 @@ static inline pco_instr *pco_igrp_prev_instr(pco_instr *instr) return NULL; pco_igrp *igrp = instr->parent_igrp; - for (enum pco_op_phase p = instr->phase; p-- > 0;) - if (igrp->instrs[p]) - return igrp->instrs[p]; + pco_foreach_phase_in_igrp_from_rev (igrp, p, instr->phase) + return igrp->instrs[p]; return NULL; } diff --git a/src/imagination/pco/pco_print.c b/src/imagination/pco/pco_print.c index 7ca02eafd65..d18bedd3e33 100644 --- a/src/imagination/pco/pco_print.c +++ b/src/imagination/pco/pco_print.c @@ -34,6 +34,14 @@ typedef struct _pco_print_state { bool verbose; /** Whether to print additional info. */ } pco_print_state; +typedef struct _pco_igrp_offsets { + unsigned instrs[_PCO_OP_PHASE_COUNT]; + unsigned lower_srcs; + unsigned upper_srcs; + unsigned iss; + unsigned dests; +} pco_igrp_offsets; + /* Forward declarations. */ static void _pco_print_cf_node(pco_print_state *state, pco_cf_node *cf_node); static void pco_print_block_name(pco_print_state *state, pco_block *block); @@ -170,14 +178,14 @@ static void pco_printfi(pco_print_state *state, const char *fmt, ...) } /** - * \brief Returns a space if the string is not empty. + * \brief Returns whether the string is not empty. * * \param[in] str String. - * \return A space if the string is not empty, else an empty string. + * \return True if the string is not empty, else false. */ -static inline const char *space_if_str(const char *str) +static inline bool if_str(const char *str) { - return str[0] != '\0' ? " " : ""; + return str[0] != '\0'; } /** @@ -371,6 +379,9 @@ static void pco_print_instr_mods(pco_print_state *state, pco_instr *instr, bool print_early) { + if (print_early) + WHITE(state); + u_foreach_bit64 (op_mod, op_info->mods) { const struct pco_op_mod_info *mod_info = &pco_op_mod_info[op_mod]; if (mod_info->print_early != print_early) @@ -417,6 +428,9 @@ static void pco_print_instr_mods(pco_print_state *state, UNREACHABLE(""); } } + + if (print_early) + RESET(state); } /** @@ -573,10 +587,7 @@ static void _pco_print_phase(pco_print_state *state, static void pco_print_igrp_phases(pco_print_state *state, pco_igrp *igrp) { bool printed = false; - for (enum pco_op_phase phase = 0; phase < _PCO_OP_PHASE_COUNT; ++phase) { - if (!igrp->instrs[phase]) - continue; - + pco_foreach_phase_in_igrp (igrp, phase) { if (printed) pco_printf(state, ","); @@ -658,6 +669,37 @@ static void pco_print_igrp_dests(pco_print_state *state, pco_igrp *igrp) } } +static inline void pco_calc_igrp_offsets(pco_igrp *igrp, + pco_igrp_offsets *offsets) +{ + memset(offsets, 0, sizeof(*offsets)); + unsigned offset = igrp->enc.len.hdr; + + pco_foreach_phase_in_igrp_rev (igrp, p) { + offsets->instrs[p] = offset; + offset += igrp->enc.len.instrs[p]; + } + + offsets->lower_srcs = offset; + offset += igrp->enc.len.lower_srcs; + + offsets->upper_srcs = offset; + offset += igrp->enc.len.upper_srcs; + + offsets->iss = offset; + offset += igrp->enc.len.iss; + + offsets->dests = offset; + +#ifndef NDEBUG + /* Sanity check. */ + offset += igrp->enc.len.dests; + offset += igrp->enc.len.word_padding; + offset += igrp->enc.len.align_padding; + assert(offset == igrp->enc.len.total); +#endif /* NDEBUG */ +} + /** * \brief Print PCO instruction group. * @@ -668,11 +710,20 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp) { bool printed = false; - pco_printfi(state, - "%04u:%s%s { ", - igrp->index, - space_if_str(pco_cc_str(igrp->hdr.cc)), - pco_cc_str(igrp->hdr.cc)); + pco_igrp_offsets offsets; + if (state->verbose) + pco_calc_igrp_offsets(igrp, &offsets); + + pco_printfi(state, "%04u:", igrp->index); + + const char *cc_str = pco_cc_str(igrp->hdr.cc); + if (if_str(cc_str)) { + WHITE(state); + pco_printf(state, " %s", cc_str); + RESET(state); + } + + pco_printf(state, " { "); if (state->verbose) { unsigned padding_size = @@ -698,7 +749,7 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp) ++state->indent; pco_printfi(state, - "type %s /* hdr bytes: %u */\n", + "type %s /* hdr bytes: %u @ +0 */\n", pco_alutype_str(igrp->hdr.alutype), igrp->enc.len.hdr); } @@ -728,8 +779,9 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp) if (state->verbose) pco_printf(state, - "/* lo src bytes: %u */\n", - igrp->enc.len.lower_srcs); + "/* lo src bytes: %u @ +%u */\n", + igrp->enc.len.lower_srcs, + offsets.lower_srcs); printed = true; } @@ -750,8 +802,9 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp) if (state->verbose) pco_printf(state, - "/* up src bytes: %u */\n", - igrp->enc.len.upper_srcs); + "/* up src bytes: %u @ +%u */\n", + igrp->enc.len.upper_srcs, + offsets.upper_srcs); printed = true; } @@ -771,14 +824,16 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp) } if (state->verbose) - pco_printf(state, "/* iss bytes: %u */\n", igrp->enc.len.iss); + pco_printf(state, + "/* iss bytes: %u @ +%u */\n", + igrp->enc.len.iss, + offsets.iss); printed = true; } - for (enum pco_op_phase phase = 0; phase < _PCO_OP_PHASE_COUNT; ++phase) { - if (!igrp->instrs[phase]) - continue; + pco_foreach_instr_in_igrp (instr, igrp) { + enum pco_op_phase phase = instr->phase; if (state->verbose) pco_printfi(state, "%s", ""); @@ -787,12 +842,15 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp) _pco_print_phase(state, igrp->hdr.alutype, phase); pco_printf(state, ": "); - _pco_print_instr(state, igrp->instrs[phase]); + _pco_print_instr(state, instr); if (state->verbose) { pco_printf(state, " /* "); _pco_print_phase(state, igrp->hdr.alutype, phase); - pco_printf(state, " bytes: %u */\n", igrp->enc.len.instrs[phase]); + pco_printf(state, + " bytes: %u @ +%u */\n", + igrp->enc.len.instrs[phase], + offsets.instrs[phase]); } printed = true; @@ -813,7 +871,10 @@ static void _pco_print_igrp(pco_print_state *state, pco_igrp *igrp) } if (state->verbose) - pco_printf(state, "/* dest bytes: %u */\n", igrp->enc.len.dests); + pco_printf(state, + "/* dest bytes: %u @ +%u */\n", + igrp->enc.len.dests, + offsets.dests); printed = true; } @@ -914,7 +975,9 @@ static void pco_print_if(pco_print_state *state, pco_if *pif) pco_printf(state, " {\n"); if (!exec_list_is_empty(&pif->prologue)) { - pco_printfi(state, "/* prologue start */\n"); + pco_printfi(state, "/* if "); + pco_print_if_name(state, pif); + pco_printf(state, " prologue start */\n"); ++state->indent; pco_foreach_cf_node_in_if_prologue (cf_node, pif) { @@ -922,7 +985,9 @@ static void pco_print_if(pco_print_state *state, pco_if *pif) } --state->indent; - pco_printfi(state, "/* prologue end */\n"); + pco_printfi(state, "/* if "); + pco_print_if_name(state, pif); + pco_printf(state, " prologue end */\n"); } if (!exec_list_is_empty(&pif->then_body)) { @@ -937,7 +1002,9 @@ static void pco_print_if(pco_print_state *state, pco_if *pif) pco_printfi(state, "} else {\n"); if (!exec_list_is_empty(&pif->interlogue)) { - pco_printfi(state, "/* interlogue start */\n"); + pco_printfi(state, "/* if "); + pco_print_if_name(state, pif); + pco_printf(state, " interlogue start */\n"); ++state->indent; pco_foreach_cf_node_in_if_interlogue (cf_node, pif) { @@ -945,7 +1012,9 @@ static void pco_print_if(pco_print_state *state, pco_if *pif) } --state->indent; - pco_printfi(state, "/* interlogue end */\n"); + pco_printfi(state, "/* if "); + pco_print_if_name(state, pif); + pco_printf(state, " interlogue end */\n"); } ++state->indent; @@ -958,7 +1027,9 @@ static void pco_print_if(pco_print_state *state, pco_if *pif) } if (!exec_list_is_empty(&pif->epilogue)) { - pco_printfi(state, "/* epilogue start */\n"); + pco_printfi(state, "/* if "); + pco_print_if_name(state, pif); + pco_printf(state, " epilogue start */\n"); ++state->indent; pco_foreach_cf_node_in_if_epilogue (cf_node, pif) { @@ -966,7 +1037,9 @@ static void pco_print_if(pco_print_state *state, pco_if *pif) } --state->indent; - pco_printfi(state, "/* epilogue end */\n"); + pco_printfi(state, "/* if "); + pco_print_if_name(state, pif); + pco_printf(state, " epilogue end */\n"); } pco_printfi(state, "}\n"); @@ -996,7 +1069,9 @@ static void pco_print_loop(pco_print_state *state, pco_loop *loop) pco_printf(state, " {\n"); if (!exec_list_is_empty(&loop->prologue)) { - pco_printfi(state, "/* prologue start */\n"); + pco_printfi(state, "/* loop "); + pco_print_loop_name(state, loop); + pco_printf(state, " prologue start */\n"); ++state->indent; pco_foreach_cf_node_in_loop_prologue (cf_node, loop) { @@ -1004,7 +1079,9 @@ static void pco_print_loop(pco_print_state *state, pco_loop *loop) } --state->indent; - pco_printfi(state, "/* prologue end */\n"); + pco_printfi(state, "/* loop "); + pco_print_loop_name(state, loop); + pco_printf(state, " prologue end */\n"); } if (!exec_list_is_empty(&loop->body)) { @@ -1032,7 +1109,9 @@ static void pco_print_loop(pco_print_state *state, pco_loop *loop) } if (!exec_list_is_empty(&loop->epilogue)) { - pco_printfi(state, "/* epilogue start */\n"); + pco_printfi(state, "/* loop "); + pco_print_loop_name(state, loop); + pco_printf(state, " epilogue start */\n"); ++state->indent; pco_foreach_cf_node_in_loop_epilogue (cf_node, loop) { @@ -1040,7 +1119,9 @@ static void pco_print_loop(pco_print_state *state, pco_loop *loop) } --state->indent; - pco_printfi(state, "/* epilogue end */\n"); + pco_printfi(state, "/* loop "); + pco_print_loop_name(state, loop); + pco_printf(state, " epilogue end */\n"); } pco_printfi(state, "}\n");