diff --git a/ir.c b/ir.c index 48e4a1e..010474e 100644 --- a/ir.c +++ b/ir.c @@ -990,7 +990,7 @@ void ir_build_def_use_lists(ir_ctx *ctx) lists[def].count++; } } - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_inputs_to_len(n); i += n; insn += n; } @@ -1012,7 +1012,7 @@ void ir_build_def_use_lists(ir_ctx *ctx) edges[use_list->refs + use_list->count++] = i; } } - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_inputs_to_len(n); i += n; insn += n; } diff --git a/ir_aarch64.dasc b/ir_aarch64.dasc index be56619..e652636 100644 --- a/ir_aarch64.dasc +++ b/ir_aarch64.dasc @@ -4670,8 +4670,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) } break; } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; rule += n; @@ -4735,8 +4734,7 @@ static void ir_preallocate_call_stack(ir_ctx *ctx, ir_backend_data *data) peak_call_stack_size = call_stack_size; } } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; } @@ -4911,8 +4909,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) } /* skip first instruction */ - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; rule = ctx->rules + i; @@ -5107,8 +5104,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) IR_ASSERT(0 && "NIY rule/insruction"); break; } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; rule += n; diff --git a/ir_check.c b/ir_check.c index 35b3355..90748e5 100644 --- a/ir_check.c +++ b/ir_check.c @@ -339,7 +339,7 @@ bool ir_check(const ir_ctx *ctx) } } } - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_inputs_to_len(n); i += n; insn += n; } diff --git a/ir_dump.c b/ir_dump.c index 5ab56a1..1438fe8 100644 --- a/ir_dump.c +++ b/ir_dump.c @@ -132,7 +132,7 @@ void ir_dump_dot(const ir_ctx *ctx, FILE *f) } } } - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_inputs_to_len(n); i += n; insn += n; } diff --git a/ir_emit_c.c b/ir_emit_c.c index 911d874..6fb9b7d 100644 --- a/ir_emit_c.c +++ b/ir_emit_c.c @@ -756,8 +756,7 @@ static int ir_emit_func(ir_ctx *ctx, FILE *f) return 0; } } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; } @@ -955,8 +954,7 @@ static int ir_emit_func(ir_ctx *ctx, FILE *f) default: IR_ASSERT(0 && "NIY instruction"); } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; } diff --git a/ir_gcm.c b/ir_gcm.c index 865e445..f0d93a1 100644 --- a/ir_gcm.c +++ b/ir_gcm.c @@ -529,7 +529,7 @@ int ir_schedule(ir_ctx *ctx) consts_count += ir_count_constant(used, insn->op2); } n = ir_input_edges_count(ctx, insn); - insns_count += 1 + (n >> 2); // support for multi-word instructions like MERGE + insns_count += ir_insn_inputs_to_len(n); i = _next[i]; insn = &ctx->ir_base[i]; /* Schedule PARAM, VAR, PI */ @@ -547,7 +547,7 @@ int ir_schedule(ir_ctx *ctx) ir_bitset_incl(scheduled, i); _xlat[i] = insns_count; /* Reuse "n" from MERGE and skip first input */ - insns_count += 1 + ((n + 1) >> 2); // support for multi-word instructions like PHI + insns_count += ir_insn_inputs_to_len(n + 1); for (j = n, p = insn->ops + 2; j > 0; p++, j--) { input = *p; if (input < IR_TRUE) { @@ -591,7 +591,7 @@ restart: } ir_bitset_incl(scheduled, i); _xlat[i] = insns_count; - insns_count += 1 + (n >> 2); // support for multi-word instructions like CALL + insns_count += ir_insn_inputs_to_len(n); i = _next[i]; insn = &ctx->ir_base[i]; } @@ -830,8 +830,7 @@ void ir_build_prev_refs(ir_ctx *ctx) IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE)); 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 + n = ir_insn_len(insn); prev = i; i += n; insn += n; diff --git a/ir_private.h b/ir_private.h index 2a5263d..fd0d1bd 100644 --- a/ir_private.h +++ b/ir_private.h @@ -842,6 +842,22 @@ IR_ALWAYS_INLINE ir_ref ir_input_edges_count(const ir_ctx *ctx, const ir_insn *i return n; } +IR_ALWAYS_INLINE uint32_t ir_insn_inputs_to_len(uint32_t inputs_count) +{ + return 1 + (inputs_count >> 2); +} + +IR_ALWAYS_INLINE uint32_t ir_insn_len(const ir_insn *insn) +{ + uint32_t flags = ir_op_flags[insn->op]; + uint32_t n = 1; + if (UNEXPECTED(IR_OP_HAS_VAR_INPUTS(flags))) { + /* MERGE, PHI, CALL, etc */ + n = ir_insn_inputs_to_len(insn->inputs_count); + } + return n; +} + /*** IR Binding ***/ IR_ALWAYS_INLINE ir_ref ir_binding_find(const ir_ctx *ctx, ir_ref ref) { diff --git a/ir_ra.c b/ir_ra.c index c7c2142..73433e7 100644 --- a/ir_ra.c +++ b/ir_ra.c @@ -57,8 +57,7 @@ static int ir_assign_virtual_registers_slow(ir_ctx *ctx) /* skip first instruction */ insn = ctx->ir_base + i; - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; while (i < bb->end) { @@ -69,8 +68,7 @@ static int ir_assign_virtual_registers_slow(ir_ctx *ctx) vregs[i] = ++vregs_count; } } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; } diff --git a/ir_save.c b/ir_save.c index 3e73a79..1df488f 100644 --- a/ir_save.c +++ b/ir_save.c @@ -123,7 +123,7 @@ void ir_save(const ir_ctx *ctx, FILE *f) } } fprintf(f, "\n"); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_inputs_to_len(n); i += n; insn += n; } diff --git a/ir_x86.dasc b/ir_x86.dasc index bc0de86..08e4d51 100644 --- a/ir_x86.dasc +++ b/ir_x86.dasc @@ -7716,8 +7716,7 @@ static void ir_allocate_unique_spill_slots(ir_ctx *ctx) } break; } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; rule += n; @@ -7778,8 +7777,7 @@ static void ir_preallocate_call_stack(ir_ctx *ctx, ir_backend_data *data) peak_call_stack_size = call_stack_size; } } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; } @@ -7984,8 +7982,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) } /* skip first instruction */ - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; rule = ctx->rules + i; @@ -8515,8 +8512,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr) IR_ASSERT(0 && "NIY rule/insruction"); break; } - n = ir_operands_count(ctx, insn); - n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI + n = ir_insn_len(insn); i += n; insn += n; rule += n;