Skip to content

Commit fe25afe

Browse files
committed
Update IR
IR commit: c407241e1be34ed2ee4f2177842cc527abf25867
1 parent 7d6bb3e commit fe25afe

File tree

4 files changed

+219
-55
lines changed

4 files changed

+219
-55
lines changed

ext/opcache/jit/ir/ir_aarch64.dasc

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,9 @@ int ir_get_target_constraints(ir_ctx *ctx, ir_ref ref, ir_target_constraints *co
518518
insn = &ctx->ir_base[insn->op3];
519519
constraints->tmp_regs[0] = IR_TMP_REG(3, insn->type, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
520520
n = 1;
521+
} else if (ir_rule(ctx, insn->op3) == IR_STATIC_ALLOCA) {
522+
constraints->tmp_regs[0] = IR_TMP_REG(3, IR_ADDR, IR_LOAD_SUB_REF, IR_DEF_SUB_REF);
523+
n = 1;
521524
}
522525
break;
523526
case IR_LOAD_FP:
@@ -919,6 +922,7 @@ binop_fp:
919922
return insn->op;
920923
}
921924
case IR_CALL:
925+
ctx->flags |= IR_USE_FRAME_POINTER;
922926
ctx->flags2 |= IR_HAS_CALLS | IR_16B_FRAME_ALIGNMENT;
923927
return IR_CALL;
924928
case IR_VAR:
@@ -935,7 +939,7 @@ binop_fp:
935939
}
936940
}
937941
ctx->flags |= IR_USE_FRAME_POINTER;
938-
ctx->flags2 |= IR_HAS_ALLOCA;
942+
ctx->flags2 |= IR_HAS_ALLOCA | IR_16B_FRAME_ALIGNMENT;
939943
}
940944
return IR_ALLOCA;
941945
case IR_LOAD:
@@ -3755,7 +3759,10 @@ static void ir_emit_vstore(ir_ctx *ctx, ir_ref ref, ir_insn *insn)
37553759
fp = (ctx->flags & IR_USE_FRAME_POINTER) ? IR_REG_FRAME_POINTER : IR_REG_STACK_POINTER;
37563760
offset = IR_SPILL_POS_TO_OFFSET(var_insn->op3);
37573761
IR_ASSERT(op3_reg != IR_REG_NONE);
3758-
if (IR_REG_SPILLED(op3_reg) && ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
3762+
if (IR_REG_SPILLED(op3_reg)
3763+
&& !IR_IS_CONST_REF(insn->op3)
3764+
&& ir_rule(ctx, insn->op3) != IR_STATIC_ALLOCA
3765+
&& ir_is_same_mem_var(ctx, insn->op3, var_insn->op3)) {
37593766
return; // fake store
37603767
}
37613768
if (IR_REG_SPILLED(op3_reg)) {
@@ -4041,12 +4048,8 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
40414048
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
40424049
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 >= 0);
40434050

4044-
if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
4045-
/* Stack must be 16 byte aligned */
4046-
size = IR_ALIGNED_SIZE(size, 16);
4047-
} else {
4048-
size = IR_ALIGNED_SIZE(size, 8);
4049-
}
4051+
/* Stack must be 16 byte aligned */
4052+
size = IR_ALIGNED_SIZE(size, 16);
40504053
if (aarch64_may_encode_imm12(size)) {
40514054
| sub sp, sp, #size
40524055
} else {
@@ -4057,7 +4060,7 @@ static void ir_emit_alloca(ir_ctx *ctx, ir_ref def, ir_insn *insn)
40574060
ctx->call_stack_size += size;
40584061
}
40594062
} else {
4060-
int32_t alignment = (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) ? 16 : 8;
4063+
int32_t alignment = 16;
40614064
ir_reg op2_reg = ctx->regs[def][2];
40624065
ir_type type = ctx->ir_base[insn->op2].type;
40634066

@@ -4095,18 +4098,14 @@ static void ir_emit_afree(ir_ctx *ctx, ir_ref def, ir_insn *insn)
40954098
IR_ASSERT(!IR_IS_SYM_CONST(val->op));
40964099
IR_ASSERT(IR_IS_TYPE_UNSIGNED(val->type) || val->val.i64 > 0);
40974100

4098-
if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
4099-
/* Stack must be 16 byte aligned */
4100-
size = IR_ALIGNED_SIZE(size, 16);
4101-
} else {
4102-
size = IR_ALIGNED_SIZE(size, 8);
4103-
}
4101+
/* Stack must be 16 byte aligned */
4102+
size = IR_ALIGNED_SIZE(size, 16);
41044103
| add sp, sp, #size
41054104
if (!(ctx->flags & IR_USE_FRAME_POINTER)) {
41064105
ctx->call_stack_size -= size;
41074106
}
41084107
} else {
4109-
// int32_t alignment = (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) ? 16 : 8;
4108+
// int32_t alignment = 16;
41104109
ir_reg op2_reg = ctx->regs[def][2];
41114110
ir_type type = ctx->ir_base[insn->op2].type;
41124111

@@ -5766,7 +5765,6 @@ void ir_fix_stack_frame(ir_ctx *ctx)
57665765
ctx->stack_frame_alignment += sizeof(void*);
57675766
}
57685767
} else if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
5769-
ctx->flags |= IR_USE_FRAME_POINTER;
57705768
/* Stack must be 16 byte aligned */
57715769
if (!(ctx->flags & IR_FUNCTION)) {
57725770
while (IR_ALIGNED_SIZE(ctx->stack_frame_size, 16) != ctx->stack_frame_size) {

ext/opcache/jit/ir/ir_ra.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,20 +1932,33 @@ int ir_coalesce(ir_ctx *ctx)
19321932
IR_ASSERT(ir_op_flags[input_insn->op] & IR_OP_FLAG_COMMUTATIVE);
19331933
if (input_insn->op2 == use
19341934
&& input_insn->op1 != use
1935-
&& (ctx->live_intervals[v1]->use_pos->flags & IR_DEF_REUSES_OP1_REG)
1936-
&& ctx->live_intervals[v2]->end == IR_USE_LIVE_POS_FROM_REF(input)) {
1935+
&& (ctx->live_intervals[v1]->use_pos->flags & IR_DEF_REUSES_OP1_REG)) {
19371936
ir_live_range *r = &ctx->live_intervals[v2]->range;
19381937

1939-
while (r->next) {
1938+
do {
1939+
if (r->end == IR_USE_LIVE_POS_FROM_REF(input)) {
1940+
break;
1941+
}
19401942
r = r->next;
1943+
} while (r);
1944+
if (r) {
1945+
r->end = IR_LOAD_LIVE_POS_FROM_REF(input);
1946+
if (!r->next) {
1947+
ctx->live_intervals[v2]->end = IR_LOAD_LIVE_POS_FROM_REF(input);
1948+
}
1949+
if (ir_vregs_overlap(ctx, v1, v2)) {
1950+
r->end = IR_USE_LIVE_POS_FROM_REF(input);
1951+
if (!r->next) {
1952+
ctx->live_intervals[v2]->end = IR_USE_LIVE_POS_FROM_REF(input);
1953+
}
1954+
} else {
1955+
ir_swap_operands(ctx, input, input_insn);
1956+
IR_ASSERT(!ir_vregs_overlap(ctx, v1, v2));
1957+
ir_vregs_coalesce(ctx, v1, v2, input, use);
1958+
compact = 1;
1959+
continue;
1960+
}
19411961
}
1942-
r->end = IR_LOAD_LIVE_POS_FROM_REF(input);
1943-
ctx->live_intervals[v2]->end = IR_LOAD_LIVE_POS_FROM_REF(input);
1944-
ir_swap_operands(ctx, input, input_insn);
1945-
IR_ASSERT(!ir_vregs_overlap(ctx, v1, v2));
1946-
ir_vregs_coalesce(ctx, v1, v2, input, use);
1947-
compact = 1;
1948-
continue;
19491962
}
19501963
}
19511964
#endif
@@ -2609,14 +2622,11 @@ static int32_t ir_allocate_big_spill_slot(ir_ctx *ctx, int32_t size, ir_reg_allo
26092622
return ir_allocate_small_spill_slot(ctx, size, data);
26102623
}
26112624

2612-
if (ctx->flags2 & IR_16B_FRAME_ALIGNMENT) {
2613-
/* Stack must be 16 byte aligned */
2614-
size = IR_ALIGNED_SIZE(size, 16);
2615-
} else {
2616-
size = IR_ALIGNED_SIZE(size, 8);
2617-
}
2618-
ret = ctx->stack_frame_size;
2619-
ctx->stack_frame_size += size;
2625+
/* Align stack allocated data to 16 byte */
2626+
ctx->flags2 |= IR_16B_FRAME_ALIGNMENT;
2627+
ret = IR_ALIGNED_SIZE(ctx->stack_frame_size, 16);
2628+
size = IR_ALIGNED_SIZE(size, 8);
2629+
ctx->stack_frame_size = ret + size;
26202630

26212631
return ret;
26222632
}

ext/opcache/jit/ir/ir_sccp.c

Lines changed: 160 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -967,6 +967,145 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use)
967967
return ref;
968968
}
969969

970+
static ir_ref ir_ext_const(ir_ctx *ctx, ir_insn *val_insn, ir_op op, ir_type type)
971+
{
972+
ir_val new_val;
973+
974+
switch (val_insn->type) {
975+
default:
976+
IR_ASSERT(0);
977+
case IR_I8:
978+
case IR_U8:
979+
case IR_BOOL:
980+
if (op == IR_SEXT) {
981+
new_val.i64 = (int64_t)val_insn->val.i8;
982+
} else {
983+
new_val.u64 = (uint64_t)val_insn->val.u8;
984+
}
985+
break;
986+
case IR_I16:
987+
case IR_U16:
988+
if (op == IR_SEXT) {
989+
new_val.i64 = (int64_t)val_insn->val.i16;
990+
} else {
991+
new_val.u64 = (uint64_t)val_insn->val.u16;
992+
}
993+
break;
994+
case IR_I32:
995+
case IR_U32:
996+
if (op == IR_SEXT) {
997+
new_val.i64 = (int64_t)val_insn->val.i32;
998+
} else {
999+
new_val.u64 = (uint64_t)val_insn->val.u32;
1000+
}
1001+
break;
1002+
}
1003+
return ir_const(ctx, new_val, type);
1004+
}
1005+
1006+
static ir_ref ir_ext_ref(ir_ctx *ctx, ir_ref var_ref, ir_ref src_ref, ir_op op, ir_type type)
1007+
{
1008+
ir_ref new_ext_ref = ir_emit1(ctx, IR_OPTX(op, type, 1), src_ref);
1009+
1010+
ctx->use_lists = ir_mem_realloc(ctx->use_lists, ctx->insns_count * sizeof(ir_use_list));
1011+
ctx->use_lists[new_ext_ref].count = 0;
1012+
ctx->use_lists[new_ext_ref].refs = IR_UNUSED;
1013+
ir_use_list_add(ctx, new_ext_ref, var_ref);
1014+
if (!IR_IS_CONST_REF(src_ref)) {
1015+
ir_use_list_replace_one(ctx, src_ref, var_ref, new_ext_ref);
1016+
}
1017+
return new_ext_ref;
1018+
}
1019+
1020+
static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bitqueue *worklist)
1021+
{
1022+
ir_type type = insn->type;
1023+
ir_op op = insn->op;
1024+
ir_ref ref = insn->op1;
1025+
ir_insn *phi_insn = &ctx->ir_base[ref];
1026+
ir_insn *op_insn;
1027+
ir_use_list *use_list;
1028+
ir_ref n, *p, use, op_ref;
1029+
1030+
/* Check for simple induction variable in the form: x2 = PHI(loop, x1, x3); x3 = ADD(x2, _); */
1031+
if (phi_insn->op != IR_PHI
1032+
|| phi_insn->inputs_count != 3 /* (2 values) */
1033+
|| ctx->ir_base[phi_insn->op1].op != IR_LOOP_BEGIN) {
1034+
return 0;
1035+
}
1036+
1037+
op_ref = phi_insn->op3;
1038+
op_insn = &ctx->ir_base[op_ref];
1039+
if ((op_insn->op != IR_ADD && op_insn->op != IR_SUB && op_insn->op != IR_MUL)
1040+
|| op_insn->op1 != ref
1041+
|| op_insn->op2 == ref
1042+
|| ctx->use_lists[op_ref].count != 1) {
1043+
return 0;
1044+
}
1045+
1046+
/* Check if we may change the type of the induction variable */
1047+
use_list = &ctx->use_lists[ref];
1048+
n = use_list->count;
1049+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
1050+
use = *p;
1051+
if (use == op_ref || use == ext_ref) {
1052+
continue;
1053+
} else {
1054+
ir_insn *use_insn = &ctx->ir_base[use];
1055+
1056+
if ((use_insn->op >= IR_EQ && use_insn->op <= IR_UGT)
1057+
&& use_insn->op1 == ref
1058+
&& use_insn->op2 != ref) {
1059+
continue;
1060+
} else if (use_insn->op == IR_IF) {
1061+
continue;
1062+
} else {
1063+
return 0;
1064+
}
1065+
}
1066+
}
1067+
1068+
phi_insn->type = insn->type;
1069+
op_insn->type = insn->type;
1070+
1071+
use_list = &ctx->use_lists[ref];
1072+
n = use_list->count;
1073+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
1074+
use = *p;
1075+
if (use == ext_ref) {
1076+
continue;
1077+
} else {
1078+
ir_insn *use_insn = &ctx->ir_base[use];
1079+
1080+
if (use_insn->op == IR_IF) {
1081+
continue;
1082+
}
1083+
IR_ASSERT(((use_insn->op >= IR_EQ && use_insn->op <= IR_UGT)
1084+
|| use_insn->op == IR_ADD || use_insn->op == IR_SUB || use_insn->op == IR_MUL)
1085+
&& use_insn->op1 == ref
1086+
&& use_insn->op2 != ref);
1087+
if (IR_IS_CONST_REF(use_insn->op2)
1088+
&& !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op2].op)) {
1089+
ctx->ir_base[use].op2 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op2], op, type);
1090+
} else {
1091+
ctx->ir_base[use].op2 = ir_ext_ref(ctx, use, use_insn->op2, op, type);
1092+
}
1093+
}
1094+
}
1095+
1096+
ir_sccp_replace_insn2(ctx, ext_ref, ref, worklist);
1097+
1098+
phi_insn = &ctx->ir_base[ref];
1099+
if (IR_IS_CONST_REF(phi_insn->op2)
1100+
&& !IR_IS_SYM_CONST(ctx->ir_base[phi_insn->op2].op)) {
1101+
ctx->ir_base[ref].op2 = ir_ext_const(ctx, &ctx->ir_base[phi_insn->op2], op, type);
1102+
} else {
1103+
ctx->ir_base[ref].op2 = ir_ext_ref(ctx, ref, phi_insn->op2, op, type);
1104+
}
1105+
1106+
return 1;
1107+
}
1108+
9701109
int ir_sccp(ir_ctx *ctx)
9711110
{
9721111
ir_ref i, j, n, *p, use;
@@ -1025,12 +1164,18 @@ int ir_sccp(ir_ctx *ctx)
10251164
}
10261165
if (!may_benefit) {
10271166
IR_MAKE_BOTTOM(i);
1028-
if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC) {
1167+
if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC
1168+
|| insn->op == IR_ZEXT || insn->op == IR_SEXT) {
10291169
ir_bitqueue_add(&worklist2, i);
10301170
}
10311171
} else if (!ir_sccp_fold(ctx, _values, i, insn->opt, insn->op1, insn->op2, insn->op3)) {
10321172
/* not changed */
10331173
continue;
1174+
} else if (_values[i].optx == IR_BOTTOM) {
1175+
if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC
1176+
|| insn->op == IR_ZEXT || insn->op == IR_SEXT) {
1177+
ir_bitqueue_add(&worklist2, i);
1178+
}
10341179
}
10351180
} else {
10361181
IR_MAKE_BOTTOM(i);
@@ -1298,15 +1443,17 @@ int ir_sccp(ir_ctx *ctx)
12981443
ir_ref ref = ir_promote_d2f(ctx, insn->op1, i);
12991444
insn->op1 = ref;
13001445
ir_sccp_replace_insn2(ctx, i, ref, &worklist2);
1446+
break;
13011447
}
13021448
} else {
13031449
if (ir_may_promote_f2d(ctx, insn->op1)) {
13041450
ir_ref ref = ir_promote_f2d(ctx, insn->op1, i);
13051451
insn->op1 = ref;
13061452
ir_sccp_replace_insn2(ctx, i, ref, &worklist2);
1453+
break;
13071454
}
13081455
}
1309-
break;
1456+
goto folding;
13101457
case IR_FP2INT:
13111458
if (ctx->ir_base[insn->op1].type == IR_DOUBLE) {
13121459
if (ir_may_promote_d2f(ctx, insn->op1)) {
@@ -1317,15 +1464,25 @@ int ir_sccp(ir_ctx *ctx)
13171464
insn->op1 = ir_promote_f2d(ctx, insn->op1, i);
13181465
}
13191466
}
1320-
break;
1467+
goto folding;
13211468
case IR_TRUNC:
13221469
if (ir_may_promote_i2i(ctx, insn->type, insn->op1)) {
13231470
ir_ref ref = ir_promote_i2i(ctx, insn->type, insn->op1, i);
13241471
insn->op1 = ref;
13251472
ir_sccp_replace_insn2(ctx, i, ref, &worklist2);
1473+
break;
1474+
}
1475+
goto folding;
1476+
case IR_SEXT:
1477+
case IR_ZEXT:
1478+
if (ir_try_promote_ext(ctx, i, insn, &worklist2)) {
1479+
break;
13261480
}
1481+
goto folding;
1482+
case IR_PHI:
13271483
break;
13281484
default:
1485+
folding:
13291486
ir_sccp_fold2(ctx, i, &worklist2);
13301487
break;
13311488
}

0 commit comments

Comments
 (0)