Skip to content

Commit f016caa

Browse files
committed
Merge IR
IR commit: 1a02c4819f210a1f4548b83850ed7cd5c76c13aa
1 parent 7ae8f93 commit f016caa

File tree

9 files changed

+100
-44
lines changed

9 files changed

+100
-44
lines changed

ext/opcache/jit/ir/ir.c

+16-20
Original file line numberDiff line numberDiff line change
@@ -1294,69 +1294,65 @@ void ir_build_def_use_lists(ir_ctx *ctx)
12941294

12951295
void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref ref)
12961296
{
1297-
ir_ref j, n, *p, *q, use;
1297+
ir_ref n, *p, *q, use;
12981298
ir_use_list *use_list;
1299-
ir_ref skip = 0;
13001299

13011300
IR_ASSERT(from > 0);
13021301
use_list = &ctx->use_lists[from];
13031302
n = use_list->count;
1304-
for (j = 0, p = q = &ctx->use_edges[use_list->refs]; j < n; j++, p++) {
1303+
for (p = q = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
13051304
use = *p;
1306-
if (use == ref) {
1307-
skip++;
1308-
} else {
1305+
if (use != ref) {
13091306
if (p != q) {
13101307
*q = use;
13111308
}
13121309
q++;
13131310
}
13141311
}
1315-
if (skip) {
1316-
use_list->count -= skip;
1312+
if (p != q) {
1313+
use_list->count -= (p - q);
13171314
do {
13181315
*q = IR_UNUSED;
13191316
q++;
1320-
} while (--skip);
1317+
} while (q != p);
13211318
}
13221319
}
13231320

13241321
void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref)
13251322
{
1326-
ir_ref j, n, *p;
1323+
ir_ref n, *p;
13271324
ir_use_list *use_list;
13281325

13291326
IR_ASSERT(from > 0);
13301327
use_list = &ctx->use_lists[from];
13311328
n = use_list->count;
1332-
j = 0;
13331329
p = &ctx->use_edges[use_list->refs];
1334-
while (j < n) {
1330+
while (n > 0) {
13351331
if (*p == ref) {
13361332
use_list->count--;
1337-
j++;
1338-
while (j < n) {
1333+
n--;
1334+
while (n > 0) {
13391335
*p = *(p+1);
13401336
p++;
1341-
j++;
1337+
n--;
13421338
}
13431339
*p = IR_UNUSED;
13441340
break;
13451341
}
13461342
p++;
1347-
j++;
1343+
n--;
13481344
}
13491345
}
13501346

13511347
void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
13521348
{
13531349
ir_use_list *use_list;
1354-
ir_ref i, n, *p;
1350+
ir_ref n, *p;
13551351

13561352
IR_ASSERT(ref > 0);
13571353
use_list = &ctx->use_lists[ref];
13581354
n = use_list->count;
1359-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
1355+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
13601356
if (*p == use) {
13611357
*p = new_use;
13621358
break;
@@ -1367,12 +1363,12 @@ void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use
13671363
void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
13681364
{
13691365
ir_use_list *use_list;
1370-
ir_ref i, n, *p;
1366+
ir_ref n, *p;
13711367

13721368
IR_ASSERT(ref > 0);
13731369
use_list = &ctx->use_lists[ref];
13741370
n = use_list->count;
1375-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
1371+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
13761372
if (*p == use) {
13771373
*p = new_use;
13781374
}

ext/opcache/jit/ir/ir_cfg.c

+18-4
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static void ir_remove_predecessor(ir_ctx *ctx, ir_block *bb, uint32_t from)
328328

329329
static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from)
330330
{
331-
ir_ref i, j, n, k, *p, use;
331+
ir_ref i, j, n, k, *p, *q, use;
332332
ir_insn *use_insn;
333333
ir_use_list *use_list;
334334
ir_bitset life_inputs;
@@ -359,7 +359,7 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from)
359359
use_list = &ctx->use_lists[merge];
360360
if (use_list->count > 1) {
361361
n++;
362-
for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) {
362+
for (k = use_list->count, p = q = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) {
363363
use = *p;
364364
use_insn = &ctx->ir_base[use];
365365
if (use_insn->op == IR_PHI) {
@@ -379,8 +379,22 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from)
379379
for (j = 2; j <= n; j++) {
380380
ir_insn_set_op(use_insn, j, IR_UNUSED);
381381
}
382-
ir_use_list_remove_all(ctx, merge, use);
382+
continue;
383+
}
384+
385+
/*compact use list */
386+
if (p != q){
387+
*q = use;
383388
}
389+
q++;
390+
}
391+
392+
if (p != q) {
393+
use_list->count -= (p - q);
394+
do {
395+
*q = IR_UNUSED; /* clenu-op the removed tail */
396+
q++;
397+
} while (p != q);
384398
}
385399
}
386400
} else {
@@ -389,7 +403,7 @@ static void ir_remove_merge_input(ir_ctx *ctx, ir_ref merge, ir_ref from)
389403
use_list = &ctx->use_lists[merge];
390404
if (use_list->count > 1) {
391405
n++;
392-
for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) {
406+
for (k = use_list->count, p = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) {
393407
use = *p;
394408
use_insn = &ctx->ir_base[use];
395409
if (use_insn->op == IR_PHI) {

ext/opcache/jit/ir/ir_check.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ void ir_consistency_check(void)
4242

4343
static bool ir_check_use_list(const ir_ctx *ctx, ir_ref from, ir_ref to)
4444
{
45-
ir_ref n, j, *p;
45+
ir_ref n, *p;
4646
ir_use_list *use_list = &ctx->use_lists[from];
4747

4848
n = use_list->count;
49-
for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) {
49+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
5050
if (*p == to) {
5151
return 1;
5252
}
@@ -304,9 +304,9 @@ bool ir_check(const ir_ctx *ctx)
304304

305305
if (ctx->use_lists) {
306306
ir_use_list *use_list = &ctx->use_lists[i];
307-
ir_ref count;
307+
ir_ref count, n = use_list->count;
308308

309-
for (j = 0, p = &ctx->use_edges[use_list->refs]; j < use_list->count; j++, p++) {
309+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
310310
use = *p;
311311
if (!ir_check_input_list(ctx, i, use)) {
312312
fprintf(stderr, "ir_base[%d] is in use list of ir_base[%d]\n", use, i);
@@ -347,8 +347,8 @@ bool ir_check(const ir_ctx *ctx)
347347
break;
348348
default:
349349
/* skip data references */
350-
count = use_list->count;
351-
for (j = 0, p = &ctx->use_edges[use_list->refs]; j < use_list->count; j++, p++) {
350+
count = n = use_list->count;
351+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
352352
use = *p;
353353
if (!(ir_op_flags[ctx->ir_base[use].op] & IR_OP_FLAG_CONTROL)) {
354354
count--;

ext/opcache/jit/ir/ir_dump.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ static void ir_dump_dessa_moves(const ir_ctx *ctx, int b, ir_block *bb, FILE *f)
177177
use_list = &ctx->use_lists[succ_bb->start];
178178
k = ir_phi_input_number(ctx, succ_bb, b);
179179

180-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) {
180+
for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) {
181181
use_ref = *p;
182182
use_insn = &ctx->ir_base[use_ref];
183183
if (use_insn->op == IR_PHI) {

ext/opcache/jit/ir/ir_emit.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static ir_reg ir_get_param_reg(const ir_ctx *ctx, ir_ref ref)
161161
}
162162
#endif
163163

164-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) {
164+
for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) {
165165
use = *p;
166166
insn = &ctx->ir_base[use];
167167
if (insn->op == IR_PARAM) {
@@ -917,7 +917,7 @@ static void ir_emit_dessa_moves(ir_ctx *ctx, int b, ir_block *bb)
917917

918918
copies = alloca(use_list->count * sizeof(ir_dessa_copy));
919919

920-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) {
920+
for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) {
921921
ir_ref ref = *p;
922922
ir_insn *insn = &ctx->ir_base[ref];
923923

ext/opcache/jit/ir/ir_ra.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -1901,7 +1901,6 @@ int ir_coalesce(ir_ctx *ctx)
19011901
qsort(list, count, sizeof(ir_coalesce_block), ir_block_cmp);
19021902

19031903
while (count > 0) {
1904-
uint32_t i;
19051904

19061905
count--;
19071906
b = list[count].b;
@@ -1913,7 +1912,7 @@ int ir_coalesce(ir_ctx *ctx)
19131912
k = ir_phi_input_number(ctx, succ_bb, b);
19141913
use_list = &ctx->use_lists[succ_bb->start];
19151914
n = use_list->count;
1916-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
1915+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
19171916
use = *p;
19181917
insn = &ctx->ir_base[use];
19191918
if (insn->op == IR_PHI) {
@@ -2061,7 +2060,7 @@ int ir_coalesce(ir_ctx *ctx)
20612060

20622061
int ir_compute_dessa_moves(ir_ctx *ctx)
20632062
{
2064-
uint32_t b, i, n;
2063+
uint32_t b, n;
20652064
ir_ref j, k, *p, use;
20662065
ir_block *bb;
20672066
ir_use_list *use_list;
@@ -2076,7 +2075,7 @@ int ir_compute_dessa_moves(ir_ctx *ctx)
20762075
if (n > 1) {
20772076
IR_ASSERT(k == ctx->ir_base[bb->start].inputs_count);
20782077
k++;
2079-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < n; i++, p++) {
2078+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
20802079
use = *p;
20812080
insn = &ctx->ir_base[use];
20822081
if (insn->op == IR_PHI) {
@@ -2136,7 +2135,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy)
21362135
len = ir_bitset_len(ctx->vregs_count + 1);
21372136
todo = ir_bitset_malloc(ctx->vregs_count + 1);
21382137

2139-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) {
2138+
for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) {
21402139
ref = *p;
21412140
insn = &ctx->ir_base[ref];
21422141
if (insn->op == IR_PHI) {
@@ -2205,7 +2204,7 @@ int ir_gen_dessa_moves(ir_ctx *ctx, uint32_t b, emit_copy_t emit_copy)
22052204
ir_mem_free(loc);
22062205

22072206
if (have_constants_or_addresses) {
2208-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) {
2207+
for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) {
22092208
ref = *p;
22102209
insn = &ctx->ir_base[ref];
22112210
if (insn->op == IR_PHI) {

ext/opcache/jit/ir/ir_save.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static void ir_save_dessa_moves(const ir_ctx *ctx, int b, ir_block *bb, FILE *f)
5353
use_list = &ctx->use_lists[succ_bb->start];
5454
k = ir_phi_input_number(ctx, succ_bb, b);
5555

56-
for (i = 0, p = &ctx->use_edges[use_list->refs]; i < use_list->count; i++, p++) {
56+
for (i = use_list->count, p = &ctx->use_edges[use_list->refs]; i > 0; p++, i--) {
5757
use_ref = *p;
5858
use_insn = &ctx->ir_base[use_ref];
5959
if (use_insn->op == IR_PHI) {

ext/opcache/jit/ir/ir_sccp.c

+12-2
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(ir_ctx *ctx, ir_insn *_values, ir_bi
667667

668668
use_list = &ctx->use_lists[i];
669669
n = use_list->count;
670-
for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) {
670+
for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) {
671671
use = *p;
672672
IR_ASSERT(use > 0);
673673
use_insn = &ctx->ir_base[use];
@@ -1048,7 +1048,7 @@ static void ir_sccp_remove_unfeasible_merge_inputs(ir_ctx *ctx, ir_insn *_values
10481048
n++;
10491049
use_list = &ctx->use_lists[ref];
10501050
if (use_list->count > 1) {
1051-
for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) {
1051+
for (k = use_list->count, p = &ctx->use_edges[use_list->refs]; k > 0; p++, k--) {
10521052
use = *p;
10531053
use_insn = &ctx->ir_base[use];
10541054
if (use_insn->op == IR_PHI) {
@@ -1715,6 +1715,7 @@ static bool ir_may_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref)
17151715
case IR_OR:
17161716
case IR_AND:
17171717
case IR_XOR:
1718+
case IR_SHL:
17181719
return ctx->use_lists[ref].count == 1 &&
17191720
ir_may_promote_i2i(ctx, type, insn->op1) &&
17201721
ir_may_promote_i2i(ctx, type, insn->op2);
@@ -1773,6 +1774,7 @@ static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use)
17731774
case IR_OR:
17741775
case IR_AND:
17751776
case IR_XOR:
1777+
case IR_SHL:
17761778
if (insn->op1 == insn->op2) {
17771779
insn->op2 = insn->op1 = ir_promote_i2i(ctx, type, insn->op1, ref);
17781780
} else {
@@ -2952,6 +2954,14 @@ static ir_ref ir_iter_optimize_condition(ir_ctx *ctx, ir_ref control, ir_ref con
29522954
{
29532955
ir_insn *condition_insn = &ctx->ir_base[condition];
29542956

2957+
while ((condition_insn->op == IR_BITCAST
2958+
|| condition_insn->op == IR_ZEXT
2959+
|| condition_insn->op == IR_SEXT)
2960+
&& ctx->use_lists[condition].count == 1) {
2961+
condition = condition_insn->op1;
2962+
condition_insn = &ctx->ir_base[condition];
2963+
}
2964+
29552965
if (condition_insn->opt == IR_OPT(IR_NOT, IR_BOOL)) {
29562966
*swap = 1;
29572967
condition = condition_insn->op1;

ext/opcache/jit/ir/ir_x86.dasc

+39-2
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,7 @@ const char *ir_reg_name(int8_t reg, ir_type type)
10101010
_(MOD_PWR2) \
10111011
_(SDIV_PWR2) \
10121012
_(SMOD_PWR2) \
1013+
_(BOOL_NOT) \
10131014
_(BOOL_NOT_INT) \
10141015
_(ABS_INT) \
10151016
_(OP_INT) \
@@ -2223,10 +2224,16 @@ binop_fp:
22232224
ir_match_fuse_load(ctx, insn->op2, ref);
22242225
return IR_MOD_INT;
22252226
case IR_BSWAP:
2227+
IR_ASSERT(IR_IS_TYPE_INT(insn->type));
2228+
return IR_OP_INT;
22262229
case IR_NOT:
22272230
if (insn->type == IR_BOOL) {
2228-
IR_ASSERT(IR_IS_TYPE_INT(ctx->ir_base[insn->op1].type)); // TODO: IR_BOOL_NOT_FP
2229-
return IR_BOOL_NOT_INT;
2231+
if (ctx->ir_base[insn->op1].type == IR_BOOL) {
2232+
return IR_BOOL_NOT;
2233+
} else {
2234+
IR_ASSERT(IR_IS_TYPE_INT(ctx->ir_base[insn->op1].type)); // TODO: IR_BOOL_NOT_FP
2235+
return IR_BOOL_NOT_INT;
2236+
}
22302237
} else {
22312238
IR_ASSERT(IR_IS_TYPE_INT(insn->type));
22322239
return IR_OP_INT;
@@ -5054,6 +5061,33 @@ static void ir_emit_abs_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
50545061
}
50555062
}
50565063

5064+
static void ir_emit_bool_not(ir_ctx *ctx, ir_ref def, ir_insn *insn)
5065+
{
5066+
ir_backend_data *data = ctx->data;
5067+
dasm_State **Dst = &data->dasm_state;
5068+
ir_type type = ctx->ir_base[insn->op1].type;
5069+
ir_ref op1 = insn->op1;
5070+
ir_reg def_reg = IR_REG_NUM(ctx->regs[def][0]);
5071+
ir_reg op1_reg = ctx->regs[def][1];
5072+
5073+
IR_ASSERT(def_reg != IR_REG_NONE);
5074+
5075+
if (op1_reg != IR_REG_NONE && IR_REG_SPILLED(op1_reg)) {
5076+
op1_reg = IR_REG_NUM(op1_reg);
5077+
ir_emit_load(ctx, type, op1_reg, op1);
5078+
}
5079+
5080+
if (def_reg != op1_reg) {
5081+
| mov Rb(def_reg), Rb(op1_reg)
5082+
}
5083+
5084+
| xor Rb(def_reg), 1
5085+
5086+
if (IR_REG_SPILLED(ctx->regs[def][0])) {
5087+
ir_emit_store(ctx, type, def, def_reg);
5088+
}
5089+
}
5090+
50575091
static void ir_emit_bool_not_int(ir_ctx *ctx, ir_ref def, ir_insn *insn)
50585092
{
50595093
ir_backend_data *data = ctx->data;
@@ -10602,6 +10636,9 @@ void *ir_emit_code(ir_ctx *ctx, size_t *size_ptr)
1060210636
case IR_ABS_INT:
1060310637
ir_emit_abs_int(ctx, i, insn);
1060410638
break;
10639+
case IR_BOOL_NOT:
10640+
ir_emit_bool_not(ctx, i, insn);
10641+
break;
1060510642
case IR_BOOL_NOT_INT:
1060610643
ir_emit_bool_not_int(ctx, i, insn);
1060710644
break;

0 commit comments

Comments
 (0)