From 23bbdd7cebbd7a3726d66afbd646d58e12b08158 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Apr 2023 18:00:30 +0300 Subject: [PATCH] Avoid loop nesting forest consruction if we didn't detect loops in ir_build_dominators_tree() --- ir.h | 6 +++++- ir_cfg.c | 39 ++++++++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/ir.h b/ir.h index 407f2b5..11b9cee 100644 --- a/ir.h +++ b/ir.h @@ -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) diff --git a/ir_cfg.c b/ir_cfg.c index b71c1be..508aa46 100644 --- a/ir_cfg.c +++ b/ir_cfg.c @@ -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,19 +938,21 @@ next: } } - for (n = 1; n < count; n++) { - i = sorted_blocks[n]; - ir_block *bb = &blocks[i]; - if (bb->loop_header > 0) { - ir_block *loop = &blocks[bb->loop_header]; - uint32_t loop_depth = loop->loop_depth; + if (ctx->flags & IR_CFG_HAS_LOOPS) { + for (n = 1; n < count; n++) { + i = sorted_blocks[n]; + ir_block *bb = &blocks[i]; + if (bb->loop_header > 0) { + ir_block *loop = &blocks[bb->loop_header]; + uint32_t loop_depth = loop->loop_depth; - if (bb->flags & IR_BB_LOOP_HEADER) { - loop_depth++; - } - bb->loop_depth = loop_depth; - if (bb->flags & (IR_BB_ENTRY|IR_BB_LOOP_WITH_ENTRY)) { - loop->flags |= IR_BB_LOOP_WITH_ENTRY; + if (bb->flags & IR_BB_LOOP_HEADER) { + loop_depth++; + } + bb->loop_depth = loop_depth; + if (bb->flags & (IR_BB_ENTRY|IR_BB_LOOP_WITH_ENTRY)) { + loop->flags |= IR_BB_LOOP_WITH_ENTRY; + } } } }