Avoid loop nesting forest consruction if we didn't detect loops in ir_build_dominators_tree()

This commit is contained in:
Dmitry Stogov 2023-04-27 18:00:30 +03:00
parent 367d2e3246
commit 23bbdd7ceb
2 changed files with 31 additions and 14 deletions

6
ir.h
View File

@ -473,6 +473,7 @@ void ir_strtab_free(ir_strtab *strtab);
#define IR_GEN_ENDBR (1<<10)
#define IR_MERGE_EMPTY_ENTRIES (1<<11)
#define IR_CFG_HAS_LOOPS (1<<14)
#define IR_IRREDUCIBLE_CFG (1<<15)
#define IR_OPT_FOLDING (1<<16)
@ -483,9 +484,12 @@ void ir_strtab_free(ir_strtab *strtab);
#define IR_GEN_NATIVE (1<<21)
#define IR_GEN_C (1<<22)
/* Temporary: SCCP */
/* Temporary: SCCP -> CFG */
#define IR_SCCP_DONE (1<<25)
/* Temporary: Dominators -> Loops */
#define IR_NO_LOOPS (1<<25)
/* Temporary: Live Ranges */
#define IR_LR_HAVE_VARS (1<<25)
#define IR_LR_HAVE_DESSA_MOVES (1<<26)

View File

@ -596,6 +596,8 @@ int ir_build_dominators_tree(ir_ctx *ctx)
uint32_t *edges;
bool changed;
ctx->flags &= ~IR_NO_LOOPS;
postnum = 1;
compute_postnum(ctx, &postnum, 1);
@ -700,7 +702,8 @@ int ir_build_dominators_tree(ir_ctx *ctx)
ir_block *blocks, *bb;
uint32_t *edges;
//ir_dump_cfg(ctx, stderr);
ctx->flags |= IR_NO_LOOPS;
/* Find immediate dominators */
blocks = ctx->cfg_blocks;
edges = ctx->cfg_edges;
@ -719,6 +722,7 @@ int ir_build_dominators_tree(ir_ctx *ctx)
if (UNEXPECTED(idom > b)) {
// TODO: try to remove this case ???
ctx->flags &= ~IR_NO_LOOPS;
while (1) {
k--;
p++;
@ -744,6 +748,8 @@ int ir_build_dominators_tree(ir_ctx *ctx)
idom = blocks[idom].idom;
}
}
} else {
ctx->flags &= ~IR_NO_LOOPS;
}
}
bb->idom = idom;
@ -795,6 +801,10 @@ int ir_find_loops(ir_ctx *ctx)
uint32_t *edges = ctx->cfg_edges;
ir_worklist work;
if (ctx->flags & IR_NO_LOOPS) {
return 1;
}
/* We don't materialize the DJ spanning tree explicitly, as we are only interested in ancestor
* queries. These are implemented by checking entry/exit times of the DFS search. */
ir_worklist_init(&work, ctx->cfg_blocks_count + 1);
@ -900,6 +910,7 @@ next:
}
} else if (ir_worklist_len(&work)) {
bb->flags |= IR_BB_LOOP_HEADER;
ctx->flags |= IR_CFG_HAS_LOOPS;
bb->loop_depth = 1;
while (ir_worklist_len(&work)) {
j = ir_worklist_pop(&work);
@ -927,6 +938,7 @@ next:
}
}
if (ctx->flags & IR_CFG_HAS_LOOPS) {
for (n = 1; n < count; n++) {
i = sorted_blocks[n];
ir_block *bb = &blocks[i];
@ -943,6 +955,7 @@ next:
}
}
}
}
ir_mem_free(entry_times);
ir_worklist_free(&work);