diff options
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_dump.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/ir3/ir3_ra.c | 43 |
3 files changed, 61 insertions, 17 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index 06bad6e26fc..98715a98c0b 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -27,6 +27,8 @@ #include <stdint.h> #include <stdbool.h> +#include "util/u_debug.h" + #include "instr-a3xx.h" #include "disasm.h" /* TODO move 'enum shader_t' somewhere else.. */ @@ -283,7 +285,7 @@ static inline bool ir3_instr_check_mark(struct ir3_instruction *instr) { if (instr->flags & IR3_INSTR_MARK) return true; /* already visited */ - instr->flags ^= IR3_INSTR_MARK; + instr->flags |= IR3_INSTR_MARK; return false; } @@ -405,7 +407,7 @@ static inline bool writes_pred(struct ir3_instruction *instr) static inline bool reg_gpr(struct ir3_register *r) { - if (r->flags & (IR3_REG_CONST | IR3_REG_IMMED | IR3_REG_RELATIV | IR3_REG_SSA | IR3_REG_ADDR)) + if (r->flags & (IR3_REG_CONST | IR3_REG_IMMED | IR3_REG_RELATIV | IR3_REG_ADDR)) return false; if ((reg_num(r) == REG_A0) || (reg_num(r) == REG_P0)) return false; @@ -455,7 +457,7 @@ typedef uint8_t regmask_t[2 * MAX_REG / 8]; static inline unsigned regmask_idx(struct ir3_register *reg) { unsigned num = reg->num; - assert(num < MAX_REG); + debug_assert(num < MAX_REG); if (reg->flags & IR3_REG_HALF) num += MAX_REG; return num; diff --git a/src/gallium/drivers/freedreno/ir3/ir3_dump.c b/src/gallium/drivers/freedreno/ir3/ir3_dump.c index 61336284412..136b57f068f 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_dump.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_dump.c @@ -108,7 +108,7 @@ static void dump_instr_name(struct ir3_dump_ctx *ctx, } static void dump_reg_name(struct ir3_dump_ctx *ctx, - struct ir3_register *reg) + struct ir3_register *reg, bool followssa) { if ((reg->flags & IR3_REG_ABS) && (reg->flags & IR3_REG_NEGATE)) fprintf(ctx->f, "(absneg)"); @@ -121,9 +121,12 @@ static void dump_reg_name(struct ir3_dump_ctx *ctx, fprintf(ctx->f, "imm[%f,%d,0x%x]", reg->fim_val, reg->iim_val, reg->iim_val); } else if (reg->flags & IR3_REG_SSA) { if (ctx->verbose) { - fprintf(ctx->f, "_["); - dump_instr_name(ctx, reg->instr); - fprintf(ctx->f, "]"); + fprintf(ctx->f, "_"); + if (followssa) { + fprintf(ctx->f, "["); + dump_instr_name(ctx, reg->instr); + fprintf(ctx->f, "]"); + } } } else { if (reg->flags & IR3_REG_HALF) @@ -282,7 +285,7 @@ static void ir3_instr_dump(struct ir3_dump_ctx *ctx, if (reg->flags & IR3_REG_SSA) fprintf(ctx->f, "<src%u> ", (i - 1)); - dump_reg_name(ctx, reg); + dump_reg_name(ctx, reg, true); } fprintf(ctx->f, "}\"];\n"); @@ -406,14 +409,19 @@ ir3_dump_instr_single(struct ir3_instruction *instr) for (i = 0; i < instr->regs_count; i++) { struct ir3_register *reg = instr->regs[i]; printf(i ? ", " : " "); - dump_reg_name(&ctx, reg); + dump_reg_name(&ctx, reg, !!i); } + + if (is_meta(instr) && (instr->opc == OPC_META_FO)) + printf(", off=%d", instr->fo.off); + printf("\n"); } void ir3_dump_instr_list(struct ir3_instruction *instr) { + struct ir3_block *block = instr->block; unsigned n = 0; while (instr) { @@ -423,4 +431,11 @@ ir3_dump_instr_list(struct ir3_instruction *instr) instr = instr->next; } printf("%u instructions\n", n); + + for (n = 0; n < block->noutputs; n++) { + if (!block->outputs[n]) + continue; + printf("out%d: ", n); + ir3_dump_instr_single(block->outputs[n]); + } } diff --git a/src/gallium/drivers/freedreno/ir3/ir3_ra.c b/src/gallium/drivers/freedreno/ir3/ir3_ra.c index aa8ad513e04..b0ce6c523c8 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_ra.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_ra.c @@ -62,6 +62,22 @@ struct ir3_ra_ctx { bool error; }; +#define ra_debug 0 + +#define ra_dump_list(msg, n) do { \ + if (ra_debug) { \ + debug_printf("-- " msg); \ + ir3_dump_instr_list(n); \ + } \ + } while (0) + +#define ra_dump_instr(msg, n) do { \ + if (ra_debug) { \ + debug_printf(">> " msg); \ + ir3_dump_instr_single(n); \ + } \ + } while (0) + /* sorta ugly way to retrofit half-precision support.. rather than * passing extra param around, just OR in a high bit. All the low * value arithmetic (ie. +/- offset within a contiguous vec4, etc) @@ -92,7 +108,8 @@ static struct ir3_ra_assignment ra_calc(struct ir3_instruction *instr); /* check that the register exists, is a GPR and is not special (a0/p0) */ static struct ir3_register * reg_check(struct ir3_instruction *instr, unsigned n) { - if ((n < instr->regs_count) && reg_gpr(instr->regs[n])) + if ((n < instr->regs_count) && reg_gpr(instr->regs[n]) && + !(instr->regs[n]->flags & IR3_REG_SSA)) return instr->regs[n]; return NULL; } @@ -444,9 +461,6 @@ static void ra_assign_reg(struct ir3_visitor *v, { struct ra_assign_visitor *a = ra_assign_visitor(v); - if (is_flow(instr) && (instr->opc == OPC_KILL)) - return; - reg->flags &= ~IR3_REG_SSA; reg->num = a->num & ~REG_HALF; @@ -582,7 +596,8 @@ static void ir3_instr_ra(struct ir3_ra_ctx *ctx, num = regid(REG_A0, 0) | REG_HALF; } else { /* predicate register (p0).. etc */ - return; + num = regid(REG_P0, 0); + debug_assert(dst->num == num); } ra_assign(ctx, instr, num); @@ -735,6 +750,8 @@ static int block_ra(struct ir3_ra_ctx *ctx, struct ir3_block *block) { struct ir3_instruction *n; + ra_dump_list("before:\n", block->head); + if (!block->parent) { unsigned i, j; int base, off = output_base(ctx); @@ -765,14 +782,16 @@ static int block_ra(struct ir3_ra_ctx *ctx, struct ir3_block *block) } } + ra_dump_list("after:\n", block->head); + /* then loop over instruction list and assign registers: */ - n = block->head; - while (n) { + for (n = block->head; n; n = n->next) { + ra_dump_instr("ASSIGN: ", n); ir3_instr_ra(ctx, n); if (ctx->error) return -1; - n = n->next; + ra_dump_list("-------", block->head); } legalize(ctx, block); @@ -784,6 +803,7 @@ int ir3_block_ra(struct ir3_block *block, enum shader_t type, bool half_precision, bool frag_coord, bool frag_face, bool *has_samp, int *max_bary) { + struct ir3_instruction *n; struct ir3_ra_ctx ctx = { .block = block, .type = type, @@ -794,6 +814,13 @@ int ir3_block_ra(struct ir3_block *block, enum shader_t type, }; int ret; + /* mark dst registers w/ SSA flag so we can see which + * have been assigned so far: + */ + for (n = block->head; n; n = n->next) + if (n->regs_count > 0) + n->regs[0]->flags |= IR3_REG_SSA; + ir3_clear_mark(block->shader); ret = block_ra(&ctx, block); *has_samp = ctx.has_samp; |