mesa/src/imagination/pco/pco_binary.c
Alyssa Rosenzweig b824ef83ab util/dynarray: infer type in append
Most of the time, we can infer the type to append in
util_dynarray_append using __typeof__, which is standardized in C23 and
support in Jesse's MSMSVCV. This patch drops the type argument most of
the time, making util_dynarray a little more ergonomic to use.

This is done in four steps.

First, rename util_dynarray_append -> util_dynarray_append_typed

    bash -c "find . -type f -exec sed -i -e 's/util_dynarray_append(/util_dynarray_append_typed(/g' \{} \;"

Then, add a new append that infers the type. This is much more ergonomic
for what you want most of the time.

Next, use type-inferred append as much as possible, via Coccinelle
patch (plus manual fixup):

    @@
    expression dynarray, element;
    type type;
    @@

    -util_dynarray_append_typed(dynarray, type, element);
    +util_dynarray_append(dynarray, element);

Finally, hand fixup cases that Coccinelle missed or incorrectly
translated, of which there were several because we can't used the
untyped append with a literal (since the sizeof won't do what you want).

All four steps are squashed to produce a single patch changing every
util_dynarray_append call site in tree to either drop a type parameter
(if possible) or insert a _typed suffix (if we can't infer). As such,
the final patch is best reviewed by hand even though it was
tool-assisted.

No Long Linguine Meals were involved in the making of this patch.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@intel.com>
Acked-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/38038>
2025-10-24 18:32:07 +00:00

157 lines
3.8 KiB
C

/*
* Copyright © 2024 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: MIT
*/
/**
* \file pco_binary.c
*
* \brief PCO binary-specific functions.
*/
#include "pco.h"
#include "pco_internal.h"
#include "pco_isa.h"
#include "pco_map.h"
#include "util/u_dynarray.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
/**
* \brief Encodes instruction group alignment.
*
* \param[in,out] buf Binary buffer.
* \param[in] igrp PCO instruction group.
*/
static inline unsigned pco_encode_align(struct util_dynarray *buf,
pco_igrp *igrp)
{
unsigned bytes_encoded = 0;
if (igrp->enc.len.word_padding) {
util_dynarray_append_typed(buf, uint8_t, 0xff);
bytes_encoded += 1;
}
if (igrp->enc.len.align_padding) {
assert(!(igrp->enc.len.align_padding % 2));
unsigned align_words = igrp->enc.len.align_padding / 2;
util_dynarray_append_typed(buf, uint8_t, 0xf0 | align_words);
bytes_encoded += 1;
for (unsigned u = 0; u < igrp->enc.len.align_padding - 1; ++u) {
util_dynarray_append_typed(buf, uint8_t, 0xff);
bytes_encoded += 1;
}
}
return bytes_encoded;
}
/**
* \brief Encodes a PCO instruction group into binary.
*
* \param[in,out] buf Binary buffer.
* \param[in] igrp PCO instruction group.
* \return The number of bytes encoded.
*/
static unsigned pco_encode_igrp(struct util_dynarray *buf, pco_igrp *igrp)
{
uint8_t *ptr;
unsigned bytes_encoded = 0;
/* Header. */
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.hdr);
bytes_encoded += pco_igrp_hdr_map_encode(ptr, igrp);
/* Instructions. */
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);
}
/* I/O. */
if (igrp->enc.len.lower_srcs) {
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.lower_srcs);
bytes_encoded += pco_srcs_map_encode(ptr, igrp, false);
}
if (igrp->enc.len.upper_srcs) {
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.upper_srcs);
bytes_encoded += pco_srcs_map_encode(ptr, igrp, true);
}
if (igrp->enc.len.iss) {
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.iss);
bytes_encoded += pco_iss_map_encode(ptr, igrp);
}
if (igrp->enc.len.dests) {
ptr = util_dynarray_grow(buf, uint8_t, igrp->enc.len.dests);
bytes_encoded += pco_dests_map_encode(ptr, igrp);
}
/* Word/alignment padding. */
bytes_encoded += pco_encode_align(buf, igrp);
assert(bytes_encoded == igrp->enc.len.total);
return bytes_encoded;
}
/**
* \brief Encodes a PCO shader into binary.
*
* \param[in] ctx PCO compiler context.
* \param[in,out] shader PCO shader.
*/
void pco_encode_ir(pco_ctx *ctx, pco_shader *shader)
{
assert(shader->is_grouped);
util_dynarray_init(&shader->binary, shader);
unsigned bytes_encoded = 0;
pco_foreach_func_in_shader (func, shader) {
func->enc_offset = bytes_encoded;
pco_foreach_block_in_func (block, func) {
pco_foreach_igrp_in_block (igrp, block) {
bytes_encoded += pco_encode_igrp(&shader->binary, igrp);
}
}
}
if (pco_should_print_binary(shader))
pco_print_binary(shader, stdout, "after encoding");
}
/**
* \brief Returns the size in bytes of a PCO shader binary.
*
* \param[in] shader PCO shader.
* \return The size in bytes of the PCO shader binary.
*/
unsigned pco_shader_binary_size(pco_shader *shader)
{
if (!shader)
return 0;
return shader->binary.size;
}
/**
* \brief Returns the PCO shader binary data.
*
* \param[in] shader PCO shader.
* \return The PCO shader binary data.
*/
const void *pco_shader_binary_data(pco_shader *shader)
{
if (!shader)
return NULL;
return shader->binary.data;
}