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 <alyssa@rosenzweig.io>
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Acked-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24671>
This commit is contained in:
Alyssa Rosenzweig 2023-08-14 10:38:03 -04:00
parent 316af8c965
commit 335cf5f22f

View file

@ -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;
}