소스 검색

freedreno/ir3: use instr flag to mark unused instructions

Rather than magic depth value, which won't be available in later stages.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
tags/11.2-branchpoint
Rob Clark 10 년 전
부모
커밋
2181f2cd58

+ 1
- 4
src/gallium/drivers/freedreno/ir3/ir3.h 파일 보기

@@ -177,6 +177,7 @@ struct ir3_instruction {
* before register assignment is done:
*/
IR3_INSTR_MARK = 0x1000,
IR3_INSTR_UNUSED= 0x2000,
} flags;
int repeat;
#ifdef DEBUG
@@ -243,11 +244,7 @@ struct ir3_instruction {
* result of moving a const to a reg would have a low cost, so to
* it could make sense to duplicate the instruction at various
* points where the result is needed to reduce register footprint.
*
* DEPTH_UNUSED used to mark unused instructions after depth
* calculation pass.
*/
#define DEPTH_UNUSED ~0
unsigned depth;
/* When we get to the RA stage, we no longer need depth, but
* we do need instruction's position/name:

+ 3
- 3
src/gallium/drivers/freedreno/ir3/ir3_depth.c 파일 보기

@@ -139,7 +139,7 @@ remove_unused_by_block(struct ir3_block *block)
/* mark it, in case it is input, so we can
* remove unused inputs:
*/
instr->depth = DEPTH_UNUSED;
instr->flags |= IR3_INSTR_UNUSED;
/* and remove from instruction list: */
list_delinit(&instr->node);
}
@@ -175,14 +175,14 @@ ir3_depth(struct ir3 *ir)
*/
for (i = 0; i < ir->indirects_count; i++) {
struct ir3_instruction *instr = ir->indirects[i];
if (instr->depth == DEPTH_UNUSED)
if (instr->flags & IR3_INSTR_UNUSED)
ir->indirects[i] = NULL;
}

/* cleanup unused inputs: */
for (i = 0; i < ir->ninputs; i++) {
struct ir3_instruction *in = ir->inputs[i];
if (in && (in->depth == DEPTH_UNUSED))
if (in && (in->flags & IR3_INSTR_UNUSED))
ir->inputs[i] = NULL;
}
}

+ 19
- 6
src/gallium/drivers/freedreno/ir3/ir3_ra.c 파일 보기

@@ -314,6 +314,14 @@ writes_gpr(struct ir3_instruction *instr)
return is_temp(instr->regs[0]);
}

static bool
instr_before(struct ir3_instruction *a, struct ir3_instruction *b)
{
if (a->flags & IR3_INSTR_UNUSED)
return false;
return (a->ip < b->ip);
}

static struct ir3_instruction *
get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
int *sz, int *off)
@@ -348,7 +356,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,

dd = get_definer(ctx, src->instr, &dsz, &doff);

if ((!d) || (dd->ip < d->ip)) {
if ((!d) || instr_before(dd, d)) {
d = dd;
*sz = dsz;
*off = doff - n;
@@ -369,9 +377,14 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
*/
int cnt = 0;

d = f;
/* need to skip over unused in the group: */
while (f && (f->flags & IR3_INSTR_UNUSED)) {
f = f->cp.right;
cnt++;
}

while (f) {
if (f->ip < d->ip)
if ((!d) || instr_before(f, d))
d = f;
if (f == instr)
*off = cnt;
@@ -414,7 +427,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
*sz = MAX2(*sz, dsz);
*off = doff;

if (dd->ip < d->ip) {
if (instr_before(dd, d)) {
d = dd;
}
}
@@ -432,7 +445,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
foreach_src(src, d) {
if (!src->instr)
continue;
if (src->instr->ip < dd->ip)
if (instr_before(src->instr, dd))
dd = src->instr;
}

@@ -446,7 +459,7 @@ get_definer(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr,
dd = get_definer(ctx, d->regs[1]->instr, &dsz, &doff);

/* by definition, should come before: */
debug_assert(dd->ip < d->ip);
debug_assert(instr_before(dd, d));

*sz = MAX2(*sz, dsz);


+ 1
- 1
src/gallium/drivers/freedreno/ir3/ir3_sched.c 파일 보기

@@ -246,7 +246,7 @@ instr_eligibility(struct ir3_sched_ctx *ctx, struct ir3_sched_notes *notes,

for (unsigned i = 0; i < ir->baryfs_count; i++) {
struct ir3_instruction *baryf = ir->baryfs[i];
if (baryf->depth == DEPTH_UNUSED)
if (baryf->flags & IR3_INSTR_UNUSED)
continue;
if (!is_scheduled(baryf)) {
notes->blocked_kill = true;

Loading…
취소
저장