Avoid instruction selection for the first instructionis of basic blocks

This commit is contained in:
Dmitry Stogov 2022-11-18 15:07:19 +03:00
parent 7d07a4ac89
commit ef6c59ad8f
3 changed files with 45 additions and 24 deletions

View File

@ -4783,7 +4783,24 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
continue; continue;
} }
|=>b: |=>b:
for (i = bb->start, insn = ctx->ir_base + i, rule = ctx->rules + i; i <= bb->end;) {
i = bb->start;
insn = ctx->ir_base + i;
if (bb->flags & IR_BB_ENTRY) {
uint32_t label = ctx->cfg_blocks_count + ctx->consts_count + 3 + insn->op3;
|=>label:
ir_emit_prologue(ctx);
}
/* skip first instruction */
n = ir_operands_count(ctx, insn);
n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI
i += n;
insn += n;
rule = ctx->rules + i;
while (i <= bb->end) {
switch (*rule) { switch (*rule) {
case IR_SKIP: case IR_SKIP:
case IR_SKIP_MEM: case IR_SKIP_MEM:
@ -4797,13 +4814,6 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
case IR_RLOAD: case IR_RLOAD:
case IR_SNAPSHOT: case IR_SNAPSHOT:
break; break;
case IR_ENTRY:
{
uint32_t label = ctx->cfg_blocks_count + ctx->consts_count + 3 + insn->op3;
|=>label:
ir_emit_prologue(ctx);
}
break;
case IR_MUL_PWR2: case IR_MUL_PWR2:
case IR_DIV_PWR2: case IR_DIV_PWR2:
case IR_MOD_PWR2: case IR_MOD_PWR2:

View File

@ -292,12 +292,13 @@ int ir_match(ir_ctx *ctx)
if (bb->flags & IR_BB_UNREACHABLE) { if (bb->flags & IR_BB_UNREACHABLE) {
continue; continue;
} }
for (i = bb->end; i >= bb->start; i = ctx->prev_ref[i]) { for (i = bb->end; i > bb->start; i = ctx->prev_ref[i]) {
insn = &ctx->ir_base[i]; insn = &ctx->ir_base[i];
if (!ctx->rules[i]) { if (!ctx->rules[i]) {
ctx->rules[i] = ir_match_insn(ctx, i, bb); ctx->rules[i] = ir_match_insn(ctx, i, bb);
} }
} }
ctx->rules[i] = IR_SKIP;
} }
return 1; return 1;

View File

@ -7272,7 +7272,31 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
continue; continue;
} }
|=>b: |=>b:
for (i = bb->start, insn = ctx->ir_base + i, rule = ctx->rules + i; i <= bb->end;) {
i = bb->start;
insn = ctx->ir_base + i;
if (bb->flags & IR_BB_ENTRY) {
uint32_t label = ctx->cfg_blocks_count + ctx->consts_count + 3 + insn->op3;
|=>label:
if ((ctx->flags & IR_GEN_ENDBR) && (ctx->flags & IR_ENTRY_BR_TARGET)) {
|.if X64
| endbr64
|.else
| endbr32
|.endif
}
ir_emit_prologue(ctx);
}
/* skip first instruction */
n = ir_operands_count(ctx, insn);
n = 1 + (n >> 2); // support for multi-word instructions like MERGE and PHI
i += n;
insn += n;
rule = ctx->rules + i;
while (i <= bb->end) {
switch (*rule) { switch (*rule) {
case IR_SKIP: case IR_SKIP:
case IR_SKIP_MEM: case IR_SKIP_MEM:
@ -7289,20 +7313,6 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
case IR_RLOAD: case IR_RLOAD:
case IR_SNAPSHOT: case IR_SNAPSHOT:
break; break;
case IR_ENTRY:
{
uint32_t label = ctx->cfg_blocks_count + ctx->consts_count + 3 + insn->op3;
|=>label:
if ((ctx->flags & IR_GEN_ENDBR) && (ctx->flags & IR_ENTRY_BR_TARGET)) {
|.if X64
| endbr64
|.else
| endbr32
|.endif
}
ir_emit_prologue(ctx);
}
break;
case IR_LEA_OB: case IR_LEA_OB:
{ {
ir_reg op1_reg = ctx->regs[i][1]; ir_reg op1_reg = ctx->regs[i][1];