mirror of
https://github.com/danog/ir.git
synced 2024-11-26 20:34:53 +01:00
Use reference to previous instruction instead of its length
This commit is contained in:
parent
ae19ad7c79
commit
dde8309108
6
ir.c
6
ir.c
@ -315,7 +315,7 @@ void ir_init(ir_ctx *ctx, ir_ref consts_limit, ir_ref insns_limit)
|
||||
ctx->fixed_save_regset = 0;
|
||||
ctx->live_intervals = NULL;
|
||||
ctx->regs = NULL;
|
||||
ctx->prev_insn_len = NULL;
|
||||
ctx->prev_ref = NULL;
|
||||
ctx->data = NULL;
|
||||
|
||||
ctx->code_buffer = NULL;
|
||||
@ -376,8 +376,8 @@ void ir_free(ir_ctx *ctx)
|
||||
if (ctx->regs) {
|
||||
ir_mem_free(ctx->regs);
|
||||
}
|
||||
if (ctx->prev_insn_len) {
|
||||
ir_mem_free(ctx->prev_insn_len);
|
||||
if (ctx->prev_ref) {
|
||||
ir_mem_free(ctx->prev_ref);
|
||||
}
|
||||
}
|
||||
|
||||
|
2
ir.h
2
ir.h
@ -483,7 +483,7 @@ typedef struct _ir_ctx {
|
||||
uint64_t fixed_save_regset;
|
||||
ir_live_interval **live_intervals;
|
||||
ir_regs *regs;
|
||||
ir_ref *prev_insn_len;
|
||||
ir_ref *prev_ref;
|
||||
void *data;
|
||||
uint32_t rodata_offset;
|
||||
uint32_t jmp_table_offset;
|
||||
|
@ -861,8 +861,8 @@ binop_fp:
|
||||
if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT
|
||||
// TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP
|
||||
&& (insn->op2 == ref - 1 ||
|
||||
(insn->op2 == ref - ctx->prev_insn_len[ref] - 1
|
||||
&& ctx->ir_base[ref - ctx->prev_insn_len[ref]].op == IR_SNAPSHOT))) {
|
||||
(insn->op2 == ctx->prev_ref[ref] - 1
|
||||
&& ctx->ir_base[ctx->prev_ref[ref]].op == IR_SNAPSHOT))) {
|
||||
if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) {
|
||||
if (insn->op1 > bb->start
|
||||
&& insn->op1 < ref
|
||||
@ -4777,7 +4777,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
||||
if (bb->flags & IR_BB_UNREACHABLE) {
|
||||
continue;
|
||||
}
|
||||
if (bb->end - ctx->prev_insn_len[bb->end] == bb->start
|
||||
if (ctx->prev_ref[bb->end] == bb->start
|
||||
&& bb->successors_count == 1
|
||||
&& !(bb->flags & (IR_BB_START|IR_BB_ENTRY|IR_BB_DESSA_MOVES))) {
|
||||
continue;
|
||||
|
6
ir_cfg.c
6
ir_cfg.c
@ -662,7 +662,7 @@ int ir_schedule_blocks(ir_ctx *ctx)
|
||||
list = ir_mem_malloc(sizeof(uint32_t) * (ctx->cfg_blocks_count + 1) * 2);
|
||||
map = list + (ctx->cfg_blocks_count + 1);
|
||||
for (b = 1, bb = &ctx->cfg_blocks[1]; b <= ctx->cfg_blocks_count; b++, bb++) {
|
||||
if (bb->end - ctx->prev_insn_len[bb->end] == bb->start
|
||||
if (ctx->prev_ref[bb->end] == bb->start
|
||||
&& bb->successors_count == 1
|
||||
&& !(bb->flags & IR_BB_DESSA_MOVES)) {
|
||||
bb->flags |= IR_BB_EMPTY;
|
||||
@ -806,7 +806,7 @@ uint32_t ir_skip_empty_target_blocks(ir_ctx *ctx, uint32_t b)
|
||||
while (1) {
|
||||
bb = &ctx->cfg_blocks[b];
|
||||
|
||||
if (bb->end - ctx->prev_insn_len[bb->end] == bb->start
|
||||
if (ctx->prev_ref[bb->end] == bb->start
|
||||
&& bb->successors_count == 1
|
||||
&& !(bb->flags & (IR_BB_START|IR_BB_ENTRY|IR_BB_DESSA_MOVES))) {
|
||||
b = ctx->cfg_edges[bb->successors];
|
||||
@ -828,7 +828,7 @@ uint32_t ir_skip_empty_next_blocks(ir_ctx *ctx, uint32_t b)
|
||||
|
||||
bb = &ctx->cfg_blocks[b];
|
||||
|
||||
if (bb->end - ctx->prev_insn_len[bb->end] == bb->start
|
||||
if (ctx->prev_ref[bb->end] == bb->start
|
||||
&& bb->successors_count == 1
|
||||
&& !(bb->flags & (IR_BB_START|/*IR_BB_ENTRY|*/IR_BB_DESSA_MOVES))) {
|
||||
b++;
|
||||
|
16
ir_emit.c
16
ir_emit.c
@ -264,24 +264,26 @@ 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;
|
||||
ir_ref i, n, prev;
|
||||
ir_block *bb;
|
||||
ir_insn *insn;
|
||||
|
||||
if (!ctx->prev_insn_len) {
|
||||
ctx->prev_insn_len = ir_mem_malloc(ctx->insns_count * sizeof(uint32_t));
|
||||
n = 1;
|
||||
if (!ctx->prev_ref) {
|
||||
ctx->prev_ref = ir_mem_malloc(ctx->insns_count * sizeof(ir_ref));
|
||||
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_insn_len[i] = n;
|
||||
prev = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,7 +292,7 @@ int ir_match(ir_ctx *ctx)
|
||||
if (bb->flags & IR_BB_UNREACHABLE) {
|
||||
continue;
|
||||
}
|
||||
for (i = bb->end; i >= bb->start; i -= ctx->prev_insn_len[i]) {
|
||||
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);
|
||||
|
@ -750,7 +750,7 @@ static int ir_emit_func(ir_ctx *ctx, FILE *f)
|
||||
if (bb->flags & IR_BB_UNREACHABLE) {
|
||||
continue;
|
||||
}
|
||||
if (bb->end - ctx->prev_insn_len[bb->end] == bb->start
|
||||
if (ctx->prev_ref[bb->end] == bb->start
|
||||
&& bb->successors_count == 1
|
||||
&& !(bb->flags & (IR_BB_START|IR_BB_ENTRY|IR_BB_DESSA_MOVES))) {
|
||||
continue;
|
||||
|
17
ir_ra.c
17
ir_ra.c
@ -46,14 +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;
|
||||
ir_ref i, n, prev;
|
||||
ir_block *bb;
|
||||
ir_insn *insn;
|
||||
uint32_t flags;
|
||||
|
||||
/* Assign unique virtual register to each data node */
|
||||
if (!ctx->prev_insn_len) {
|
||||
ctx->prev_insn_len = ir_mem_malloc(ctx->insns_count * sizeof(uint32_t));
|
||||
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;
|
||||
@ -65,12 +65,14 @@ int ir_assign_virtual_registers(ir_ctx *ctx)
|
||||
|
||||
/* skip first instruction */
|
||||
insn = ctx->ir_base + i;
|
||||
ctx->prev_ref[i] = 0;
|
||||
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_insn_len[i] = n;
|
||||
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)) {
|
||||
@ -80,10 +82,11 @@ 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_insn_len[i] = n;
|
||||
ctx->prev_ref[i] = prev;
|
||||
}
|
||||
ctx->vregs_count = vregs_count;
|
||||
ctx->vregs = vregs;
|
||||
@ -454,9 +457,9 @@ int ir_compute_live_ranges(ir_ctx *ctx)
|
||||
ref = bb->end;
|
||||
insn = &ctx->ir_base[ref];
|
||||
if (insn->op == IR_END || insn->op == IR_LOOP_END) {
|
||||
ref -= ctx->prev_insn_len[ref];
|
||||
ref = ctx->prev_ref[ref];
|
||||
}
|
||||
for (; ref > bb->start; ref -= ctx->prev_insn_len[ref]) {
|
||||
for (; ref > bb->start; ref = ctx->prev_ref[ref]) {
|
||||
uint32_t def_flags;
|
||||
uint32_t flags;
|
||||
ir_ref *p;
|
||||
|
@ -1701,8 +1701,8 @@ store_int:
|
||||
if (op2_insn->op >= IR_EQ && op2_insn->op <= IR_UGT
|
||||
// TODO: register allocator may clobber operands of CMP before they are used in the GUARD_CMP
|
||||
&& (insn->op2 == ref - 1 ||
|
||||
(insn->op2 == ref - ctx->prev_insn_len[ref] - 1
|
||||
&& ctx->ir_base[ref - ctx->prev_insn_len[ref]].op == IR_SNAPSHOT))) {
|
||||
(insn->op2 == ctx->prev_ref[ref] - 1
|
||||
&& ctx->ir_base[ctx->prev_ref[ref]].op == IR_SNAPSHOT))) {
|
||||
if (IR_IS_TYPE_INT(ctx->ir_base[op2_insn->op1].type)) {
|
||||
if (op2_insn->op1 > bb->start
|
||||
&& op2_insn->op1 < ref
|
||||
@ -7266,7 +7266,7 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
|
||||
if (bb->flags & IR_BB_UNREACHABLE) {
|
||||
continue;
|
||||
}
|
||||
if (bb->end - ctx->prev_insn_len[bb->end] == bb->start
|
||||
if (ctx->prev_ref[bb->end] == bb->start
|
||||
&& bb->successors_count == 1
|
||||
&& !(bb->flags & (IR_BB_START|IR_BB_ENTRY|IR_BB_DESSA_MOVES))) {
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user