From 63e5b72da8b1df4bbb0fcf46524d106f51264605 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 7 Jan 2015 11:52:32 -0500 Subject: [PATCH] freedreno/ir3: make reg array dynamic To use fanin's to group registers in an array, we can potentially have a much larger array of registers. Rather than continuing to bump up the array size, just make it dynamically allocated when the instruction is created. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/ir3/ir3.c | 46 ++++++++++++++++--- src/gallium/drivers/freedreno/ir3/ir3.h | 9 ++-- .../drivers/freedreno/ir3/ir3_compiler.c | 4 +- src/gallium/drivers/freedreno/ir3/ir3_sched.c | 4 +- 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/freedreno/ir3/ir3.c b/src/gallium/drivers/freedreno/ir3/ir3.c index 41112460155..095085a0ea9 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.c +++ b/src/gallium/drivers/freedreno/ir3/ir3.c @@ -648,11 +648,27 @@ struct ir3_block * ir3_block_create(struct ir3 *shader, return block; } -struct ir3_instruction * ir3_instr_create(struct ir3_block *block, - int category, opc_t opc) +static struct ir3_instruction *instr_create(struct ir3_block *block, int nreg) +{ + struct ir3_instruction *instr; + unsigned sz = sizeof(*instr) + (nreg * sizeof(instr->regs[0])); + char *ptr = ir3_alloc(block->shader, sz); + + instr = (struct ir3_instruction *)ptr; + ptr += sizeof(*instr); + instr->regs = (struct ir3_register **)ptr; + +#ifdef DEBUG + instr->regs_max = nreg; +#endif + + return instr; +} + +struct ir3_instruction * ir3_instr_create2(struct ir3_block *block, + int category, opc_t opc, int nreg) { - struct ir3_instruction *instr = - ir3_alloc(block->shader, sizeof(struct ir3_instruction)); + struct ir3_instruction *instr = instr_create(block, nreg); instr->block = block; instr->category = category; instr->opc = opc; @@ -660,13 +676,27 @@ struct ir3_instruction * ir3_instr_create(struct ir3_block *block, return instr; } +struct ir3_instruction * ir3_instr_create(struct ir3_block *block, + int category, opc_t opc) +{ + /* NOTE: we could be slightly more clever, at least for non-meta, + * and choose # of regs based on category. + */ + return ir3_instr_create2(block, category, opc, 4); +} + +/* only used by old compiler: */ struct ir3_instruction * ir3_instr_clone(struct ir3_instruction *instr) { - struct ir3_instruction *new_instr = - ir3_alloc(instr->block->shader, sizeof(struct ir3_instruction)); + struct ir3_instruction *new_instr = instr_create(instr->block, + instr->regs_count); + struct ir3_register **regs; unsigned i; + regs = new_instr->regs; *new_instr = *instr; + new_instr->regs = regs; + insert_instr(instr->block->shader, new_instr); /* clone registers: */ @@ -685,7 +715,9 @@ struct ir3_register * ir3_reg_create(struct ir3_instruction *instr, int num, int flags) { struct ir3_register *reg = reg_create(instr->block->shader, num, flags); - assert(instr->regs_count < ARRAY_SIZE(instr->regs)); +#ifdef DEBUG + debug_assert(instr->regs_count < instr->regs_max); +#endif instr->regs[instr->regs_count++] = reg; return reg; } diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h index aaa0ff6efa8..b1fb08fcec5 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3.h +++ b/src/gallium/drivers/freedreno/ir3/ir3.h @@ -106,8 +106,6 @@ struct ir3_register { }; }; -#define IR3_INSTR_SRCS 10 - struct ir3_instruction { struct ir3_block *block; int category; @@ -166,8 +164,11 @@ struct ir3_instruction { IR3_INSTR_MARK = 0x1000, } flags; int repeat; +#ifdef DEBUG + unsigned regs_max; +#endif unsigned regs_count; - struct ir3_register *regs[1 + IR3_INSTR_SRCS]; + struct ir3_register **regs; union { struct { char inv; @@ -320,6 +321,8 @@ struct ir3_block * ir3_block_create(struct ir3 *shader, struct ir3_instruction * ir3_instr_create(struct ir3_block *block, int category, opc_t opc); +struct ir3_instruction * ir3_instr_create2(struct ir3_block *block, + int category, opc_t opc, int nreg); struct ir3_instruction * ir3_instr_clone(struct ir3_instruction *instr); const char *ir3_instr_name(struct ir3_instruction *instr); diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c index 209621bd013..99bad377d53 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler.c @@ -1365,7 +1365,7 @@ trans_samp(const struct instr_translater *t, reg = ir3_reg_create(instr, 0, IR3_REG_SSA); - collect = ir3_instr_create(ctx->block, -1, OPC_META_FI); + collect = ir3_instr_create2(ctx->block, -1, OPC_META_FI, 12); ir3_reg_create(collect, 0, 0); for (i = 0; i < 4; i++) { if (tinf.src_wrmask & (1 << i)) @@ -1403,7 +1403,7 @@ trans_samp(const struct instr_translater *t, reg = ir3_reg_create(instr, 0, IR3_REG_SSA); - collect = ir3_instr_create(ctx->block, -1, OPC_META_FI); + collect = ir3_instr_create2(ctx->block, -1, OPC_META_FI, 5); ir3_reg_create(collect, 0, 0); if (inst->Texture.NumOffsets) { diff --git a/src/gallium/drivers/freedreno/ir3/ir3_sched.c b/src/gallium/drivers/freedreno/ir3/ir3_sched.c index b2ef8111f56..29689dbed7e 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_sched.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_sched.c @@ -211,7 +211,7 @@ static unsigned delay_calc(struct ir3_sched_ctx *ctx, static int trysched(struct ir3_sched_ctx *ctx, struct ir3_instruction *instr) { - struct ir3_instruction *srcs[ARRAY_SIZE(instr->regs) - 1]; + struct ir3_instruction *srcs[64]; struct ir3_instruction *src; unsigned i, delay, nsrcs = 0; @@ -219,6 +219,8 @@ static int trysched(struct ir3_sched_ctx *ctx, if (instr->flags & IR3_INSTR_MARK) return 0; + debug_assert(instr->regs_count < ARRAY_SIZE(srcs)); + /* figure out our src's: */ for (i = 1; i < instr->regs_count; i++) { struct ir3_register *reg = instr->regs[i]; -- 2.30.2