summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir/nir.h')
-rw-r--r--src/compiler/nir/nir.h99
1 files changed, 92 insertions, 7 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index a55e6821cbe..b23130e205b 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1550,6 +1550,12 @@ nir_start_block(nir_function_impl *impl)
return (nir_block *) exec_list_get_head(&impl->body);
}
+static inline nir_block *
+nir_impl_last_block(nir_function_impl *impl)
+{
+ return (nir_block *) exec_list_get_tail(&impl->body);
+}
+
static inline nir_cf_node *
nir_cf_node_next(nir_cf_node *node)
{
@@ -2121,14 +2127,93 @@ void nir_ssa_def_rewrite_uses_after(nir_ssa_def *def, nir_src new_src,
uint8_t nir_ssa_def_components_read(nir_ssa_def *def);
-/* visits basic blocks in source-code order */
+/*
+ * finds the next basic block in source-code order, returns NULL if there is
+ * none
+ */
+
+nir_block *nir_block_cf_tree_next(nir_block *block);
+
+/* Performs the opposite of nir_block_cf_tree_next() */
+
+nir_block *nir_block_cf_tree_prev(nir_block *block);
+
+/* Gets the first block in a CF node in source-code order */
+
+nir_block *nir_cf_node_cf_tree_first(nir_cf_node *node);
+
+/* Gets the last block in a CF node in source-code order */
+
+nir_block *nir_cf_node_cf_tree_last(nir_cf_node *node);
+
+/* Gets the next block after a CF node in source-code order */
+
+nir_block *nir_cf_node_cf_tree_next(nir_cf_node *node);
+
+/* Macros for loops that visit blocks in source-code order */
+
+#define nir_foreach_block(block, impl) \
+ for (nir_block *block = nir_start_block(impl); block != NULL; \
+ block = nir_block_cf_tree_next(block))
+
+#define nir_foreach_block_safe(block, impl) \
+ for (nir_block *block = nir_start_block(impl), \
+ *next = nir_block_cf_tree_next(block); \
+ block != NULL; \
+ block = next, next = nir_block_cf_tree_next(block))
+
+#define nir_foreach_block_reverse(block, impl) \
+ for (nir_block *block = nir_impl_last_block(impl); block != NULL; \
+ block = nir_block_cf_tree_prev(block))
+
+#define nir_foreach_block_reverse_safe(block, impl) \
+ for (nir_block *block = nir_impl_last_block(impl), \
+ *prev = nir_block_cf_tree_prev(block); \
+ block != NULL; \
+ block = prev, prev = nir_block_cf_tree_prev(block))
+
+#define nir_foreach_block_in_cf_node(block, node) \
+ for (nir_block *block = nir_cf_node_cf_tree_first(node); \
+ block != nir_cf_node_cf_tree_next(node); \
+ block = nir_block_cf_tree_next(block))
+
typedef bool (*nir_foreach_block_cb)(nir_block *block, void *state);
-bool nir_foreach_block_call(nir_function_impl *impl, nir_foreach_block_cb cb,
- void *state);
-bool nir_foreach_block_reverse_call(nir_function_impl *impl, nir_foreach_block_cb cb,
- void *state);
-bool nir_foreach_block_in_cf_node_call(nir_cf_node *node, nir_foreach_block_cb cb,
- void *state);
+
+static inline bool
+nir_foreach_block_call(nir_function_impl *impl, nir_foreach_block_cb cb,
+ void *state)
+{
+ nir_foreach_block_safe(block, impl) {
+ if (!cb(block, state))
+ return false;
+ }
+
+ return true;
+}
+
+static inline bool
+nir_foreach_block_reverse_call(nir_function_impl *impl, nir_foreach_block_cb cb,
+ void *state)
+{
+ nir_foreach_block_reverse_safe(block, impl) {
+ if (!cb(block, state))
+ return false;
+ }
+
+ return true;
+}
+
+static inline bool
+nir_foreach_block_in_cf_node_call(nir_cf_node *node, nir_foreach_block_cb cb,
+ void *state)
+{
+ nir_foreach_block_in_cf_node(block, node) {
+ if (!cb(block, state))
+ return false;
+ }
+
+ return true;
+}
/* If the following CF node is an if, this function returns that if.
* Otherwise, it returns NULL.