pan/midgard: Add mir_foreach_instr_in_block_rev
[mesa.git] / src / panfrost / midgard / compiler.h
index 61fe8a92b2e96983942b9061d959f0e84c198be8..6f953d48cb80c1f44d9ac04c9ad3840cdc184b83 100644 (file)
@@ -173,6 +173,8 @@ typedef struct midgard_block {
         struct midgard_block *successors[2];
         unsigned nr_successors;
 
+        struct set *predecessors;
+
         /* The successors pointer form a graph, and in the case of
          * complex control flow, this graph has a cycles. To aid
          * traversal during liveness analysis, we have a visited?
@@ -334,6 +336,8 @@ mir_next_op(struct midgard_instruction *ins)
 
 #define mir_foreach_instr_in_block(block, v) \
         list_for_each_entry(struct midgard_instruction, v, &block->instructions, link)
+#define mir_foreach_instr_in_block_rev(block, v) \
+        list_for_each_entry_rev(struct midgard_instruction, v, &block->instructions, link)
 
 #define mir_foreach_instr_in_block_safe(block, v) \
         list_for_each_entry_safe(struct midgard_instruction, v, &block->instructions, link)
@@ -358,6 +362,25 @@ mir_next_op(struct midgard_instruction *ins)
         mir_foreach_block(ctx, v_block) \
                 mir_foreach_instr_in_block_safe(v_block, v)
 
+#define mir_foreach_successor(blk, v) \
+        struct midgard_block *v; \
+        struct midgard_block **_v; \
+        for (_v = &blk->successors[0], \
+                v = *_v; \
+                v != NULL && _v < &blk->successors[2]; \
+                _v++, v = *_v) \
+
+/* Based on set_foreach, expanded with automatic type casts */
+
+#define mir_foreach_predecessor(blk, v) \
+        struct set_entry *_entry_##v; \
+        struct midgard_block *v; \
+        for (_entry_##v = _mesa_set_next_entry(blk->predecessors, NULL), \
+                v = (struct midgard_block *) (_entry_##v ? _entry_##v->key : NULL);  \
+                _entry_##v != NULL; \
+                _entry_##v = _mesa_set_next_entry(blk->predecessors, _entry_##v), \
+                v = (struct midgard_block *) (_entry_##v ? _entry_##v->key : NULL))
+
 static inline midgard_instruction *
 mir_last_in_block(struct midgard_block *block)
 {
@@ -375,6 +398,19 @@ mir_get_block(compiler_context *ctx, int idx)
         return (struct midgard_block *) lst;
 }
 
+static inline midgard_block *
+mir_exit_block(struct compiler_context *ctx)
+{
+        midgard_block *last = list_last_entry(&ctx->blocks,
+                        struct midgard_block, link);
+
+        /* The last block must be empty (the exit block) */
+        assert(list_empty(&last->instructions));
+        assert(last->nr_successors == 0);
+
+        return last;
+}
+
 static inline bool
 mir_is_alu_bundle(midgard_bundle *bundle)
 {