diff --git a/ir.h b/ir.h index f827ff4..1410a73 100644 --- a/ir.h +++ b/ir.h @@ -582,6 +582,7 @@ int ir_build_cfg(ir_ctx *ctx); int ir_build_dominators_tree(ir_ctx *ctx); int ir_find_loops(ir_ctx *ctx); int ir_schedule_blocks(ir_ctx *ctx); +void ir_build_prev_refs(ir_ctx *ctx); /* SCCP - Sparse Conditional Constant Propagation (implementation in ir_sccp.c) */ int ir_sccp(ir_ctx *ctx); diff --git a/ir_emit.c b/ir_emit.c index aa43eeb..450ca9a 100644 --- a/ir_emit.c +++ b/ir_emit.c @@ -264,27 +264,11 @@ static void *ir_jmp_addr(ir_ctx *ctx, ir_insn *insn, ir_insn *addr_insn) int ir_match(ir_ctx *ctx) { uint32_t b; - ir_ref i, n, prev; + ir_ref i; ir_block *bb; - ir_insn *insn; if (!ctx->prev_ref) { - ctx->prev_ref = ir_mem_malloc(ctx->insns_count * sizeof(ir_ref)); - prev = 0; - for (b = 1, bb = ctx->cfg_blocks + b; b <= ctx->cfg_blocks_count; b++, bb++) { - if (bb->flags & IR_BB_UNREACHABLE) { - continue; - } - for (i = bb->start, insn = ctx->ir_base + i; i < bb->end;) { - ctx->prev_ref[i] = prev; - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI - prev = i; - i += n; - insn += n; - } - ctx->prev_ref[i] = prev; - } + ir_build_prev_refs(ctx); } ctx->rules = ir_mem_calloc(ctx->insns_count, sizeof(uint32_t)); @@ -293,7 +277,6 @@ int ir_match(ir_ctx *ctx) continue; } for (i = bb->end; i > bb->start; i = ctx->prev_ref[i]) { - insn = &ctx->ir_base[i]; if (!ctx->rules[i]) { ctx->rules[i] = ir_match_insn(ctx, i, bb); } diff --git a/ir_emit_c.c b/ir_emit_c.c index c90d1aa..f7e1e51 100644 --- a/ir_emit_c.c +++ b/ir_emit_c.c @@ -672,6 +672,10 @@ static int ir_emit_func(ir_ctx *ctx, FILE *f) ret_type = ir_get_return_type(ctx); + if (!ctx->prev_ref) { + ir_build_prev_refs(ctx); + } + use_list = &ctx->use_lists[1]; n = use_list->count; for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) { diff --git a/ir_gcm.c b/ir_gcm.c index 3133209..d4bc17a 100644 --- a/ir_gcm.c +++ b/ir_gcm.c @@ -739,3 +739,28 @@ restart: return 1; } + +void ir_build_prev_refs(ir_ctx *ctx) +{ + uint32_t b; + ir_block *bb; + ir_ref i, n, prev; + ir_insn *insn; + + ctx->prev_ref = ir_mem_malloc(ctx->insns_count * sizeof(ir_ref)); + prev = 0; + for (b = 1, bb = ctx->cfg_blocks + b; b <= ctx->cfg_blocks_count; b++, bb++) { + if (bb->flags & IR_BB_UNREACHABLE) { + continue; + } + for (i = bb->start, insn = ctx->ir_base + i; i < bb->end;) { + ctx->prev_ref[i] = prev; + n = ir_operands_count(ctx, insn); + n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + prev = i; + i += n; + insn += n; + } + ctx->prev_ref[i] = prev; + } +} diff --git a/ir_ra.c b/ir_ra.c index 18f0e48..5c59440 100644 --- a/ir_ra.c +++ b/ir_ra.c @@ -46,18 +46,14 @@ int ir_assign_virtual_registers(ir_ctx *ctx) uint32_t *vregs; uint32_t vregs_count = 0; uint32_t b; - ir_ref i, n, prev; + ir_ref i, n; ir_block *bb; ir_insn *insn; uint32_t flags; /* Assign unique virtual register to each data node */ - if (!ctx->prev_ref) { - ctx->prev_ref = ir_mem_malloc(ctx->insns_count * sizeof(ir_ref)); - } vregs = ir_mem_calloc(ctx->insns_count, sizeof(ir_ref)); n = 1; - prev = 0; for (b = 1, bb = ctx->cfg_blocks + b; b <= ctx->cfg_blocks_count; b++, bb++) { if (bb->flags & IR_BB_UNREACHABLE) { continue; @@ -66,14 +62,11 @@ int ir_assign_virtual_registers(ir_ctx *ctx) /* skip first instruction */ insn = ctx->ir_base + i; - ctx->prev_ref[i] = prev; - prev = i; n = ir_operands_count(ctx, insn); n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI i += n; insn += n; while (i < bb->end) { - ctx->prev_ref[i] = prev; flags = ir_op_flags[insn->op]; if (((flags & IR_OP_FLAG_DATA) && ctx->use_lists[i].count > 0) || ((flags & IR_OP_FLAG_MEM) && ctx->use_lists[i].count > 1)) { @@ -83,11 +76,9 @@ int ir_assign_virtual_registers(ir_ctx *ctx) } n = ir_operands_count(ctx, insn); n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI - prev = i; i += n; insn += n; } - ctx->prev_ref[i] = prev; } ctx->vregs_count = vregs_count; ctx->vregs = vregs;