#include "vc4_screen.h"
#include "vc4_qpu_defines.h"
+#include "vc4_qpu.h"
#include "kernel/vc4_packet.h"
#include "pipe/p_state.h"
bool clamp_color;
};
+/** A basic block of QIR intructions. */
+struct qblock {
+ struct list_head link;
+
+ struct list_head instructions;
+
+ struct set *predecessors;
+ struct qblock *successors[2];
+
+ int index;
+
+ /** @{ used by vc4_qir_live_variables.c */
+ BITSET_WORD *def;
+ BITSET_WORD *use;
+ BITSET_WORD *live_in;
+ BITSET_WORD *live_out;
+ int start_ip, end_ip;
+ /** @} */
+};
+
struct vc4_compile {
struct vc4_context *vc4;
nir_shader *s;
struct vc4_fs_key *fs_key;
struct vc4_vs_key *vs_key;
+ /* Live ranges of temps. */
+ int *temp_start, *temp_end;
+
uint32_t *uniform_data;
enum quniform_contents *uniform_contents;
uint32_t uniform_array_size;
struct qreg undef;
enum qstage stage;
uint32_t num_temps;
- struct list_head instructions;
+
+ struct list_head blocks;
+ int next_block_index;
+ struct qblock *cur_block;
struct list_head qpu_inst_list;
uint64_t *qpu_insts;
struct vc4_compile *qir_compile_init(void);
void qir_compile_destroy(struct vc4_compile *c);
+struct qblock *qir_new_block(struct vc4_compile *c);
+void qir_set_emit_block(struct vc4_compile *c, struct qblock *block);
+void qir_link_blocks(struct qblock *predecessor, struct qblock *successor);
+struct qblock *qir_entry_block(struct vc4_compile *c);
+struct qblock *qir_exit_block(struct vc4_compile *c);
struct qinst *qir_inst(enum qop op, struct qreg dst,
struct qreg src0, struct qreg src1);
struct qinst *qir_inst4(enum qop op, struct qreg dst,
struct qinst *qir_emit_nondef(struct vc4_compile *c, struct qinst *inst);
struct qreg qir_get_temp(struct vc4_compile *c);
+void qir_calculate_live_intervals(struct vc4_compile *c);
int qir_get_op_nsrc(enum qop qop);
bool qir_reg_equals(struct qreg a, struct qreg b);
bool qir_has_side_effects(struct vc4_compile *c, struct qinst *inst);
bool qir_depends_on_flags(struct qinst *inst);
bool qir_writes_r4(struct qinst *inst);
struct qreg qir_follow_movs(struct vc4_compile *c, struct qreg reg);
+uint8_t qir_channels_written(struct qinst *inst);
void qir_dump(struct vc4_compile *c);
void qir_dump_inst(struct vc4_compile *c, struct qinst *inst);
*payload = qir_get_temp(c); \
struct qinst *inst = qir_inst(QOP_##name, *payload, \
c->undef, c->undef); \
- list_add(&inst->link, &c->instructions); \
+ struct qblock *entry = qir_entry_block(c); \
+ list_add(&inst->link, &entry->instructions); \
c->defs[payload->index] = inst; \
return *payload; \
}
struct qinst *a = qir_MOV_dest(c, t, src0);
struct qinst *b = qir_MOV_dest(c, t, src1);
a->cond = cond;
- b->cond = cond ^ 1;
+ b->cond = qpu_cond_complement(cond);
return t;
}
qir_reg(QFILE_LOAD_IMM, val), c->undef));
}
+#define qir_for_each_block(block, c) \
+ list_for_each_entry(struct qblock, block, &c->blocks, link)
+
+#define qir_for_each_block_rev(block, c) \
+ list_for_each_entry_rev(struct qblock, block, &c->blocks, link)
+
+/* Loop over the non-NULL members of the successors array. */
+#define qir_for_each_successor(succ, block) \
+ for (struct qblock *succ = block->successors[0]; \
+ succ != NULL; \
+ succ = (succ == block->successors[1] ? NULL : \
+ block->successors[1]))
+
+#define qir_for_each_inst(inst, block) \
+ list_for_each_entry(struct qinst, inst, &block->instructions, link)
+
+#define qir_for_each_inst_rev(inst, block) \
+ list_for_each_entry_rev(struct qinst, inst, &block->instructions, link)
+
+#define qir_for_each_inst_safe(inst, block) \
+ list_for_each_entry_safe(struct qinst, inst, &block->instructions, link)
+
+#define qir_for_each_inst_inorder(inst, c) \
+ qir_for_each_block(_block, c) \
+ qir_for_each_inst(inst, _block)
+
#endif /* VC4_QIR_H */