Skip to content

Commit 8e4363d

Browse files
committed
Update IR
IR commit: 3b35a1fd61b2b72da8a0852549880d2aff391dbe
1 parent bad5d2c commit 8e4363d

File tree

4 files changed

+92
-62
lines changed

4 files changed

+92
-62
lines changed

ext/opcache/jit/ir/ir_cfg.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -549,8 +549,9 @@ int ir_build_dominators_tree(ir_ctx *ctx)
549549
if (bb->predecessors_count == 1) {
550550
uint32_t pred_b = edges[bb->predecessors];
551551

552-
IR_ASSERT(blocks[pred_b].idom > 0);
553-
if (bb->idom != pred_b) {
552+
if (blocks[pred_b].idom <= 0) {
553+
//IR_ASSERT("Wrong blocks order: BB is before its single predecessor");
554+
} else if (bb->idom != pred_b) {
554555
bb->idom = pred_b;
555556
changed = 1;
556557
}
@@ -663,7 +664,7 @@ int ir_build_dominators_tree(ir_ctx *ctx)
663664
if (UNEXPECTED(idom > b)) {
664665
/* In rare cases, LOOP_BEGIN.op1 may be a back-edge. Skip back-edges. */
665666
ctx->flags2 &= ~IR_NO_LOOPS;
666-
IR_ASSERT(k > 1);
667+
IR_ASSERT(k > 1 && "Wrong blocks order: BB is before its single predecessor");
667668
ir_list_push(&worklist, idom);
668669
while (1) {
669670
k--;

ext/opcache/jit/ir/ir_private.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,8 +865,9 @@ ir_ref ir_const_ex(ir_ctx *ctx, ir_val val, uint8_t type, uint32_t optx);
865865

866866
IR_ALWAYS_INLINE bool ir_const_is_true(const ir_insn *v)
867867
{
868-
869-
if (v->type == IR_BOOL) {
868+
if (IR_IS_SYM_CONST(v->op)) {
869+
return 1;
870+
} else if (v->type == IR_BOOL) {
870871
return v->val.b;
871872
} else if (IR_IS_TYPE_INT(v->type)) {
872873
return v->val.i64 != 0;

ext/opcache/jit/ir/ir_sccp.c

Lines changed: 78 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,22 @@ static bool ir_sccp_meet_phi(ir_ctx *ctx, ir_insn *_values, ir_ref i, ir_insn *i
251251
}
252252
}
253253

254+
static bool ir_is_dead_load_ex(ir_ctx *ctx, ir_ref ref, uint32_t flags, ir_insn *insn)
255+
{
256+
if ((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) {
257+
return ctx->use_lists[ref].count == 1;
258+
} else if (insn->op == IR_ALLOCA) {
259+
return ctx->use_lists[ref].count == 1;
260+
}
261+
return 0;
262+
}
263+
254264
static bool ir_is_dead_load(ir_ctx *ctx, ir_ref ref)
255265
{
256266
if (ctx->use_lists[ref].count == 1) {
257-
if ((ir_op_flags[ctx->ir_base[ref].op] & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) {
267+
uint32_t flags = ir_op_flags[ctx->ir_base[ref].op];
268+
269+
if ((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)) {
258270
return 1;
259271
} else if (ctx->ir_base[ref].op == IR_ALLOCA) {
260272
return 1;
@@ -273,6 +285,25 @@ static bool ir_is_dead(ir_ctx *ctx, ir_ref ref)
273285
return 0;
274286
}
275287

288+
static ir_ref ir_find1(ir_ctx *ctx, uint32_t optx, ir_ref op1)
289+
{
290+
IR_ASSERT(!IR_IS_CONST_REF(op1));
291+
292+
ir_use_list *use_list = &ctx->use_lists[op1];
293+
ir_ref *p, n = use_list->count;
294+
295+
for (p = ctx->use_edges + use_list->refs; n > 0; p++, n--) {
296+
ir_ref use = *p;
297+
ir_insn *use_insn = &ctx->ir_base[use];
298+
299+
if (use_insn->optx == optx) {
300+
IR_ASSERT(use_insn->op1 == op1);
301+
return use;
302+
}
303+
}
304+
return IR_UNUSED;
305+
}
306+
276307
static bool ir_sccp_is_true(ir_ctx *ctx, ir_insn *_values, ir_ref a)
277308
{
278309
ir_insn *v = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a];
@@ -285,6 +316,8 @@ static bool ir_sccp_is_equal(ir_ctx *ctx, ir_insn *_values, ir_ref a, ir_ref b)
285316
ir_insn *v1 = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a];
286317
ir_insn *v2 = IR_IS_CONST_REF(b) ? &ctx->ir_base[b] : &_values[b];
287318

319+
IR_ASSERT(!IR_IS_SYM_CONST(v1->op));
320+
IR_ASSERT(!IR_IS_SYM_CONST(v2->op));
288321
return v1->val.u64 == v2->val.u64;
289322
}
290323

@@ -316,10 +349,8 @@ static void ir_sccp_remove_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_bi
316349
*p = IR_UNUSED;
317350
if (input > 0 && _values[input].op == IR_BOTTOM) {
318351
ir_use_list_remove_all(ctx, input, ref);
319-
/* schedule DCE */
320-
if ((IR_IS_FOLDABLE_OP(ctx->ir_base[input].op) && ctx->use_lists[input].count == 0)
321-
|| ((ir_op_flags[ctx->ir_base[input].op] & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)
322-
&& ctx->use_lists[input].count == 1)) {
352+
if (ir_is_dead(ctx, input)) {
353+
/* schedule DCE */
323354
ir_bitqueue_add(worklist, input);
324355
}
325356
}
@@ -340,12 +371,11 @@ static void ir_sccp_remove_insn2(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist)
340371
*p = IR_UNUSED;
341372
if (input > 0) {
342373
ir_use_list_remove_all(ctx, input, ref);
343-
/* schedule DCE */
344-
if ((IR_IS_FOLDABLE_OP(ctx->ir_base[input].op) && ctx->use_lists[input].count == 0)
345-
|| ((ir_op_flags[ctx->ir_base[input].op] & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)
346-
&& ctx->use_lists[input].count == 1)) {
374+
if (ir_is_dead(ctx, input)) {
375+
/* schedule DCE */
347376
ir_bitqueue_add(worklist, input);
348377
} else if (ctx->ir_base[input].op == IR_PHI && ctx->use_lists[input].count == 1) {
378+
/* try to optimize PHI into ABS/MIN/MAX/COND */
349379
ir_bitqueue_add(worklist, ctx->ir_base[input].op1);
350380
}
351381
}
@@ -368,12 +398,11 @@ static void ir_sccp_replace_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_r
368398
*p = IR_UNUSED;
369399
if (input > 0) {
370400
ir_use_list_remove_all(ctx, input, ref);
371-
/* schedule DCE */
372-
if (worklist
373-
&& ((IR_IS_FOLDABLE_OP(ctx->ir_base[input].op) && ctx->use_lists[input].count == 0)
374-
|| ((ir_op_flags[ctx->ir_base[input].op] & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)
375-
&& ctx->use_lists[input].count == 1))) {
376-
ir_bitqueue_add(worklist, input);
401+
if (_values[input].op == IR_BOTTOM) {
402+
if (ir_is_dead(ctx, input)) {
403+
/* schedule DCE */
404+
ir_bitqueue_add(worklist, input);
405+
}
377406
}
378407
}
379408
}
@@ -426,10 +455,11 @@ static void ir_sccp_replace_insn2(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bi
426455
*p = IR_UNUSED;
427456
if (input > 0) {
428457
ir_use_list_remove_all(ctx, input, ref);
429-
/* schedule DCE */
430-
if ((IR_IS_FOLDABLE_OP(ctx->ir_base[input].op) && ctx->use_lists[input].count == 0)
431-
|| ((ir_op_flags[ctx->ir_base[input].op] & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)
432-
&& ctx->use_lists[input].count == 1)) {
458+
if (ir_is_dead(ctx, input)) {
459+
/* schedule DCE */
460+
ir_bitqueue_add(worklist, input);
461+
} else if (ctx->ir_base[input].op == IR_PHI && ctx->use_lists[input].count == 1) {
462+
/* try to optimize PHI into ABS/MIN/MAX/COND */
433463
ir_bitqueue_add(worklist, input);
434464
}
435465
}
@@ -833,6 +863,7 @@ static ir_ref ir_promote_f2d(ir_ctx *ctx, ir_ref ref, ir_ref use)
833863
{
834864
ir_insn *insn = &ctx->ir_base[ref];
835865
uint32_t count;
866+
ir_ref old_ref;
836867

837868
IR_ASSERT(insn->type == IR_FLOAT);
838869
if (IR_IS_CONST_REF(ref)) {
@@ -863,6 +894,15 @@ static ir_ref ir_promote_f2d(ir_ctx *ctx, ir_ref ref, ir_ref use)
863894
}
864895
return insn->op1;
865896
case IR_INT2FP:
897+
old_ref = ir_find1(ctx, IR_OPTX(IR_INT2FP, IR_DOUBLE, 1), insn->op1);
898+
if (old_ref) {
899+
IR_ASSERT(ctx->use_lists[ref].count == 1);
900+
ir_use_list_remove_one(ctx, insn->op1, ref);
901+
CLEAR_USES(ref);
902+
MAKE_NOP(insn);
903+
ir_use_list_add(ctx, old_ref, use);
904+
return old_ref;
905+
}
866906
insn->type = IR_DOUBLE;
867907
return ref;
868908
case IR_NEG:
@@ -1030,36 +1070,28 @@ static ir_ref ir_ext_const(ir_ctx *ctx, ir_insn *val_insn, ir_op op, ir_type typ
10301070
static ir_ref ir_ext_ref(ir_ctx *ctx, ir_ref var_ref, ir_ref src_ref, ir_op op, ir_type type)
10311071
{
10321072
uint32_t optx = IR_OPTX(op, type, 1);
1033-
ir_ref new_ext_ref;
1073+
ir_ref ref;
10341074

10351075
if (!IR_IS_CONST_REF(src_ref)) {
1036-
ir_use_list *use_list = &ctx->use_lists[src_ref];
1037-
ir_ref *p, n = use_list->count;
1038-
1039-
for (p = ctx->use_edges + use_list->refs; n > 0; p++, n--) {
1040-
ir_ref use = *p;
1041-
ir_insn *use_insn = &ctx->ir_base[use];
1042-
1043-
if (use_insn->optx == optx) {
1044-
IR_ASSERT(use_insn->op1 == src_ref);
1045-
ir_use_list_add(ctx, use, var_ref);
1046-
if (!IR_IS_CONST_REF(src_ref)) {
1047-
ir_use_list_remove_one(ctx, src_ref, var_ref);
1048-
}
1049-
return use;
1076+
ref = ir_find1(ctx, optx, src_ref);
1077+
if (ref) {
1078+
ir_use_list_add(ctx, ref, var_ref);
1079+
if (!IR_IS_CONST_REF(src_ref)) {
1080+
ir_use_list_remove_one(ctx, src_ref, var_ref);
10501081
}
1082+
return ref;
10511083
}
10521084
}
10531085

1054-
new_ext_ref = ir_emit1(ctx, optx, src_ref);
1086+
ref = ir_emit1(ctx, optx, src_ref);
10551087
ctx->use_lists = ir_mem_realloc(ctx->use_lists, ctx->insns_count * sizeof(ir_use_list));
1056-
ctx->use_lists[new_ext_ref].count = 0;
1057-
ctx->use_lists[new_ext_ref].refs = IR_UNUSED;
1058-
ir_use_list_add(ctx, new_ext_ref, var_ref);
1088+
ctx->use_lists[ref].count = 0;
1089+
ctx->use_lists[ref].refs = IR_UNUSED;
1090+
ir_use_list_add(ctx, ref, var_ref);
10591091
if (!IR_IS_CONST_REF(src_ref)) {
1060-
ir_use_list_replace_one(ctx, src_ref, var_ref, new_ext_ref);
1092+
ir_use_list_replace_one(ctx, src_ref, var_ref, ref);
10611093
}
1062-
return new_ext_ref;
1094+
return ref;
10631095
}
10641096

10651097
static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bitqueue *worklist)
@@ -1111,10 +1143,9 @@ static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bi
11111143
phi_insn->type = insn->type;
11121144
op_insn->type = insn->type;
11131145

1114-
use_list = &ctx->use_lists[ref];
1115-
n = use_list->count;
1116-
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
1117-
use = *p;
1146+
for (n = 0; n < ctx->use_lists[ref].count; n++) {
1147+
/* "use_lists" may be reallocated by ir_ext_ref() */
1148+
use = ctx->use_edges[ctx->use_lists[ref].refs + n];
11181149
if (use == ext_ref) {
11191150
continue;
11201151
} else {
@@ -2320,9 +2351,7 @@ int ir_sccp(ir_ctx *ctx)
23202351
}
23212352
}
23222353
IR_MAKE_BOTTOM(i);
2323-
} else if (((flags & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)
2324-
|| insn->op == IR_ALLOCA)
2325-
&& ctx->use_lists[i].count == 1) {
2354+
} else if (ir_is_dead_load_ex(ctx, i, flags, insn)) {
23262355
/* dead load */
23272356
_values[i].optx = IR_LOAD;
23282357
} else {
@@ -2430,7 +2459,7 @@ int ir_sccp(ir_ctx *ctx)
24302459
}
24312460
}
24322461
}
2433-
ir_sccp_replace_insn(ctx, _values, i, IR_UNUSED, NULL);
2462+
ir_sccp_replace_insn(ctx, _values, i, IR_UNUSED, &worklist2);
24342463
}
24352464
} else if (value->op == IR_IF) {
24362465
/* remove one way IF/SWITCH */
@@ -2523,10 +2552,7 @@ int ir_sccp(ir_ctx *ctx)
25232552
} else if (insn->op == IR_MERGE) {
25242553
ir_optimize_merge(ctx, i, insn, &worklist2);
25252554
}
2526-
} else if (((ir_op_flags[insn->op] & (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_MASK)) == (IR_OP_FLAG_MEM|IR_OP_FLAG_MEM_LOAD)
2527-
|| insn->op == IR_ALLOCA)
2528-
&& ctx->use_lists[i].count == 1) {
2529-
/* dead load */
2555+
} else if (ir_is_dead_load(ctx, i)) {
25302556
ir_ref next = ctx->use_edges[ctx->use_lists[i].refs];
25312557

25322558
/* remove LOAD from double linked control list */

ext/opcache/jit/ir/ir_x86.dasc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10922,18 +10922,20 @@ void *ir_emit_thunk(ir_code_buffer *code_buffer, void *addr, size_t *size_ptr)
1092210922
void ir_fix_thunk(void *thunk_entry, void *addr)
1092310923
{
1092410924
unsigned char *code = thunk_entry;
10925-
void **addr_ptr;
1092610925

10927-
if (sizeof(void*) == 8) {
10926+
if (sizeof(void*) == 8 && !IR_IS_SIGNED_32BIT(((unsigned char*)addr - (code + 5)))) {
1092810927
int32_t *offset_ptr;
10928+
void **addr_ptr;
1092910929

1093010930
IR_ASSERT(code[0] == 0xff && code[1] == 0x25);
1093110931
offset_ptr = (int32_t*)(code + 2);
1093210932
addr_ptr = (void**)(code + 6 + *offset_ptr);
1093310933
*addr_ptr = addr;
1093410934
} else {
10935-
IR_ASSERT(code[0] == 0xe9);
10936-
addr_ptr = (void**)(code + 1);
10937-
*addr_ptr = (void*)((unsigned char*)addr - (code + 5));
10935+
int32_t *addr_ptr;
10936+
10937+
code[0] = 0xe9;
10938+
addr_ptr = (int32_t*)(code + 1);
10939+
*addr_ptr = (int32_t)(intptr_t)(void*)((unsigned char*)addr - (code + 5));
1093810940
}
1093910941
}

0 commit comments

Comments
 (0)