From 987aea14000ce6524b12d72488dc1275d5e8a991 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 5 Mar 2020 17:03:53 -0500 Subject: [PATCH] pan/bi: Handle loops when ingesting CFG Not very useful without also handling breaks and continues, of course. We use the strategy from v3d (vir_to_nir) instead of Midgard's, since the latter is mildly insane. I mean, it passes deqp but... Signed-off-by: Alyssa Rosenzweig Part-of: --- src/panfrost/bifrost/bifrost_compile.c | 32 ++++++++++++++++++++++++-- src/panfrost/bifrost/compiler.h | 3 +++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c index 361c8fcdaa2..01f20c44d55 100644 --- a/src/panfrost/bifrost/bifrost_compile.c +++ b/src/panfrost/bifrost/bifrost_compile.c @@ -174,6 +174,36 @@ emit_if(bi_context *ctx, nir_if *nif) bi_block_add_successor(end_else_block, ctx->after_block); /* fallthrough */ } +static void +emit_loop(bi_context *ctx, nir_loop *nloop) +{ + /* Remember where we are */ + bi_block *start_block = ctx->current_block; + + bi_block *saved_break = ctx->break_block; + bi_block *saved_continue = ctx->continue_block; + + ctx->continue_block = create_empty_block(ctx); + ctx->break_block = create_empty_block(ctx); + ctx->after_block = ctx->continue_block; + + /* Emit the body itself */ + emit_cf_list(ctx, &nloop->body); + + /* 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); + + ctx->after_block = ctx->break_block; + + /* Pop off */ + ctx->break_block = saved_break; + ctx->continue_block = saved_continue; + ++ctx->loop_count; +} + static bi_block * emit_cf_list(bi_context *ctx, struct exec_list *list) { @@ -194,11 +224,9 @@ emit_cf_list(bi_context *ctx, struct exec_list *list) emit_if(ctx, nir_cf_node_as_if(node)); break; -#if 0 case nir_cf_node_loop: emit_loop(ctx, nir_cf_node_as_loop(node)); break; -#endif default: unreachable("Unknown control flow"); diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h index d57bdc2c9cc..c63f175f542 100644 --- a/src/panfrost/bifrost/compiler.h +++ b/src/panfrost/bifrost/compiler.h @@ -325,9 +325,12 @@ typedef struct { bi_block *current_block; unsigned block_name_count; bi_block *after_block; + bi_block *break_block; + bi_block *continue_block; /* Stats for shader-db */ unsigned instruction_count; + unsigned loop_count; } bi_context; static inline bi_instruction * -- 2.30.2