From 9b75f410c44053a4fc84715dec473dadedf7aa14 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 11 Mar 2020 14:35:38 -0400 Subject: [PATCH] panfrost: Sync Midgard/Bifrost control flow We can move e v e n more code to be shared and let bi_block inherit from pan_block, which will allow us to use the shared data flow analysis. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/bifrost/bi_print.c | 18 ++++----- src/panfrost/bifrost/bi_schedule.c | 10 +++-- src/panfrost/bifrost/bifrost_compile.c | 51 +++++++------------------- src/panfrost/bifrost/compiler.h | 42 +++++++-------------- src/panfrost/midgard/compiler.h | 8 ---- src/panfrost/midgard/midgard_compile.c | 19 ---------- src/panfrost/midgard/midgard_print.c | 8 ++-- src/panfrost/util/pan_ir.c | 22 +++++++++++ src/panfrost/util/pan_ir.h | 4 +- src/panfrost/util/pan_liveness.c | 2 +- 10 files changed, 70 insertions(+), 114 deletions(-) diff --git a/src/panfrost/bifrost/bi_print.c b/src/panfrost/bifrost/bi_print.c index e258333649d..389d4fff409 100644 --- a/src/panfrost/bifrost/bi_print.c +++ b/src/panfrost/bifrost/bi_print.c @@ -360,7 +360,7 @@ bi_print_instruction(bi_instruction *ins, FILE *fp) if (ins->type == BI_BRANCH) { if (ins->branch.target) - fprintf(fp, "-> block%u", ins->branch.target->name); + fprintf(fp, "-> block%u", ins->branch.target->base.name); else fprintf(fp, "-> blockhole"); } @@ -428,7 +428,7 @@ bi_print_clause(bi_clause *clause, FILE *fp) void bi_print_block(bi_block *block, FILE *fp) { - fprintf(fp, "block%u {\n", block->name); + fprintf(fp, "block%u {\n", block->base.name); if (block->scheduled) { bi_foreach_clause_in_block(block, clause) @@ -440,20 +440,18 @@ bi_print_block(bi_block *block, FILE *fp) fprintf(fp, "}"); - if (block->successors[0]) { + if (block->base.successors[0]) { fprintf(fp, " -> "); - for (unsigned i = 0; i < ARRAY_SIZE(block->successors); ++i) { - if (block->successors[i]) - fprintf(fp, "block%u ", block->successors[i]->name); - } + pan_foreach_successor((&block->base), succ) + fprintf(fp, "block%u ", succ->name); } - if (block->predecessors->entries) { + if (block->base.predecessors->entries) { fprintf(fp, " from"); bi_foreach_predecessor(block, pred) - fprintf(fp, " block%u", pred->name); + fprintf(fp, " block%u", pred->base.name); } fprintf(fp, "\n\n"); @@ -463,5 +461,5 @@ void bi_print_shader(bi_context *ctx, FILE *fp) { bi_foreach_block(ctx, block) - bi_print_block(block, fp); + bi_print_block((bi_block *) block, fp); } diff --git a/src/panfrost/bifrost/bi_schedule.c b/src/panfrost/bifrost/bi_schedule.c index dc45487f7c8..669b4019d5c 100644 --- a/src/panfrost/bifrost/bi_schedule.c +++ b/src/panfrost/bifrost/bi_schedule.c @@ -40,9 +40,11 @@ bi_schedule(bi_context *ctx) bool is_first = true; bi_foreach_block(ctx, block) { - list_inithead(&block->clauses); + bi_block *bblock = (bi_block *) block; - bi_foreach_instr_in_block(block, ins) { + list_inithead(&bblock->clauses); + + bi_foreach_instr_in_block(bblock, ins) { unsigned props = bi_class_props[ins->type]; bi_clause *u = rzalloc(ctx, bi_clause); @@ -68,9 +70,9 @@ bi_schedule(bi_context *ctx) u->constant_count = 1; u->constants[0] = ins->constant.u64; - list_addtail(&u->link, &block->clauses); + list_addtail(&u->link, &bblock->clauses); } - block->scheduled = true; + bblock->scheduled = true; } } diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 46f9aea5496..6893bfcf5b1 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -39,7 +39,6 @@ static bi_block *emit_cf_list(bi_context *ctx, struct exec_list *list); static bi_instruction *bi_emit_branch(bi_context *ctx); -static void bi_block_add_successor(bi_block *block, bi_block *successor); static void bi_schedule_barrier(bi_context *ctx); static void @@ -58,7 +57,7 @@ emit_jump(bi_context *ctx, nir_jump_instr *instr) unreachable("Unhandled jump type"); } - bi_block_add_successor(ctx->current_block, branch->branch.target); + pan_block_add_successor(&ctx->current_block->base, &branch->branch.target->base); } /* Gets a bytemask for a complete vecN write */ @@ -530,45 +529,23 @@ create_empty_block(bi_context *ctx) { bi_block *blk = rzalloc(ctx, bi_block); - blk->predecessors = _mesa_set_create(blk, + blk->base.predecessors = _mesa_set_create(blk, _mesa_hash_pointer, _mesa_key_pointer_equal); - blk->name = ctx->block_name_count++; + blk->base.name = ctx->block_name_count++; return blk; } -static void -bi_block_add_successor(bi_block *block, bi_block *successor) -{ - assert(block); - assert(successor); - - for (unsigned i = 0; i < ARRAY_SIZE(block->successors); ++i) { - if (block->successors[i]) { - if (block->successors[i] == successor) - return; - else - continue; - } - - block->successors[i] = successor; - _mesa_set_add(successor->predecessors, block); - return; - } - - unreachable("Too many successors"); -} - static void bi_schedule_barrier(bi_context *ctx) { bi_block *temp = ctx->after_block; ctx->after_block = create_empty_block(ctx); - list_addtail(&ctx->after_block->link, &ctx->blocks); - list_inithead(&ctx->after_block->instructions); - bi_block_add_successor(ctx->current_block, ctx->after_block); + list_addtail(&ctx->after_block->base.link, &ctx->blocks); + list_inithead(&ctx->after_block->base.instructions); + pan_block_add_successor(&ctx->current_block->base, &ctx->after_block->base); ctx->current_block = ctx->after_block; ctx->after_block = temp; } @@ -583,8 +560,8 @@ emit_block(bi_context *ctx, nir_block *block) ctx->current_block = create_empty_block(ctx); } - list_addtail(&ctx->current_block->link, &ctx->blocks); - list_inithead(&ctx->current_block->instructions); + list_addtail(&ctx->current_block->base.link, &ctx->blocks); + list_inithead(&ctx->current_block->base.instructions); nir_foreach_instr(instr, block) { emit_instr(ctx, instr); @@ -662,15 +639,15 @@ emit_if(bi_context *ctx, nir_if *nif) } else { then_branch->branch.target = else_block; then_exit->branch.target = ctx->after_block; - bi_block_add_successor(end_then_block, then_exit->branch.target); + pan_block_add_successor(&end_then_block->base, &then_exit->branch.target->base); } /* Wire up the successors */ - bi_block_add_successor(before_block, then_branch->branch.target); /* then_branch */ + pan_block_add_successor(&before_block->base, &then_branch->branch.target->base); /* then_branch */ - bi_block_add_successor(before_block, then_block); /* fallthrough */ - bi_block_add_successor(end_else_block, ctx->after_block); /* fallthrough */ + pan_block_add_successor(&before_block->base, &then_block->base); /* fallthrough */ + pan_block_add_successor(&end_else_block->base, &ctx->after_block->base); /* fallthrough */ } static void @@ -692,8 +669,8 @@ emit_loop(bi_context *ctx, nir_loop *nloop) /* Branch back to loop back */ bi_instruction *br_back = bi_emit_branch(ctx); br_back->branch.target = ctx->continue_block; - bi_block_add_successor(start_block, ctx->continue_block); - bi_block_add_successor(ctx->current_block, ctx->continue_block); + pan_block_add_successor(&start_block->base, &ctx->continue_block->base); + pan_block_add_successor(&ctx->current_block->base, &ctx->continue_block->base); ctx->after_block = ctx->break_block; diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index 49ecb19302b..1c01b2d989b 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -308,17 +308,11 @@ typedef struct { } bi_clause; typedef struct bi_block { - struct list_head link; /* must be first */ - unsigned name; /* Just for pretty-printing */ + pan_block base; /* must be first */ /* If true, uses clauses; if false, uses instructions */ bool scheduled; - struct list_head instructions; /* pre-schedule, list of bi_instructions */ struct list_head clauses; /* list of bi_clause */ - - /* Control flow graph */ - struct set *predecessors; - struct bi_block *successors[2]; } bi_block; typedef struct { @@ -350,7 +344,7 @@ bi_emit(bi_context *ctx, bi_instruction ins) { bi_instruction *u = rzalloc(ctx, bi_instruction); memcpy(u, &ins, sizeof(ins)); - list_addtail(&u->link, &ctx->current_block->instructions); + list_addtail(&u->link, &ctx->current_block->base.instructions); return u; } @@ -427,57 +421,49 @@ bir_dest_index(nir_dest *dst) /* Iterators for Bifrost IR */ #define bi_foreach_block(ctx, v) \ - list_for_each_entry(bi_block, v, &ctx->blocks, link) + list_for_each_entry(pan_block, v, &ctx->blocks, link) #define bi_foreach_block_from(ctx, from, v) \ - list_for_each_entry_from(bi_block, v, from, &ctx->blocks, link) + list_for_each_entry_from(pan_block, v, from, &ctx->blocks, link) #define bi_foreach_instr_in_block(block, v) \ - list_for_each_entry(bi_instruction, v, &block->instructions, link) + list_for_each_entry(bi_instruction, v, &block->base.instructions, link) #define bi_foreach_instr_in_block_rev(block, v) \ - list_for_each_entry_rev(bi_instruction, v, &block->instructions, link) + list_for_each_entry_rev(bi_instruction, v, &block->base.instructions, link) #define bi_foreach_instr_in_block_safe(block, v) \ - list_for_each_entry_safe(bi_instruction, v, &block->instructions, link) + list_for_each_entry_safe(bi_instruction, v, &block->base.instructions, link) #define bi_foreach_instr_in_block_safe_rev(block, v) \ - list_for_each_entry_safe_rev(bi_instruction, v, &block->instructions, link) + list_for_each_entry_safe_rev(bi_instruction, v, &block->base.instructions, link) #define bi_foreach_instr_in_block_from(block, v, from) \ - list_for_each_entry_from(bi_instruction, v, from, &block->instructions, link) + list_for_each_entry_from(bi_instruction, v, from, &block->base.instructions, link) #define bi_foreach_instr_in_block_from_rev(block, v, from) \ - list_for_each_entry_from_rev(bi_instruction, v, from, &block->instructions, link) + list_for_each_entry_from_rev(bi_instruction, v, from, &block->base.instructions, link) #define bi_foreach_clause_in_block(block, v) \ list_for_each_entry(bi_clause, v, &block->clauses, link) #define bi_foreach_instr_global(ctx, v) \ bi_foreach_block(ctx, v_block) \ - bi_foreach_instr_in_block(v_block, v) + bi_foreach_instr_in_block((pan_block *) v_block, v) #define bi_foreach_instr_global_safe(ctx, v) \ bi_foreach_block(ctx, v_block) \ - bi_foreach_instr_in_block_safe(v_block, v) - -#define bi_foreach_successor(blk, v) \ - bi_block *v; \ - bi_block **_v; \ - for (_v = &blk->successors[0], \ - v = *_v; \ - v != NULL && _v < &blk->successors[2]; \ - _v++, v = *_v) \ + bi_foreach_instr_in_block_safe((pan_block *) v_block, v) /* Based on set_foreach, expanded with automatic type casts */ #define bi_foreach_predecessor(blk, v) \ struct set_entry *_entry_##v; \ bi_block *v; \ - for (_entry_##v = _mesa_set_next_entry(blk->predecessors, NULL), \ + for (_entry_##v = _mesa_set_next_entry(blk->base.predecessors, NULL), \ v = (bi_block *) (_entry_##v ? _entry_##v->key : NULL); \ _entry_##v != NULL; \ - _entry_##v = _mesa_set_next_entry(blk->predecessors, _entry_##v), \ + _entry_##v = _mesa_set_next_entry(blk->base.predecessors, _entry_##v), \ v = (bi_block *) (_entry_##v ? _entry_##v->key : NULL)) #define bi_foreach_src(ins, v) \ diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index 34a53cd1ac3..aa0c193d99d 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -388,14 +388,6 @@ mir_next_op(struct midgard_instruction *ins) mir_foreach_block(ctx, v_block) \ mir_foreach_instr_in_block_safe(((midgard_block *) v_block), v) -#define mir_foreach_successor(blk, v) \ - struct midgard_block *v; \ - struct midgard_block **_v; \ - for (_v = &blk->base.successors[0], \ - v = *_v; \ - v != NULL && _v < &blk->base.successors[2]; \ - _v++, v = *_v) \ - /* Based on set_foreach, expanded with automatic type casts */ #define mir_foreach_predecessor(blk, v) \ diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 9ff11a003cf..5d3bcba15ea 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -83,25 +83,6 @@ create_empty_block(compiler_context *ctx) return blk; } -static void -pan_block_add_successor(pan_block *block, pan_block *successor) -{ - assert(block); - assert(successor); - - /* Deduplicate */ - for (unsigned i = 0; i < block->nr_successors; ++i) { - if ((pan_block *) block->successors[i] == successor) - return; - } - - block->successors[block->nr_successors++] = successor; - assert(block->nr_successors <= ARRAY_SIZE(block->successors)); - - /* Note the predecessor in the other direction */ - _mesa_set_add(successor->predecessors, block); -} - static void schedule_barrier(compiler_context *ctx) { diff --git a/src/panfrost/midgard/midgard_print.c b/src/panfrost/midgard/midgard_print.c index e5e3e16c6c7..67104f3c7aa 100644 --- a/src/panfrost/midgard/midgard_print.c +++ b/src/panfrost/midgard/midgard_print.c @@ -394,12 +394,10 @@ mir_print_block(midgard_block *block) printf("}"); - if (block->base.nr_successors) { + if (block->base.successors[0]) { printf(" -> "); - for (unsigned i = 0; i < block->base.nr_successors; ++i) { - printf("block%u%s", block->base.successors[i]->name, - (i + 1) != block->base.nr_successors ? ", " : ""); - } + pan_foreach_successor((&block->base), succ) + printf(" block%u ", succ->name); } printf(" from { "); diff --git a/src/panfrost/util/pan_ir.c b/src/panfrost/util/pan_ir.c index 95f8e6b5326..fbe8f66bff4 100644 --- a/src/panfrost/util/pan_ir.c +++ b/src/panfrost/util/pan_ir.c @@ -70,3 +70,25 @@ pan_to_bytemask(unsigned bytes, unsigned mask) unreachable("Invalid register mode"); } } + +void +pan_block_add_successor(pan_block *block, pan_block *successor) +{ + assert(block); + assert(successor); + + for (unsigned i = 0; i < ARRAY_SIZE(block->successors); ++i) { + if (block->successors[i]) { + if (block->successors[i] == successor) + return; + else + continue; + } + + block->successors[i] = successor; + _mesa_set_add(successor->predecessors, block); + return; + } + + unreachable("Too many successors"); +} diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h index 6b132228ddd..be02dc7576e 100644 --- a/src/panfrost/util/pan_ir.h +++ b/src/panfrost/util/pan_ir.h @@ -128,8 +128,6 @@ typedef struct pan_block { /* Control flow graph */ struct pan_block *successors[2]; - unsigned nr_successors; - struct set *predecessors; /* In liveness analysis, these are live masks (per-component) for @@ -179,4 +177,6 @@ void pan_free_liveness(struct list_head *blocks); uint16_t pan_to_bytemask(unsigned bytes, unsigned mask); +void pan_block_add_successor(pan_block *block, pan_block *successor); + #endif diff --git a/src/panfrost/util/pan_liveness.c b/src/panfrost/util/pan_liveness.c index 48ec71b253a..a46a11d9d3c 100644 --- a/src/panfrost/util/pan_liveness.c +++ b/src/panfrost/util/pan_liveness.c @@ -108,7 +108,7 @@ static inline pan_block * pan_exit_block(struct list_head *blocks) { pan_block *last = list_last_entry(blocks, pan_block, link); - assert(last->nr_successors == 0); + assert(!last->successors[0] && !last->successors[1]); return last; } -- 2.30.2