Skip to content

Commit 75ed209

Browse files
committed
Merge branch 'PHP-8.5'
* PHP-8.5: Update IR (#21594)
2 parents 87b8345 + d6a28fb commit 75ed209

File tree

8 files changed

+93
-46
lines changed

8 files changed

+93
-46
lines changed

ext/opcache/jit/ir/ir.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,24 +1443,6 @@ bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref)
14431443
}
14441444
}
14451445

1446-
static int ir_ref_cmp(const void *p1, const void *p2)
1447-
{
1448-
return *(ir_ref*)p1 - *(ir_ref*)p2;
1449-
}
1450-
1451-
void ir_use_list_sort(ir_ctx *ctx, ir_ref ref)
1452-
{
1453-
ir_use_list *use_list;
1454-
uint32_t n;
1455-
1456-
IR_ASSERT(ref > 0);
1457-
use_list = &ctx->use_lists[ref];
1458-
n = use_list->count;
1459-
if (n > 1) {
1460-
qsort(ctx->use_edges + use_list->refs, n, sizeof(ir_ref), ir_ref_cmp);
1461-
}
1462-
}
1463-
14641446
void ir_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref)
14651447
{
14661448
int i, j, n, *p, use;

ext/opcache/jit/ir/ir_aarch64.dasc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ get_arg_hints:
720720
break;
721721
case IR_PARAM:
722722
constraints->def_reg = ir_get_param_reg(ctx, ref);
723-
flags = 0;
723+
flags = (constraints->def_reg != IR_REG_NONE) ? IR_USE_SHOULD_BE_IN_REG : 0;
724724
break;
725725
case IR_PI:
726726
case IR_PHI:

ext/opcache/jit/ir/ir_builder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ void _ir_TAILCALL_3(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_re
654654
void _ir_TAILCALL_4(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4);
655655
void _ir_TAILCALL_5(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4, ir_ref arg5);
656656
void _ir_TAILCALL_6(ir_ctx *ctx, ir_type type, ir_ref func, ir_ref arg1, ir_ref arg2, ir_ref arg3, ir_ref arg4, ir_ref arg5, ir_ref arg6);
657-
ir_ref _ir_TAILCALL_N(ir_ctx *ctx, ir_type type, ir_ref func, uint32_t count, ir_ref *args);
657+
void _ir_TAILCALL_N(ir_ctx *ctx, ir_type type, ir_ref func, uint32_t count, ir_ref *args);
658658
ir_ref _ir_ALLOCA(ir_ctx *ctx, ir_ref size);
659659
void _ir_AFREE(ir_ctx *ctx, ir_ref size);
660660
ir_ref _ir_VLOAD(ir_ctx *ctx, ir_type type, ir_ref var);

ext/opcache/jit/ir/ir_gcm.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,6 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b)
408408
}
409409

410410
/* Reconstruct IR: Update DEF->USE lists, CFG mapping and etc */
411-
ctx->use_lists = ir_mem_realloc(ctx->use_lists, ctx->insns_count * sizeof(ir_use_list));
412-
ctx->cfg_map = ir_mem_realloc(ctx->cfg_map, ctx->insns_count * sizeof(uint32_t));
413411
n = ctx->use_lists[ref].refs;
414412
for (i = 0; i < clones_count; i++) {
415413
clone = clones[i].ref;
@@ -428,6 +426,7 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b)
428426

429427
uint32_t u = clones[i].use;
430428
while (u != (uint32_t)-1) {
429+
uint32_t src = uses[u].block;
431430
use = uses[u].ref;
432431
ctx->use_edges[n++] = use;
433432
u = uses[u].next;
@@ -437,9 +436,11 @@ static bool ir_split_partially_dead_node(ir_ctx *ctx, ir_ref ref, uint32_t b)
437436
ir_ref k, l = insn->inputs_count;
438437

439438
if (insn->op == IR_PHI) {
440-
for (k = 1; k <= l; k++) {
441-
if (ir_insn_op(insn, k) == ref) {
442-
j = ctx->cfg_map[ir_insn_op(&ctx->ir_base[insn->op1], k - 1)];
439+
ir_insn *merge = &ctx->ir_base[insn->op1];
440+
for (k = 2; k <= l; k++) {
441+
j = ctx->cfg_map[ir_insn_op(merge, k - 1)];
442+
if (j == src) {
443+
IR_ASSERT(ir_insn_op(insn, k) == ref);
443444
if (j != clones[i].block) {
444445
uint32_t dom_depth = ctx->cfg_blocks[clones[i].block].dom_depth;
445446
while (ctx->cfg_blocks[j].dom_depth > dom_depth) {

ext/opcache/jit/ir/ir_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,6 @@ void ir_use_list_remove_one(ir_ctx *ctx, ir_ref def, ir_ref use);
10471047
void ir_use_list_replace_all(ir_ctx *ctx, ir_ref def, ir_ref use, ir_ref new_use);
10481048
void ir_use_list_replace_one(ir_ctx *ctx, ir_ref def, ir_ref use, ir_ref new_use);
10491049
bool ir_use_list_add(ir_ctx *ctx, ir_ref def, ir_ref use);
1050-
void ir_use_list_sort(ir_ctx *ctx, ir_ref def);
10511050

10521051
IR_ALWAYS_INLINE ir_ref ir_next_control(const ir_ctx *ctx, ir_ref ref)
10531052
{
@@ -1100,6 +1099,7 @@ void ir_iter_add_uses(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist);
11001099
void ir_iter_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bitqueue *worklist);
11011100
void ir_iter_update_op(ir_ctx *ctx, ir_ref ref, uint32_t idx, ir_ref new_val, ir_bitqueue *worklist);
11021101
void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist);
1102+
void ir_iter_cleanup(ir_ctx *ctx);
11031103

11041104
/*** IR Basic Blocks info ***/
11051105
#define IR_IS_BB_START(op) \

ext/opcache/jit/ir/ir_ra.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3190,6 +3190,7 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li
31903190
return IR_REG_NONE;
31913191
}
31923192
if (split_pos >= blockPos[reg]) {
3193+
try_next_available_register:
31933194
IR_REGSET_EXCL(available, reg);
31943195
if (IR_REGSET_IS_EMPTY(available)) {
31953196
fprintf(stderr, "LSRA Internal Error: Unsolvable conflict. Allocation is not possible\n");
@@ -3222,31 +3223,33 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li
32223223
IR_LOG_LSRA_CONFLICT(" ---- Conflict with active", other, overlap);
32233224

32243225
split_pos = ir_last_use_pos_before(other, ival->range.start, IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG);
3225-
if (split_pos == 0) {
3226-
split_pos = ival->range.start;
3227-
}
3228-
split_pos = ir_find_optimal_split_position(ctx, other, split_pos, ival->range.start, 1);
3229-
if (split_pos > other->range.start) {
3230-
child = ir_split_interval_at(ctx, other, split_pos);
3231-
if (prev) {
3232-
prev->list_next = other->list_next;
3226+
if (split_pos) {
3227+
split_pos = ir_find_optimal_split_position(ctx, other, split_pos, ival->range.start, 1);
3228+
if (split_pos > other->range.start) {
3229+
child = ir_split_interval_at(ctx, other, split_pos);
3230+
if (prev) {
3231+
prev->list_next = other->list_next;
3232+
} else {
3233+
*active = other->list_next;
3234+
}
3235+
IR_LOG_LSRA(" ---- Finish", other, "");
32333236
} else {
3234-
*active = other->list_next;
3237+
goto try_next_available_register;
32353238
}
3236-
IR_LOG_LSRA(" ---- Finish", other, "");
32373239
} else {
32383240
child = other;
3239-
other->reg = IR_REG_NONE;
3240-
if (prev) {
3241-
prev->list_next = other->list_next;
3242-
} else {
3243-
*active = other->list_next;
3244-
}
3245-
IR_LOG_LSRA(" ---- Spill and Finish", other, " (it must not be in reg)");
32463241
}
32473242

32483243
split_pos = ir_first_use_pos_after(child, ival->range.start, IR_USE_MUST_BE_IN_REG | IR_USE_SHOULD_BE_IN_REG) - 1; // TODO: ???
32493244
if (split_pos > child->range.start && split_pos < child->end) {
3245+
if (child == other) {
3246+
other->reg = IR_REG_NONE;
3247+
if (prev) {
3248+
prev->list_next = other->list_next;
3249+
} else {
3250+
*active = other->list_next;
3251+
}
3252+
}
32503253
ir_live_pos opt_split_pos = ir_find_optimal_split_position(ctx, child, ival->range.start, split_pos, 1);
32513254
if (opt_split_pos > child->range.start) {
32523255
split_pos = opt_split_pos;
@@ -3259,6 +3262,8 @@ static ir_reg ir_allocate_blocked_reg(ir_ctx *ctx, ir_live_interval *ival, ir_li
32593262
// TODO: this may cause endless loop
32603263
ir_add_to_unhandled(unhandled, child);
32613264
IR_LOG_LSRA(" ---- Queue", child, "");
3265+
} else {
3266+
goto try_next_available_register;
32623267
}
32633268
}
32643269
break;

ext/opcache/jit/ir/ir_sccp.c

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(const ir_ctx *ctx, ir_sccp_val *_val
603603
bool may_benefit = 0;
604604
bool has_top = 0;
605605

606-
if (_values[i].op != IR_TOP) {
606+
if (_values[i].op != IR_TOP || insn->op == IR_COPY) {
607607
may_benefit = 1;
608608
}
609609

@@ -987,6 +987,7 @@ static void ir_sccp_remove_if(ir_ctx *ctx, const ir_sccp_val *_values, ir_ref re
987987
insn->optx = IR_OPTX(IR_END, IR_VOID, 1);
988988
next_insn = &ctx->ir_base[dst];
989989
next_insn->op = IR_BEGIN;
990+
next_insn->op2 = IR_UNUSED;
990991
}
991992
}
992993

@@ -2726,7 +2727,16 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re
27262727
}
27272728

27282729
return 1;
2729-
} else if (cond->op != IR_OVERFLOW && insn->op2 <= cond_ref && insn->op3 <= cond_ref) {
2730+
} else if (insn->op2 <= cond_ref && insn->op3 <= cond_ref
2731+
&& cond->op != IR_OVERFLOW
2732+
// TODO: temporary disable IF-conversion for RLOAD.
2733+
// We don't track anti-dependencies in GCM and Local Scheduling.
2734+
// As result COND may be scheduled below the following RSTORE.
2735+
// See: https://github.com/dstogov/ir/issues/132
2736+
&& cond->op != IR_RLOAD
2737+
&& !((cond->op >= IR_EQ && cond->op <= IR_UNORDERED)
2738+
&& ((!IR_IS_CONST_REF(cond->op1) && ctx->ir_base[cond->op1].op == IR_RLOAD)
2739+
|| (!IR_IS_CONST_REF(cond->op2) && ctx->ir_base[cond->op2].op == IR_RLOAD)))) {
27302740
/* COND
27312741
*
27322742
* prev prev
@@ -2968,9 +2978,11 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue
29682978

29692979
if_false->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1);
29702980
if_false->op1 = end1_ref;
2981+
if_false->op2 = IR_UNUSED;
29712982

29722983
if_true->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1);
29732984
if_true->op1 = end2_ref;
2985+
if_true->op2 = IR_UNUSED;
29742986

29752987
ir_bitqueue_add(worklist, if_false_ref);
29762988
ir_bitqueue_add(worklist, if_true_ref);
@@ -3008,6 +3020,7 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue
30083020

30093021
if_true->optx = IR_BEGIN;
30103022
if_true->op1 = IR_UNUSED;
3023+
if_true->op2 = IR_UNUSED;
30113024

30123025
ctx->flags2 &= ~IR_CFG_REACHABLE;
30133026

@@ -3157,9 +3170,11 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu
31573170

31583171
if_false->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1);
31593172
if_false->op1 = end1_ref;
3173+
if_false->op2 = IR_UNUSED;
31603174

31613175
if_true->optx = IR_OPTX(IR_BEGIN, IR_VOID, 1);
31623176
if_true->op1 = end2_ref;
3177+
if_true->op2 = IR_UNUSED;
31633178

31643179
ir_bitqueue_add(worklist, if_false_ref);
31653180
ir_bitqueue_add(worklist, if_true_ref);
@@ -3201,6 +3216,7 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu
32013216

32023217
if_true->optx = IR_BEGIN;
32033218
if_true->op1 = IR_UNUSED;
3219+
if_true->op2 = IR_UNUSED;
32043220

32053221
ctx->flags2 &= ~IR_CFG_REACHABLE;
32063222

@@ -3487,7 +3503,9 @@ static void ir_iter_optimize_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu
34873503
if_true = &ctx->ir_base[if_true_ref];
34883504
if_false = &ctx->ir_base[if_false_ref];
34893505
if_true->op = IR_BEGIN;
3506+
if_true->op2 = IR_UNUSED;
34903507
if_false->op = IR_BEGIN;
3508+
if_false->op2 = IR_UNUSED;
34913509
if (ir_ref_is_true(ctx, condition)) {
34923510
if_false->op1 = IR_UNUSED;
34933511
ir_use_list_remove_one(ctx, ref, if_false_ref);
@@ -3750,6 +3768,47 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist)
37503768
}
37513769
}
37523770

3771+
void ir_iter_cleanup(ir_ctx *ctx)
3772+
{
3773+
ir_bitqueue iter_worklist;
3774+
ir_bitqueue cfg_worklist;
3775+
ir_ref i, n;
3776+
ir_insn *insn;
3777+
3778+
ir_bitqueue_init(&cfg_worklist, ctx->insns_count);
3779+
ir_bitqueue_init(&iter_worklist, ctx->insns_count);
3780+
3781+
/* Remove unused nodes */
3782+
for (i = IR_UNUSED + 1, insn = ctx->ir_base + i; i < ctx->insns_count;) {
3783+
if (IR_IS_FOLDABLE_OP(insn->op)) {
3784+
if (insn->op != IR_NOP && ctx->use_lists[i].count == 0) {
3785+
ir_iter_remove_insn(ctx, i, &iter_worklist);
3786+
}
3787+
} else if (insn->op == IR_IF || insn->op == IR_MERGE) {
3788+
ir_bitqueue_add(&cfg_worklist, i);
3789+
}
3790+
n = insn->inputs_count;
3791+
n = ir_insn_inputs_to_len(n);
3792+
i += n;
3793+
insn += n;
3794+
}
3795+
3796+
while ((i = ir_bitqueue_pop(&iter_worklist)) >= 0) {
3797+
insn = &ctx->ir_base[i];
3798+
if (IR_IS_FOLDABLE_OP(insn->op)) {
3799+
if (ctx->use_lists[i].count == 0) {
3800+
ir_iter_remove_insn(ctx, i, &iter_worklist);
3801+
}
3802+
}
3803+
}
3804+
3805+
/* Cleanup Control Flow */
3806+
ir_iter_opt(ctx, &cfg_worklist);
3807+
3808+
ir_bitqueue_free(&iter_worklist);
3809+
ir_bitqueue_free(&cfg_worklist);
3810+
}
3811+
37533812
int ir_sccp(ir_ctx *ctx)
37543813
{
37553814
ir_bitqueue sccp_worklist, iter_worklist;

ext/opcache/jit/ir/ir_x86.dasc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,7 @@ get_arg_hints:
16661666
break;
16671667
case IR_PARAM:
16681668
constraints->def_reg = ir_get_param_reg(ctx, ref);
1669-
flags = 0;
1669+
flags = (constraints->def_reg != IR_REG_NONE) ? IR_USE_SHOULD_BE_IN_REG : 0;
16701670
break;
16711671
case IR_PI:
16721672
case IR_PHI:

0 commit comments

Comments
 (0)