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.
This commit is contained in:
Dmitry Stogov 2023-04-27 14:18:39 +03:00
parent b15d9d213f
commit 367d2e3246
5 changed files with 31 additions and 22 deletions

3
ir.h
View File

@ -483,6 +483,9 @@ void ir_strtab_free(ir_strtab *strtab);
#define IR_GEN_NATIVE (1<<21) #define IR_GEN_NATIVE (1<<21)
#define IR_GEN_C (1<<22) #define IR_GEN_C (1<<22)
/* Temporary: SCCP */
#define IR_SCCP_DONE (1<<25)
/* Temporary: Live Ranges */ /* Temporary: Live Ranges */
#define IR_LR_HAVE_VARS (1<<25) #define IR_LR_HAVE_VARS (1<<25)
#define IR_LR_HAVE_DESSA_MOVES (1<<26) #define IR_LR_HAVE_DESSA_MOVES (1<<26)

View File

@ -101,6 +101,7 @@ int ir_build_cfg(ir_ctx *ctx)
uint32_t b; uint32_t b;
ir_insn *insn; ir_insn *insn;
ir_worklist worklist; ir_worklist worklist;
uint32_t bb_init_falgs;
uint32_t count, bb_count = 0; uint32_t count, bb_count = 0;
uint32_t edges_count = 0; uint32_t edges_count = 0;
ir_block *blocks, *bb; ir_block *blocks, *bb;
@ -221,7 +222,6 @@ next_successor:
_ir_add_successors(ctx, ref, &worklist); _ir_add_successors(ctx, ref, &worklist);
} while (ir_worklist_len(&worklist)); } while (ir_worklist_len(&worklist));
} }
ir_worklist_clear(&worklist);
IR_ASSERT(bb_count > 0); IR_ASSERT(bb_count > 0);
@ -230,6 +230,8 @@ next_successor:
b = 1; b = 1;
bb = blocks + 1; bb = blocks + 1;
count = 0; 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) { IR_BITSET_FOREACH(bb_starts, len, start) {
end = _blocks[start]; end = _blocks[start];
_blocks[start] = b; _blocks[start] = b;
@ -252,9 +254,8 @@ next_successor:
if (insn->op == IR_START) { if (insn->op == IR_START) {
bb->flags = IR_BB_START; bb->flags = IR_BB_START;
bb->predecessors_count = 0; bb->predecessors_count = 0;
ir_worklist_push(&worklist, b);
} else { } 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) { if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN) {
n = insn->inputs_count; n = insn->inputs_count;
bb->predecessors_count = n; bb->predecessors_count = n;
@ -312,10 +313,16 @@ next_successor:
ctx->cfg_edges = edges; ctx->cfg_edges = edges;
ctx->cfg_map = _blocks; ctx->cfg_map = _blocks;
if (!(ctx->flags & IR_SCCP_DONE)) {
uint32_t reachable_count = 0;
/* Mark reachable blocks */ /* Mark reachable blocks */
ir_worklist_clear(&worklist);
ir_worklist_push(&worklist, 1);
while (ir_worklist_len(&worklist) != 0) { while (ir_worklist_len(&worklist) != 0) {
uint32_t *p; uint32_t *p;
reachable_count++;
b = ir_worklist_pop(&worklist); b = ir_worklist_pop(&worklist);
bb = &blocks[b]; bb = &blocks[b];
bb->flags &= ~IR_BB_UNREACHABLE; bb->flags &= ~IR_BB_UNREACHABLE;
@ -328,6 +335,11 @@ next_successor:
ir_worklist_push(&worklist, edges[bb->successors]); ir_worklist_push(&worklist, edges[bb->successors]);
} }
} }
if (reachable_count != ctx->cfg_blocks_count) {
ir_remove_unreachable_blocks(ctx);
}
}
ir_worklist_free(&worklist); ir_worklist_free(&worklist);
return 1; return 1;

View File

@ -165,10 +165,6 @@ int ir_compile_func(ir_ctx *ctx, int opt_level, uint32_t dump, const char *dump_
/* Schedule */ /* Schedule */
if (opt_level > 0) { 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_build_dominators_tree(ctx);
ir_find_loops(ctx); ir_find_loops(ctx);
ir_gcm(ctx); ir_gcm(ctx);

View File

@ -871,6 +871,7 @@ int ir_sccp(ir_ctx *ctx)
ir_bitqueue_free(&worklist); ir_bitqueue_free(&worklist);
ctx->flags &= ~IR_OPT_IN_SCCP; ctx->flags &= ~IR_OPT_IN_SCCP;
ctx->flags |= IR_SCCP_DONE;
return 1; return 1;
} }

View File

@ -169,9 +169,6 @@ int main(int argc, char **argv)
ir_sccp(&ctx); ir_sccp(&ctx);
} }
ir_build_cfg(&ctx); ir_build_cfg(&ctx);
if (opt_level <= 1) {
ir_remove_unreachable_blocks(&ctx);
}
if (opt_level > 0) { if (opt_level > 0) {
ir_build_dominators_tree(&ctx); ir_build_dominators_tree(&ctx);
ir_find_loops(&ctx); ir_find_loops(&ctx);