Module: Mesa Branch: main Commit: 335cf5f22f2a662a3869efae87745f1a533917fa URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=335cf5f22f2a662a3869efae87745f1a533917fa
Author: Alyssa Rosenzweig <[email protected]> Date: Mon Aug 14 10:38:03 2023 -0400 nir: Use a tagged pointer for nir_src parents This allows us to pack the is_if boolean into the bottom bit of the parent pointer, eliminating the boolean and hence shrinking the nir_src by 8 bytes (due to the extra 63 bits of padding incurred in the old layout). Because all access is forced through helpers now, this is a local change. Signed-off-by: Alyssa Rosenzweig <[email protected]> Reviewed-by: Rhys Perry <[email protected]> Acked-by: Faith Ekstrand <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24671> --- src/compiler/nir/nir.h | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 0597cddcd8e..dbab63aa32b 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -997,56 +997,75 @@ struct nir_src; struct nir_if; typedef struct nir_src { - union { - /** Instruction that consumes this value as a source. */ - nir_instr *renamed_parent_instr; - struct nir_if *parent_if; - }; + /* Instruction or if-statement that consumes this value as a source. This + * should only be accessed through nir_src_* helpers. + * + * Internally, it is a tagged pointer to a nir_instr or nir_if. + */ + uintptr_t _parent; struct list_head use_link; nir_def *ssa; - - bool is_if; } nir_src; +/* Layout of the _parent pointer. Bottom bit is set for nir_if parents (clear + * for nir_instr parents). Remaining bits are the pointer. + */ +#define NIR_SRC_PARENT_IS_IF (0x1) +#define NIR_SRC_PARENT_MASK (~((uintptr_t) NIR_SRC_PARENT_IS_IF)) + static inline bool nir_src_is_if(const nir_src *src) { - return src->is_if; + return src->_parent & NIR_SRC_PARENT_IS_IF; } static inline nir_instr * nir_src_parent_instr(const nir_src *src) { assert(!nir_src_is_if(src)); - return src->renamed_parent_instr; + + /* Because it is not an if, the tag is 0, therefore we do not need to mask */ + return (nir_instr *)(src->_parent); } static inline struct nir_if * nir_src_parent_if(const nir_src *src) { assert(nir_src_is_if(src)); - return src->parent_if; + + /* Because it is an if, the tag is 1, so we need to mask */ + return (struct nir_if *)(src->_parent & NIR_SRC_PARENT_MASK); +} + +static inline void +_nir_src_set_parent(nir_src *src, void *parent, bool is_if) +{ + uintptr_t ptr = (uintptr_t) parent; + assert((ptr & ~NIR_SRC_PARENT_MASK) == 0 && "pointer must be aligned"); + + if (is_if) + ptr |= NIR_SRC_PARENT_IS_IF; + + src->_parent = ptr; } static inline void nir_src_set_parent_instr(nir_src *src, nir_instr *parent_instr) { - src->is_if = false; - src->renamed_parent_instr = parent_instr; + _nir_src_set_parent(src, parent_instr, false); } static inline void nir_src_set_parent_if(nir_src *src, struct nir_if *parent_if) { - src->is_if = true; - src->parent_if = parent_if; + _nir_src_set_parent(src, parent_if, true); } static inline nir_src nir_src_init(void) { - nir_src src = { { NULL } }; + nir_src src = { 0 }; return src; }
