From 367d2e324654930342295e008bd077352477df19 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Apr 2023 14:18:39 +0300 Subject: [PATCH] Avoid CFG reachability check after SCCP SCCP eliminates unreachable BBs before the CFG constraction. So ir_build_cfg() doesn't need to perforem reachability chececk if it runs after SCCP, otherwise it starts call ir_remove_unreachable_blocks() if necessary. User code dont have to call ir_remove_unreachable_blocks() anymore. --- ir.h | 3 +++ ir_cfg.c | 42 +++++++++++++++++++++++++++--------------- ir_main.c | 4 ---- ir_sccp.c | 1 + ir_test.c | 3 --- 5 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ir.h b/ir.h index e863851..407f2b5 100644 --- a/ir.h +++ b/ir.h @@ -483,6 +483,9 @@ void ir_strtab_free(ir_strtab *strtab); #define IR_GEN_NATIVE (1<<21) #define IR_GEN_C (1<<22) +/* Temporary: SCCP */ +#define IR_SCCP_DONE (1<<25) + /* Temporary: Live Ranges */ #define IR_LR_HAVE_VARS (1<<25) #define IR_LR_HAVE_DESSA_MOVES (1<<26) diff --git a/ir_cfg.c b/ir_cfg.c index 759057e..b71c1be 100644 --- a/ir_cfg.c +++ b/ir_cfg.c @@ -101,6 +101,7 @@ int ir_build_cfg(ir_ctx *ctx) uint32_t b; ir_insn *insn; ir_worklist worklist; + uint32_t bb_init_falgs; uint32_t count, bb_count = 0; uint32_t edges_count = 0; ir_block *blocks, *bb; @@ -221,7 +222,6 @@ next_successor: _ir_add_successors(ctx, ref, &worklist); } while (ir_worklist_len(&worklist)); } - ir_worklist_clear(&worklist); IR_ASSERT(bb_count > 0); @@ -230,6 +230,8 @@ next_successor: b = 1; bb = blocks + 1; count = 0; + /* SCCP already removed UNREACHABKE blocks, otherwiseall blocks are marked as UNREACHABLE first */ + bb_init_falgs = (ctx->flags & IR_SCCP_DONE) ? 0 : IR_BB_UNREACHABLE; IR_BITSET_FOREACH(bb_starts, len, start) { end = _blocks[start]; _blocks[start] = b; @@ -252,9 +254,8 @@ next_successor: if (insn->op == IR_START) { bb->flags = IR_BB_START; bb->predecessors_count = 0; - ir_worklist_push(&worklist, b); } else { - bb->flags = IR_BB_UNREACHABLE; /* all blocks are marked as UNREACHABLE first */ + bb->flags = bb_init_falgs; if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN) { n = insn->inputs_count; bb->predecessors_count = n; @@ -312,22 +313,33 @@ next_successor: ctx->cfg_edges = edges; ctx->cfg_map = _blocks; - /* Mark reachable blocks */ - while (ir_worklist_len(&worklist) != 0) { - uint32_t *p; + if (!(ctx->flags & IR_SCCP_DONE)) { + uint32_t reachable_count = 0; - b = ir_worklist_pop(&worklist); - bb = &blocks[b]; - bb->flags &= ~IR_BB_UNREACHABLE; - n = bb->successors_count; - if (n > 1) { - for (p = edges + bb->successors; n > 0; p++, n--) { - ir_worklist_push(&worklist, *p); + /* Mark reachable blocks */ + ir_worklist_clear(&worklist); + ir_worklist_push(&worklist, 1); + while (ir_worklist_len(&worklist) != 0) { + uint32_t *p; + + reachable_count++; + b = ir_worklist_pop(&worklist); + bb = &blocks[b]; + bb->flags &= ~IR_BB_UNREACHABLE; + n = bb->successors_count; + if (n > 1) { + for (p = edges + bb->successors; n > 0; p++, n--) { + ir_worklist_push(&worklist, *p); + } + } else if (n == 1) { + ir_worklist_push(&worklist, edges[bb->successors]); } - } else if (n == 1) { - ir_worklist_push(&worklist, edges[bb->successors]); + } + if (reachable_count != ctx->cfg_blocks_count) { + ir_remove_unreachable_blocks(ctx); } } + ir_worklist_free(&worklist); return 1; diff --git a/ir_main.c b/ir_main.c index a057d73..092f13f 100644 --- a/ir_main.c +++ b/ir_main.c @@ -165,10 +165,6 @@ int ir_compile_func(ir_ctx *ctx, int opt_level, uint32_t dump, const char *dump_ /* Schedule */ if (opt_level > 0) { - if (opt_level == 1) { - /* With -O2 unreachable blocks are removed by SCCP */ - ir_remove_unreachable_blocks(ctx); - } ir_build_dominators_tree(ctx); ir_find_loops(ctx); ir_gcm(ctx); diff --git a/ir_sccp.c b/ir_sccp.c index d57ee45..7424710 100644 --- a/ir_sccp.c +++ b/ir_sccp.c @@ -871,6 +871,7 @@ int ir_sccp(ir_ctx *ctx) ir_bitqueue_free(&worklist); ctx->flags &= ~IR_OPT_IN_SCCP; + ctx->flags |= IR_SCCP_DONE; return 1; } diff --git a/ir_test.c b/ir_test.c index cb7daff..0b3cdea 100644 --- a/ir_test.c +++ b/ir_test.c @@ -169,9 +169,6 @@ int main(int argc, char **argv) ir_sccp(&ctx); } ir_build_cfg(&ctx); - if (opt_level <= 1) { - ir_remove_unreachable_blocks(&ctx); - } if (opt_level > 0) { ir_build_dominators_tree(&ctx); ir_find_loops(&ctx);