mirror of
https://github.com/danog/ir.git
synced 2024-11-26 20:34:53 +01:00
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:
parent
b15d9d213f
commit
367d2e3246
3
ir.h
3
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)
|
||||
|
18
ir_cfg.c
18
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,10 +313,16 @@ next_successor:
|
||||
ctx->cfg_edges = edges;
|
||||
ctx->cfg_map = _blocks;
|
||||
|
||||
if (!(ctx->flags & IR_SCCP_DONE)) {
|
||||
uint32_t reachable_count = 0;
|
||||
|
||||
/* 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;
|
||||
@ -328,6 +335,11 @@ next_successor:
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user