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?
#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)
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)
{
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)
{