mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Update IR
IR commit: 7c26e26126123beac8dbaf811d5eac8d789d584f
This commit is contained in:
@@ -1110,11 +1110,13 @@ ir_ref ir_get_op(ir_ctx *ctx, ir_ref ref, int32_t n)
|
|||||||
|
|
||||||
ir_ref ir_param(ir_ctx *ctx, ir_type type, ir_ref region, const char *name, int pos)
|
ir_ref ir_param(ir_ctx *ctx, ir_type type, ir_ref region, const char *name, int pos)
|
||||||
{
|
{
|
||||||
|
IR_ASSERT(ctx->ir_base[region].op == IR_START);
|
||||||
return ir_emit(ctx, IR_OPT(IR_PARAM, type), region, ir_str(ctx, name), pos);
|
return ir_emit(ctx, IR_OPT(IR_PARAM, type), region, ir_str(ctx, name), pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_ref ir_var(ir_ctx *ctx, ir_type type, ir_ref region, const char *name)
|
ir_ref ir_var(ir_ctx *ctx, ir_type type, ir_ref region, const char *name)
|
||||||
{
|
{
|
||||||
|
IR_ASSERT(IR_IS_BB_START(ctx->ir_base[region].op));
|
||||||
return ir_emit(ctx, IR_OPT(IR_VAR, type), region, ir_str(ctx, name), IR_UNUSED);
|
return ir_emit(ctx, IR_OPT(IR_VAR, type), region, ir_str(ctx, name), IR_UNUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1963,7 +1965,7 @@ ir_ref _ir_VAR(ir_ctx *ctx, ir_type type, const char* name)
|
|||||||
ir_ref ref = ctx->control;
|
ir_ref ref = ctx->control;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
IR_ASSERT(ctx->control);
|
IR_ASSERT(ref);
|
||||||
if (IR_IS_BB_START(ctx->ir_base[ref].op)) {
|
if (IR_IS_BB_START(ctx->ir_base[ref].op)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3731,6 +3731,10 @@ static void ir_emit_vload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
int32_t offset;
|
int32_t offset;
|
||||||
ir_mem mem;
|
ir_mem mem;
|
||||||
|
|
||||||
|
if (ctx->use_lists[def].count == 1) {
|
||||||
|
/* dead load */
|
||||||
|
return;
|
||||||
|
}
|
||||||
IR_ASSERT(var_insn->op == IR_VAR);
|
IR_ASSERT(var_insn->op == IR_VAR);
|
||||||
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
|
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
|
||||||
offset = IR_SPILL_POS_TO_OFFSET(var_insn->op3);
|
offset = IR_SPILL_POS_TO_OFFSET(var_insn->op3);
|
||||||
@@ -4128,6 +4132,10 @@ static void ir_emit_block_begin(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
dasm_State **Dst = &data->dasm_state;
|
dasm_State **Dst = &data->dasm_state;
|
||||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||||
|
|
||||||
|
if (ctx->use_lists[def].count == 1) {
|
||||||
|
/* dead load */
|
||||||
|
return;
|
||||||
|
}
|
||||||
| mov Rx(def_reg), sp
|
| mov Rx(def_reg), sp
|
||||||
|
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
||||||
|
|||||||
@@ -890,9 +890,11 @@ int ir_schedule(ir_ctx *ctx)
|
|||||||
|
|
||||||
/* Topological sort according dependencies inside each basic block */
|
/* Topological sort according dependencies inside each basic block */
|
||||||
for (b = 1, bb = ctx->cfg_blocks + 1; b <= ctx->cfg_blocks_count; b++, bb++) {
|
for (b = 1, bb = ctx->cfg_blocks + 1; b <= ctx->cfg_blocks_count; b++, bb++) {
|
||||||
|
ir_ref start;
|
||||||
|
|
||||||
IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE));
|
IR_ASSERT(!(bb->flags & IR_BB_UNREACHABLE));
|
||||||
/* Schedule BB start */
|
/* Schedule BB start */
|
||||||
i = bb->start;
|
start = i = bb->start;
|
||||||
_xlat[i] = bb->start = insns_count;
|
_xlat[i] = bb->start = insns_count;
|
||||||
insn = &ctx->ir_base[i];
|
insn = &ctx->ir_base[i];
|
||||||
if (insn->op == IR_CASE_VAL) {
|
if (insn->op == IR_CASE_VAL) {
|
||||||
@@ -904,12 +906,15 @@ int ir_schedule(ir_ctx *ctx)
|
|||||||
i = _next[i];
|
i = _next[i];
|
||||||
insn = &ctx->ir_base[i];
|
insn = &ctx->ir_base[i];
|
||||||
if (bb->flags & (IR_BB_HAS_PHI|IR_BB_HAS_PI|IR_BB_HAS_PARAM|IR_BB_HAS_VAR)) {
|
if (bb->flags & (IR_BB_HAS_PHI|IR_BB_HAS_PI|IR_BB_HAS_PARAM|IR_BB_HAS_VAR)) {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
/* Schedule PARAM, VAR, PI */
|
/* Schedule PARAM, VAR, PI */
|
||||||
while (insn->op == IR_PARAM || insn->op == IR_VAR || insn->op == IR_PI) {
|
while (insn->op == IR_PARAM || insn->op == IR_VAR || insn->op == IR_PI) {
|
||||||
_xlat[i] = insns_count;
|
_xlat[i] = insns_count;
|
||||||
insns_count += 1;
|
insns_count += 1;
|
||||||
i = _next[i];
|
i = _next[i];
|
||||||
insn = &ctx->ir_base[i];
|
insn = &ctx->ir_base[i];
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
/* Schedule PHIs */
|
/* Schedule PHIs */
|
||||||
while (insn->op == IR_PHI) {
|
while (insn->op == IR_PHI) {
|
||||||
@@ -926,6 +931,52 @@ int ir_schedule(ir_ctx *ctx)
|
|||||||
}
|
}
|
||||||
i = _next[i];
|
i = _next[i];
|
||||||
insn = &ctx->ir_base[i];
|
insn = &ctx->ir_base[i];
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
/* Schedule remaining PHIs */
|
||||||
|
if (UNEXPECTED(count < ctx->use_lists[start].count - 1)) {
|
||||||
|
ir_use_list *use_list = &ctx->use_lists[start];
|
||||||
|
ir_ref *p, count = use_list->count;
|
||||||
|
ir_ref phis = _prev[i];
|
||||||
|
|
||||||
|
for (p = &ctx->use_edges[use_list->refs]; count > 0; p++, count--) {
|
||||||
|
ir_ref use = *p;
|
||||||
|
if (!_xlat[use]) {
|
||||||
|
ir_insn *use_insn = &ctx->ir_base[use];
|
||||||
|
if (use_insn->op == IR_PARAM
|
||||||
|
|| use_insn->op == IR_VAR
|
||||||
|
|| use_insn->op == IR_PI
|
||||||
|
|| use_insn->op == IR_PHI) {
|
||||||
|
if (_prev[use] != phis) {
|
||||||
|
/* remove "use" */
|
||||||
|
_prev[_next[use]] = _prev[use];
|
||||||
|
_next[_prev[use]] = _next[use];
|
||||||
|
/* insert "use" after "phis" */
|
||||||
|
_prev[use] = phis;
|
||||||
|
_next[use] = _next[phis];
|
||||||
|
_prev[_next[phis]] = use;
|
||||||
|
_next[phis] = use;
|
||||||
|
}
|
||||||
|
phis = use;
|
||||||
|
_xlat[use] = insns_count;
|
||||||
|
if (use_insn->op == IR_PHI) {
|
||||||
|
ir_ref *q;
|
||||||
|
/* Reuse "n" from MERGE and skip first input */
|
||||||
|
insns_count += ir_insn_inputs_to_len(n + 1);
|
||||||
|
for (j = n, q = use_insn->ops + 2; j > 0; q++, j--) {
|
||||||
|
ir_ref input = *q;
|
||||||
|
if (input < IR_TRUE) {
|
||||||
|
consts_count += ir_count_constant(_xlat, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
insns_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i = _next[phis];
|
||||||
|
insn = &ctx->ir_base[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bb->successors_count > 1) {
|
if (bb->successors_count > 1) {
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ static bool ir_is_dead_load_ex(ir_ctx *ctx, ir_ref ref, uint32_t flags, ir_insn
|
|||||||
{
|
{
|
||||||
if ((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) {
|
if ((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) {
|
||||||
return ctx->use_lists[ref].count == 1;
|
return ctx->use_lists[ref].count == 1;
|
||||||
} else if (insn->op == IR_ALLOCA) {
|
} else if (insn->op == IR_ALLOCA || insn->op == IR_BLOCK_BEGIN) {
|
||||||
return ctx->use_lists[ref].count == 1;
|
return ctx->use_lists[ref].count == 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -644,8 +644,13 @@ static void ir_sccp_remove_unfeasible_merge_inputs(ir_ctx *ctx, ir_insn *_values
|
|||||||
next_insn = use_insn;
|
next_insn = use_insn;
|
||||||
} else if (use_insn->op != IR_NOP) {
|
} else if (use_insn->op != IR_NOP) {
|
||||||
IR_ASSERT(use_insn->op1 == ref);
|
IR_ASSERT(use_insn->op1 == ref);
|
||||||
use_insn->op1 = prev;
|
IR_ASSERT(use_insn->op == IR_VAR);
|
||||||
ir_use_list_add(ctx, prev, use);
|
ir_ref region = prev;
|
||||||
|
while (!IR_IS_BB_START(ctx->ir_base[region].op)) {
|
||||||
|
region = ctx->ir_base[region].op1;
|
||||||
|
}
|
||||||
|
use_insn->op1 = region;
|
||||||
|
ir_use_list_add(ctx, region, use);
|
||||||
p = &ctx->use_edges[use_list->refs + k];
|
p = &ctx->use_edges[use_list->refs + k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1240,6 +1245,22 @@ static void ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin, ir_bitqueue *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ir_remove_unused_vars(ir_ctx *ctx, ir_ref start, ir_ref end)
|
||||||
|
{
|
||||||
|
ir_use_list *use_list = &ctx->use_lists[start];
|
||||||
|
ir_ref *p, use, n = use_list->count;
|
||||||
|
|
||||||
|
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
|
||||||
|
use = *p;
|
||||||
|
if (use != end) {
|
||||||
|
ir_insn *use_insn = &ctx->ir_base[use];
|
||||||
|
IR_ASSERT(use_insn->op == IR_VAR);
|
||||||
|
IR_ASSERT(ctx->use_lists[use].count == 0);
|
||||||
|
MAKE_NOP(use_insn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist)
|
static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist)
|
||||||
{
|
{
|
||||||
if (insn->inputs_count == 2) {
|
if (insn->inputs_count == 2) {
|
||||||
@@ -1289,8 +1310,12 @@ static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn,
|
|||||||
ir_ref next_ref = ctx->use_edges[ctx->use_lists[ref].refs];
|
ir_ref next_ref = ctx->use_edges[ctx->use_lists[ref].refs];
|
||||||
ir_insn *next = &ctx->ir_base[next_ref];
|
ir_insn *next = &ctx->ir_base[next_ref];
|
||||||
|
|
||||||
IR_ASSERT(ctx->use_lists[start1_ref].count == 1);
|
if (ctx->use_lists[start1_ref].count != 1) {
|
||||||
IR_ASSERT(ctx->use_lists[start2_ref].count == 1);
|
ir_remove_unused_vars(ctx, start1_ref, end1_ref);
|
||||||
|
}
|
||||||
|
if (ctx->use_lists[start2_ref].count != 1) {
|
||||||
|
ir_remove_unused_vars(ctx, start2_ref, end2_ref);
|
||||||
|
}
|
||||||
|
|
||||||
next->op1 = root->op1;
|
next->op1 = root->op1;
|
||||||
ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref);
|
ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref);
|
||||||
@@ -1331,7 +1356,9 @@ static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn,
|
|||||||
if (start->op != IR_CASE_VAL && start->op != IR_CASE_DEFAULT) {
|
if (start->op != IR_CASE_VAL && start->op != IR_CASE_DEFAULT) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
IR_ASSERT(ctx->use_lists[start_ref].count == 1);
|
if (ctx->use_lists[start_ref].count != 1) {
|
||||||
|
ir_remove_unused_vars(ctx, start_ref, end_ref);
|
||||||
|
}
|
||||||
if (!root_ref) {
|
if (!root_ref) {
|
||||||
root_ref = start->op1;
|
root_ref = start->op1;
|
||||||
if (ctx->use_lists[root_ref].count != count) {
|
if (ctx->use_lists[root_ref].count != count) {
|
||||||
@@ -1454,8 +1481,12 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re
|
|||||||
}
|
}
|
||||||
next = &ctx->ir_base[next_ref];
|
next = &ctx->ir_base[next_ref];
|
||||||
|
|
||||||
IR_ASSERT(ctx->use_lists[start1_ref].count == 1);
|
if (ctx->use_lists[start1_ref].count != 1) {
|
||||||
IR_ASSERT(ctx->use_lists[start2_ref].count == 1);
|
ir_remove_unused_vars(ctx, start1_ref, end1_ref);
|
||||||
|
}
|
||||||
|
if (ctx->use_lists[start2_ref].count != 1) {
|
||||||
|
ir_remove_unused_vars(ctx, start2_ref, end2_ref);
|
||||||
|
}
|
||||||
|
|
||||||
insn->op = (
|
insn->op = (
|
||||||
(is_less ? cond->op1 : cond->op2)
|
(is_less ? cond->op1 : cond->op2)
|
||||||
@@ -1540,8 +1571,12 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re
|
|||||||
}
|
}
|
||||||
next = &ctx->ir_base[next_ref];
|
next = &ctx->ir_base[next_ref];
|
||||||
|
|
||||||
IR_ASSERT(ctx->use_lists[start1_ref].count == 1);
|
if (ctx->use_lists[start1_ref].count != 1) {
|
||||||
IR_ASSERT(ctx->use_lists[start2_ref].count == 1);
|
ir_remove_unused_vars(ctx, start1_ref, end1_ref);
|
||||||
|
}
|
||||||
|
if (ctx->use_lists[start2_ref].count != 1) {
|
||||||
|
ir_remove_unused_vars(ctx, start2_ref, end2_ref);
|
||||||
|
}
|
||||||
|
|
||||||
insn->op = IR_ABS;
|
insn->op = IR_ABS;
|
||||||
insn->inputs_count = 1;
|
insn->inputs_count = 1;
|
||||||
@@ -1605,8 +1640,12 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re
|
|||||||
}
|
}
|
||||||
next = &ctx->ir_base[next_ref];
|
next = &ctx->ir_base[next_ref];
|
||||||
|
|
||||||
IR_ASSERT(ctx->use_lists[start1_ref].count == 1);
|
if (ctx->use_lists[start1_ref].count != 1) {
|
||||||
IR_ASSERT(ctx->use_lists[start2_ref].count == 1);
|
ir_remove_unused_vars(ctx, start1_ref, end1_ref);
|
||||||
|
}
|
||||||
|
if (ctx->use_lists[start2_ref].count != 1) {
|
||||||
|
ir_remove_unused_vars(ctx, start2_ref, end2_ref);
|
||||||
|
}
|
||||||
|
|
||||||
insn->op = IR_COND;
|
insn->op = IR_COND;
|
||||||
insn->inputs_count = 3;
|
insn->inputs_count = 3;
|
||||||
@@ -2126,9 +2165,13 @@ static void ir_optimize_merge(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_
|
|||||||
|
|
||||||
ir_ref next_ref = ctx->use_edges[use_list->refs + 1];
|
ir_ref next_ref = ctx->use_edges[use_list->refs + 1];
|
||||||
ir_insn *next = &ctx->ir_base[next_ref];
|
ir_insn *next = &ctx->ir_base[next_ref];
|
||||||
IR_ASSERT(next->op != IR_PHI);
|
|
||||||
|
|
||||||
if (phi->op == IR_PHI) {
|
if (next->op == IR_PHI) {
|
||||||
|
SWAP_REFS(phi_ref, next_ref);
|
||||||
|
SWAP_INSNS(phi, next);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phi->op == IR_PHI && next->op != IR_PHI) {
|
||||||
if (next->op == IR_IF && next->op1 == merge_ref && ctx->use_lists[phi_ref].count == 1) {
|
if (next->op == IR_IF && next->op1 == merge_ref && ctx->use_lists[phi_ref].count == 1) {
|
||||||
if (next->op2 == phi_ref) {
|
if (next->op2 == phi_ref) {
|
||||||
if (ir_try_split_if(ctx, next_ref, next, worklist)) {
|
if (ir_try_split_if(ctx, next_ref, next, worklist)) {
|
||||||
|
|||||||
@@ -1149,8 +1149,10 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co
|
|||||||
} else {
|
} else {
|
||||||
flags = IR_DEF_REUSES_OP1_REG | IR_USE_MUST_BE_IN_REG | IR_OP1_SHOULD_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG;
|
flags = IR_DEF_REUSES_OP1_REG | IR_USE_MUST_BE_IN_REG | IR_OP1_SHOULD_BE_IN_REG | IR_OP2_SHOULD_BE_IN_REG;
|
||||||
}
|
}
|
||||||
if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) {
|
if (IR_IS_CONST_REF(insn->op2)) {
|
||||||
n = ir_add_const_tmp_reg(ctx, insn->op2, 2, n, constraints);
|
if (insn->op1 != insn->op2) {
|
||||||
|
n = ir_add_const_tmp_reg(ctx, insn->op2, 2, n, constraints);
|
||||||
|
}
|
||||||
} else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) {
|
} else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) {
|
||||||
constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
|
constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
|
||||||
n++;
|
n++;
|
||||||
@@ -1223,9 +1225,11 @@ op2_const:
|
|||||||
} else if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
} else if (ir_rule(ctx, insn->op1) & IR_FUSED) {
|
||||||
flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG;
|
flags = IR_USE_MUST_BE_IN_REG | IR_OP2_MUST_BE_IN_REG;
|
||||||
}
|
}
|
||||||
if (IR_IS_CONST_REF(insn->op2) && insn->op1 != insn->op2) {
|
if (IR_IS_CONST_REF(insn->op2)) {
|
||||||
flags = IR_USE_MUST_BE_IN_REG | IR_OP1_SHOULD_BE_IN_REG;
|
if (insn->op1 != insn->op2) {
|
||||||
n = ir_add_const_tmp_reg(ctx, insn->op2, 2, n, constraints);
|
flags = IR_USE_MUST_BE_IN_REG | IR_OP1_SHOULD_BE_IN_REG;
|
||||||
|
n = ir_add_const_tmp_reg(ctx, insn->op2, 2, n, constraints);
|
||||||
|
}
|
||||||
} else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) {
|
} else if (ir_rule(ctx, insn->op2) == IR_STATIC_ALLOCA) {
|
||||||
constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
|
constraints->tmp_regs[n] = IR_TMP_REG(2, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
|
||||||
n++;
|
n++;
|
||||||
@@ -3360,10 +3364,23 @@ static ir_mem ir_fuse_addr(ir_ctx *ctx, ir_ref root, ir_ref ref)
|
|||||||
offset_insn = insn;
|
offset_insn = insn;
|
||||||
break;
|
break;
|
||||||
case IR_LEA_IB_O:
|
case IR_LEA_IB_O:
|
||||||
base_reg_ref = insn->op1 * sizeof(ir_ref) + 1;
|
op1_insn = &ctx->ir_base[insn->op1];
|
||||||
index_reg_ref = insn->op1 * sizeof(ir_ref) + 2;
|
|
||||||
offset_insn = insn;
|
offset_insn = insn;
|
||||||
scale = 1;
|
scale = 1;
|
||||||
|
if (ir_rule(ctx, op1_insn->op2) == IR_STATIC_ALLOCA) {
|
||||||
|
offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op1_insn->op2].op3);
|
||||||
|
base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
|
||||||
|
base_reg_ref = IR_UNUSED;
|
||||||
|
index_reg_ref = insn->op1 * sizeof(ir_ref) + 1;
|
||||||
|
} else if (ir_rule(ctx, op1_insn->op1) == IR_STATIC_ALLOCA) {
|
||||||
|
offset = IR_SPILL_POS_TO_OFFSET(ctx->ir_base[op1_insn->op1].op3);
|
||||||
|
base_reg = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
|
||||||
|
base_reg_ref = IR_UNUSED;
|
||||||
|
index_reg_ref = insn->op1 * sizeof(ir_ref) + 2;
|
||||||
|
} else {
|
||||||
|
base_reg_ref = insn->op1 * sizeof(ir_ref) + 1;
|
||||||
|
index_reg_ref = insn->op1 * sizeof(ir_ref) + 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case IR_LEA_OB_SI:
|
case IR_LEA_OB_SI:
|
||||||
index_reg_ref = insn->op2 * sizeof(ir_ref) + 1;
|
index_reg_ref = insn->op2 * sizeof(ir_ref) + 1;
|
||||||
@@ -7463,6 +7480,10 @@ static void ir_emit_vload(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
ir_reg fp;
|
ir_reg fp;
|
||||||
ir_mem mem;
|
ir_mem mem;
|
||||||
|
|
||||||
|
if (ctx->use_lists[def].count == 1) {
|
||||||
|
/* dead load */
|
||||||
|
return;
|
||||||
|
}
|
||||||
IR_ASSERT(var_insn->op == IR_VAR);
|
IR_ASSERT(var_insn->op == IR_VAR);
|
||||||
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
|
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
|
||||||
mem = IR_MEM_BO(fp, IR_SPILL_POS_TO_OFFSET(var_insn->op3));
|
mem = IR_MEM_BO(fp, IR_SPILL_POS_TO_OFFSET(var_insn->op3));
|
||||||
@@ -7909,6 +7930,10 @@ static void ir_emit_block_begin(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
|||||||
dasm_State **Dst = &data->dasm_state;
|
dasm_State **Dst = &data->dasm_state;
|
||||||
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
|
||||||
|
|
||||||
|
if (ctx->use_lists[def].count == 1) {
|
||||||
|
/* dead load */
|
||||||
|
return;
|
||||||
|
}
|
||||||
| mov Ra(def_reg), Ra(IR_REG_RSP)
|
| mov Ra(def_reg), Ra(IR_REG_RSP)
|
||||||
|
|
||||||
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
if (IR_REG_SPILLED(ctx->regs[def][0])) {
|
||||||
|
|||||||
Reference in New Issue
Block a user