From 95d4a956c08acafe0167ff8ba4dcd9b912962a70 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 10 Apr 2020 16:10:14 -0700 Subject: [PATCH] freedreno/ir3: CSE the up/downconversion of SEL's cond's size. Not many programs hit this, but if you were, say, selecting between vec4s, you'd convert the cond 4 times. instructions in affected programs: 2957 -> 2717 (-8.12%) nops in affected programs: 989 -> 899 (-9.10%) non-nops in affected programs: 1968 -> 1818 (-7.62%) dwords in affected programs: 3232 -> 2752 (-14.85%) last-baryf in affected programs: 102 -> 90 (-11.76%) full in affected programs: 5 -> 4 (-20.00%) sstall in affected programs: 329 -> 329 (0.00%) (ss) in affected programs: 86 -> 105 (22.09%) (sy) in affected programs: 14 -> 12 (-14.29%) Part-of: --- src/freedreno/ir3/ir3_compiler_nir.c | 25 ++++++++++++++++++------- src/freedreno/ir3/ir3_context.c | 2 ++ src/freedreno/ir3/ir3_context.h | 2 ++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index bc0513f413e..752adc8f1b7 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -642,13 +642,22 @@ emit_alu(struct ir3_context *ctx, nir_alu_instr *alu) } compile_assert(ctx, bs[1] == bs[2]); - /* Make sure the boolean condition has the same bit size as the other - * two arguments, adding a conversion if necessary. - */ - if (bs[1] < bs[0]) - cond = ir3_COV(b, cond, TYPE_U32, TYPE_U16); - else if (bs[1] > bs[0]) - cond = ir3_COV(b, cond, TYPE_U16, TYPE_U32); + if (bs[1] != bs[0]) { + struct hash_entry *prev_entry = + _mesa_hash_table_search(ctx->sel_cond_conversions, src[0]); + if (prev_entry) { + cond = prev_entry->data; + } else { + /* Make sure the boolean condition has the same bit size as the other + * two arguments, adding a conversion if necessary. + */ + if (bs[1] < bs[0]) + cond = ir3_COV(b, cond, TYPE_U32, TYPE_U16); + else if (bs[1] > bs[0]) + cond = ir3_COV(b, cond, TYPE_U16, TYPE_U32); + _mesa_hash_table_insert(ctx->sel_cond_conversions, src[0], cond); + } + } if (bs[1] > 16) dst[0] = ir3_SEL_B32(b, src[1], 0, cond, 0, src[2], 0); @@ -2687,6 +2696,8 @@ emit_block(struct ir3_context *ctx, nir_block *nblock) if (ctx->error) return; } + + _mesa_hash_table_clear(ctx->sel_cond_conversions, NULL); } static void emit_cf_list(struct ir3_context *ctx, struct exec_list *list); diff --git a/src/freedreno/ir3/ir3_context.c b/src/freedreno/ir3/ir3_context.c index 6050f3f69d3..f4511ec77da 100644 --- a/src/freedreno/ir3/ir3_context.c +++ b/src/freedreno/ir3/ir3_context.c @@ -63,6 +63,8 @@ ir3_context_init(struct ir3_compiler *compiler, _mesa_hash_pointer, _mesa_key_pointer_equal); ctx->block_ht = _mesa_hash_table_create(ctx, _mesa_hash_pointer, _mesa_key_pointer_equal); + ctx->sel_cond_conversions = _mesa_hash_table_create(ctx, + _mesa_hash_pointer, _mesa_key_pointer_equal); /* TODO: maybe generate some sort of bitmask of what key * lowers vs what shader has (ie. no need to lower diff --git a/src/freedreno/ir3/ir3_context.h b/src/freedreno/ir3/ir3_context.h index a109a9a13be..d1de1a67a26 100644 --- a/src/freedreno/ir3/ir3_context.h +++ b/src/freedreno/ir3/ir3_context.h @@ -127,6 +127,8 @@ struct ir3_context { */ struct hash_table_u64 *addr1_ht; + struct hash_table *sel_cond_conversions; + /* last dst array, for indirect we need to insert a var-store. */ struct ir3_instruction **last_dst; -- 2.30.2