Mesa (master): broadcom/vc5: Add cursors to the compiler infrastructure, like NIR's.
Eric Anholt
anholt at kemper.freedesktop.org
Mon Mar 19 23:45:03 UTC 2018
Module: Mesa
Branch: master
Commit: d721348dcdb3658572c5952563d1f4d1ca0321af
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=d721348dcdb3658572c5952563d1f4d1ca0321af
Author: Eric Anholt <eric at anholt.net>
Date: Tue Mar 13 15:41:16 2018 -0700
broadcom/vc5: Add cursors to the compiler infrastructure, like NIR's.
This will let me do lowering late in compilation using the same
instruction builder as we use in nir_to_vir.
---
src/broadcom/compiler/nir_to_vir.c | 9 +++-----
src/broadcom/compiler/v3d_compiler.h | 43 ++++++++++++++++++++++++++++++++++++
src/broadcom/compiler/vir.c | 29 ++++++++++++++++++++++--
3 files changed, 73 insertions(+), 8 deletions(-)
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c
index 61486870dc..c1ba1e3049 100644
--- a/src/broadcom/compiler/nir_to_vir.c
+++ b/src/broadcom/compiler/nir_to_vir.c
@@ -198,14 +198,11 @@ ntq_store_dest(struct v3d_compile *c, nir_dest *dest, int chan,
if (c->execute.file != QFILE_NULL) {
last_inst->dst.index = qregs[chan].index;
- /* Set the flags to the current exec mask. To insert
- * the flags push, we temporarily remove our SSA
- * instruction.
+ /* Set the flags to the current exec mask.
*/
- list_del(&last_inst->link);
+ c->cursor = vir_before_inst(last_inst);
vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
- list_addtail(&last_inst->link,
- &c->cur_block->instructions);
+ c->cursor = vir_after_inst(last_inst);
vir_set_cond(last_inst, V3D_QPU_COND_IFA);
last_inst->cond_is_exec_mask = true;
diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h
index f777cfcd87..fdf1b13197 100644
--- a/src/broadcom/compiler/v3d_compiler.h
+++ b/src/broadcom/compiler/v3d_compiler.h
@@ -384,6 +384,48 @@ struct qblock {
/** @} */
};
+/** Which util/list.h add mode we should use when inserting an instruction. */
+enum vir_cursor_mode {
+ vir_cursor_add,
+ vir_cursor_addtail,
+};
+
+/**
+ * Tracking structure for where new instructions should be inserted. Create
+ * with one of the vir_after_inst()-style helper functions.
+ *
+ * This does not protect against removal of the block or instruction, so we
+ * have an assert in instruction removal to try to catch it.
+ */
+struct vir_cursor {
+ enum vir_cursor_mode mode;
+ struct list_head *link;
+};
+
+static inline struct vir_cursor
+vir_before_inst(struct qinst *inst)
+{
+ return (struct vir_cursor){ vir_cursor_addtail, &inst->link };
+}
+
+static inline struct vir_cursor
+vir_after_inst(struct qinst *inst)
+{
+ return (struct vir_cursor){ vir_cursor_add, &inst->link };
+}
+
+static inline struct vir_cursor
+vir_before_block(struct qblock *block)
+{
+ return (struct vir_cursor){ vir_cursor_add, &block->instructions };
+}
+
+static inline struct vir_cursor
+vir_after_block(struct qblock *block)
+{
+ return (struct vir_cursor){ vir_cursor_addtail, &block->instructions };
+}
+
/**
* Compiler state saved across compiler invocations, for any expensive global
* setup.
@@ -500,6 +542,7 @@ struct v3d_compile {
struct qreg undef;
uint32_t num_temps;
+ struct vir_cursor cursor;
struct list_head blocks;
int next_block_index;
struct qblock *cur_block;
diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c
index 7ea431036e..0b2bbf0e79 100644
--- a/src/broadcom/compiler/vir.c
+++ b/src/broadcom/compiler/vir.c
@@ -418,7 +418,16 @@ vir_branch_inst(enum v3d_qpu_branch_cond cond, struct qreg src)
static void
vir_emit(struct v3d_compile *c, struct qinst *inst)
{
- list_addtail(&inst->link, &c->cur_block->instructions);
+ switch (c->cursor.mode) {
+ case vir_cursor_add:
+ list_add(&inst->link, c->cursor.link);
+ break;
+ case vir_cursor_addtail:
+ list_addtail(&inst->link, c->cursor.link);
+ break;
+ }
+
+ c->cursor = vir_after_inst(inst);
}
/* Updates inst to write to a new temporary, emits it, and notes the def. */
@@ -468,6 +477,7 @@ void
vir_set_emit_block(struct v3d_compile *c, struct qblock *block)
{
c->cur_block = block;
+ c->cursor = vir_after_block(block);
list_addtail(&block->link, &c->blocks);
}
@@ -791,6 +801,8 @@ vir_remove_instruction(struct v3d_compile *c, struct qinst *qinst)
if (qinst->dst.file == QFILE_TEMP)
c->defs[qinst->dst.index] = NULL;
+ assert(&qinst->link != c->cursor.link);
+
list_del(&qinst->link);
free(qinst);
}
@@ -818,6 +830,10 @@ vir_follow_movs(struct v3d_compile *c, struct qreg reg)
void
vir_compile_destroy(struct v3d_compile *c)
{
+ /* Defuse the assert that we aren't removing the cursor's instruction.
+ */
+ c->cursor.link = NULL;
+
vir_for_each_block(block, c) {
while (!list_empty(&block->instructions)) {
struct qinst *qinst =
@@ -867,9 +883,18 @@ vir_PF(struct v3d_compile *c, struct qreg src, enum v3d_qpu_pf pf)
{
struct qinst *last_inst = NULL;
- if (!list_empty(&c->cur_block->instructions))
+ if (!list_empty(&c->cur_block->instructions)) {
last_inst = (struct qinst *)c->cur_block->instructions.prev;
+ /* Can't stuff the PF into the last last inst if our cursor
+ * isn't pointing after it.
+ */
+ struct vir_cursor after_inst = vir_after_inst(last_inst);
+ if (c->cursor.mode != after_inst.mode ||
+ c->cursor.link != after_inst.link)
+ last_inst = NULL;
+ }
+
if (src.file != QFILE_TEMP ||
!c->defs[src.index] ||
last_inst != c->defs[src.index]) {
More information about the mesa-commit
mailing list