spirv: Add cast and loop helpers for vtn_cf_node
Cherry-pick'd from 9d7fcf1de04b69d8657671220265f8ec5e1cd274
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3820>
Change-Id: I52309997d67811d3764aab626f713817aad072b2
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/mesa/+/403193
Reviewed-by: John Bauman <jbauman@google.com>
diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c
index 08a6b10..700caf8 100644
--- a/src/compiler/spirv/vtn_cfg.c
+++ b/src/compiler/spirv/vtn_cfg.c
@@ -922,10 +922,10 @@
nir_variable *switch_fall_var, bool *has_switch_break,
vtn_instruction_handler handler)
{
- list_for_each_entry(struct vtn_cf_node, node, cf_list, link) {
+ vtn_foreach_cf_node(node, cf_list) {
switch (node->type) {
case vtn_cf_node_type_block: {
- struct vtn_block *block = (struct vtn_block *)node;
+ struct vtn_block *block = vtn_cf_node_as_block(node);
const uint32_t *block_start = block->label;
const uint32_t *block_end = block->merge ? block->merge :
@@ -963,7 +963,7 @@
}
case vtn_cf_node_type_if: {
- struct vtn_if *vtn_if = (struct vtn_if *)node;
+ struct vtn_if *vtn_if = vtn_cf_node_as_if(node);
bool sw_break = false;
nir_if *nif =
@@ -1002,7 +1002,7 @@
}
case vtn_cf_node_type_loop: {
- struct vtn_loop *vtn_loop = (struct vtn_loop *)node;
+ struct vtn_loop *vtn_loop = vtn_cf_node_as_loop(node);
nir_loop *loop = nir_push_loop(&b->nb);
loop->control = vtn_loop_control(b, vtn_loop);
@@ -1039,7 +1039,7 @@
}
case vtn_cf_node_type_switch: {
- struct vtn_switch *vtn_switch = (struct vtn_switch *)node;
+ struct vtn_switch *vtn_switch = vtn_cf_node_as_switch(node);
/* First, we create a variable to keep track of whether or not the
* switch is still going at any given point. Any switch breaks
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 4b2d289..a042afe 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -242,6 +242,22 @@
SpvFunctionControlMask control;
};
+#define VTN_DECL_CF_NODE_CAST(_type) \
+static inline struct vtn_##_type * \
+vtn_cf_node_as_##_type(struct vtn_cf_node *node) \
+{ \
+ assert(node->type == vtn_cf_node_type_##_type); \
+ return (struct vtn_##_type *)node; \
+}
+
+VTN_DECL_CF_NODE_CAST(block)
+VTN_DECL_CF_NODE_CAST(loop)
+VTN_DECL_CF_NODE_CAST(if)
+VTN_DECL_CF_NODE_CAST(switch)
+
+#define vtn_foreach_cf_node(node, cf_list) \
+ list_for_each_entry(struct vtn_cf_node, node, cf_list, link)
+
typedef bool (*vtn_instruction_handler)(struct vtn_builder *, SpvOp,
const uint32_t *, unsigned);