mirror of
https://github.com/danog/ir.git
synced 2024-11-30 04:39:43 +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_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)
|
||||||
|
18
ir_cfg.c
18
ir_cfg.c
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user