bool writeout;
bool prepacked_branch;
+ /* Kind of a hack, but hint against aggressive DCE */
+ bool dont_eliminate;
+
/* Masks in a saneish format. One bit per channel, not packed fancy.
* Use this instead of the op specific ones, and switch over at emit
* time */
bool invert;
+ /* Hint for the register allocator not to spill the destination written
+ * from this instruction (because it is a spill/unspill node itself) */
+
+ bool no_spill;
+
+ /* Generic hint for intra-pass use */
+ bool hint;
+
union {
midgard_load_store_word load_store;
midgard_vector_alu alu;
/* 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) */
/* 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?
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;
/* Alpha ref value passed in */
float alpha_ref;
- /* The index corresponding to the fragment output */
- unsigned fragment_output;
-
/* The mapping of sysvals to uniforms, the count, and the off-by-one inverse */
unsigned sysvals[MAX_SYSVAL_COUNT];
unsigned sysval_count;
#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))
+
+#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)
{
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)
{
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 */
midgard_instruction *
emit_ubo_read(
compiler_context *ctx,
+ nir_instr *instr,
unsigned dest,
unsigned offset,
nir_src *indirect_offset,