pan/midgard: Index blocks for printing
[mesa.git] / src / panfrost / midgard / compiler.h
index e7b786dd7aca69f01bdb734e8202854d812a8c83..1fddd3f1fe8377e8c432940fb1b827dead5a09e4 100644 (file)
@@ -160,6 +160,9 @@ typedef struct midgard_block {
         /* List of midgard_instructions emitted for the current block */
         struct list_head instructions;
 
+        /* Index of the block in source order */
+        unsigned source_id;
+
         bool is_scheduled;
 
         /* List of midgard_bundles emitted (after the scheduler has run) */
@@ -170,9 +173,11 @@ typedef struct midgard_block {
 
         /* Succeeding blocks. The compiler should not necessarily rely on
          * source-order traversal */
-        struct midgard_block *successors[4];
+        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?
@@ -227,6 +232,9 @@ typedef struct compiler_context {
         int block_count;
         struct list_head blocks;
 
+        /* TODO merge with block_count? */
+        unsigned block_source_count;
+
         /* List of midgard_instructions emitted for the current block */
         midgard_block *current_block;
 
@@ -334,6 +342,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 +368,28 @@ 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))
+
+#define mir_foreach_src(ins, v) \
+        for (unsigned v = 0; v < ARRAY_SIZE(ins->ssa_args.src); ++v)
+
 static inline midgard_instruction *
 mir_last_in_block(struct midgard_block *block)
 {
@@ -375,6 +407,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)
 {
@@ -441,6 +486,7 @@ bool mir_special_index(compiler_context *ctx, unsigned idx);
 unsigned mir_use_count(compiler_context *ctx, unsigned value);
 bool mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node);
 unsigned mir_mask_of_read_components(midgard_instruction *ins, unsigned node);
+unsigned mir_ubo_shift(midgard_load_store_op op);
 
 /* MIR printing */