Skip to content

Commit 7aa8c7e

Browse files
committed
Don't add guards that are not going to be checked
1 parent de7a0df commit 7aa8c7e

File tree

1 file changed

+96
-63
lines changed

1 file changed

+96
-63
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 96 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,15 @@ static zend_always_inline uint32_t zend_jit_trace_type_to_info(zend_uchar type)
345345
SET_STACK_TYPE(stack, EX_VAR_TO_NUM(_var), _type); \
346346
} while (0)
347347

348+
#define ADD_OP_GUARD(_var, _op_type) do { \
349+
if (_var >= 0 && _op_type != IS_UNKNOWN) { \
350+
zend_ssa_var_info *info = &ssa_var_info[_var]; \
351+
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << _op_type)) { \
352+
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(_op_type, info->type); \
353+
} \
354+
} \
355+
} while (0)
356+
348357
#define CHECK_OP_TRACE_TYPE(_var, _ssa_var, op_info, op_type) do { \
349358
if (op_type != IS_UNKNOWN) { \
350359
if ((op_info & MAY_BE_GUARD) != 0 \
@@ -365,6 +374,12 @@ static zend_always_inline uint32_t zend_jit_trace_type_to_info(zend_uchar type)
365374
} \
366375
} while (0)
367376

377+
#define ADD_OP1_TRACE_GUARD() \
378+
ADD_OP_GUARD(tssa->ops[idx].op1_use, op1_type)
379+
#define ADD_OP2_TRACE_GUARD() \
380+
ADD_OP_GUARD(tssa->ops[idx].op2_use, op2_type)
381+
#define ADD_OP1_DATA_TRACE_GUARD() \
382+
ADD_OP_GUARD(tssa->ops[idx+1].op1_use, op3_type)
368383
#define CHECK_OP1_TRACE_TYPE() \
369384
CHECK_OP_TRACE_TYPE(opline->op1.var, ssa_op->op1_use, op1_info, op1_type)
370385
#define CHECK_OP2_TRACE_TYPE() \
@@ -1294,15 +1309,43 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
12941309
}
12951310

12961311
switch (opline->opcode) {
1312+
case ZEND_ASSIGN_OP:
1313+
if (opline->extended_value == ZEND_POW
1314+
|| opline->extended_value == ZEND_DIV) {
1315+
// TODO: check for division by zero ???
1316+
break;
1317+
}
1318+
if (opline->op1_type != IS_CV || opline->result_type != IS_UNUSED) {
1319+
break;
1320+
}
1321+
ADD_OP1_TRACE_GUARD();
1322+
ADD_OP2_TRACE_GUARD();
1323+
break;
12971324
case ZEND_ASSIGN_DIM_OP:
1325+
if (opline->extended_value == ZEND_POW
1326+
|| opline->extended_value == ZEND_DIV) {
1327+
// TODO: check for division by zero ???
1328+
break;
1329+
}
1330+
if (opline->result_type != IS_UNUSED) {
1331+
break;
1332+
}
1333+
/* break missing intentionally */
12981334
case ZEND_ASSIGN_DIM:
1299-
if (tssa->ops[idx+1].op1_use >= 0 && op3_type != IS_UNKNOWN) {
1300-
zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx+1].op1_use];
1301-
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op3_type)) {
1302-
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(op3_type, info->type);
1303-
}
1335+
if (opline->op1_type != IS_CV) {
1336+
break;
13041337
}
1338+
ADD_OP1_DATA_TRACE_GUARD();
13051339
/* break missing intentionally */
1340+
case ZEND_IS_EQUAL:
1341+
case ZEND_IS_NOT_EQUAL:
1342+
case ZEND_IS_SMALLER:
1343+
case ZEND_IS_SMALLER_OR_EQUAL:
1344+
case ZEND_CASE:
1345+
case ZEND_IS_IDENTICAL:
1346+
case ZEND_IS_NOT_IDENTICAL:
1347+
case ZEND_FETCH_DIM_R:
1348+
case ZEND_FETCH_DIM_IS:
13061349
case ZEND_BW_OR:
13071350
case ZEND_BW_AND:
13081351
case ZEND_BW_XOR:
@@ -1315,76 +1358,71 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
13151358
// case ZEND_DIV: // TODO: check for division by zero ???
13161359
case ZEND_CONCAT:
13171360
case ZEND_FAST_CONCAT:
1318-
case ZEND_ASSIGN_OP:
1319-
case ZEND_IS_EQUAL:
1320-
case ZEND_IS_NOT_EQUAL:
1321-
case ZEND_IS_SMALLER:
1322-
case ZEND_IS_SMALLER_OR_EQUAL:
1323-
case ZEND_CASE:
1324-
case ZEND_IS_IDENTICAL:
1325-
case ZEND_IS_NOT_IDENTICAL:
1326-
case ZEND_FETCH_DIM_R:
1327-
case ZEND_FETCH_DIM_IS:
1328-
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
1329-
if (tssa->ops[idx].op2_use >= 0 && op2_type != IS_UNKNOWN) {
1330-
zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx].op2_use];
1331-
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op2_type)) {
1332-
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(op2_type, info->type);
1333-
}
1334-
}
1361+
ADD_OP2_TRACE_GUARD();
13351362
/* break missing intentionally */
1363+
case ZEND_ECHO:
1364+
case ZEND_STRLEN:
1365+
case ZEND_QM_ASSIGN:
1366+
ADD_OP1_TRACE_GUARD();
1367+
break;
13361368
case ZEND_PRE_INC:
13371369
case ZEND_PRE_DEC:
13381370
case ZEND_POST_INC:
13391371
case ZEND_POST_DEC:
1340-
case ZEND_QM_ASSIGN:
1341-
case ZEND_BOOL:
1342-
case ZEND_BOOL_NOT:
1372+
if (opline->op1_type != IS_CV) {
1373+
break;
1374+
}
1375+
ADD_OP1_TRACE_GUARD();
1376+
break;
1377+
case ZEND_ASSIGN:
1378+
if (opline->op1_type != IS_CV) {
1379+
break;
1380+
}
1381+
ADD_OP2_TRACE_GUARD();
1382+
break;
1383+
case ZEND_CAST:
1384+
if (opline->extended_value != op1_type) {
1385+
break;
1386+
}
1387+
ADD_OP1_TRACE_GUARD();
1388+
break;
13431389
case ZEND_JMPZ:
13441390
case ZEND_JMPNZ:
1391+
if (/*opline > op_array->opcodes + ssa->cfg.blocks[b].start && ??? */
1392+
opline->op1_type == IS_TMP_VAR &&
1393+
((opline-1)->result_type & (IS_SMART_BRANCH_JMPZ|IS_SMART_BRANCH_JMPNZ)) != 0) {
1394+
/* smart branch */
1395+
break;
1396+
}
1397+
/* break missing intentionally */
13451398
case ZEND_JMPZNZ:
13461399
case ZEND_JMPZ_EX:
13471400
case ZEND_JMPNZ_EX:
1348-
case ZEND_ECHO:
1349-
case ZEND_STRLEN:
1350-
if (tssa->ops[idx].op1_use >= 0 && op1_type != IS_UNKNOWN) {
1351-
zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx].op1_use];
1352-
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op1_type)) {
1353-
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(op1_type, info->type);
1354-
}
1355-
}
1401+
case ZEND_BOOL:
1402+
case ZEND_BOOL_NOT:
1403+
ADD_OP1_TRACE_GUARD();
13561404
break;
1357-
case ZEND_CAST:
1358-
if (tssa->ops[idx].op1_use >= 0 && op1_type != IS_UNKNOWN) {
1359-
if (opline->extended_value == op1_type) {
1360-
zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx].op1_use];
1361-
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op1_type)) {
1362-
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(op1_type, info->type);
1363-
}
1364-
}
1405+
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
1406+
if ((opline->extended_value & ZEND_ISEMPTY)) {
1407+
// TODO: support for empty() ???
1408+
break;
13651409
}
1410+
ADD_OP1_TRACE_GUARD();
1411+
ADD_OP2_TRACE_GUARD();
13661412
break;
1367-
case ZEND_ASSIGN:
1368-
if (tssa->ops[idx].op2_use >= 0 && op2_type != IS_UNKNOWN) {
1369-
zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx].op2_use];
1370-
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op2_type)) {
1371-
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(op2_type, info->type);
1372-
}
1413+
case ZEND_SEND_VAL_EX:
1414+
case ZEND_SEND_VAR_EX:
1415+
case ZEND_SEND_VAR_NO_REF_EX:
1416+
if (opline->op2.num > MAX_ARG_FLAG_NUM) {
1417+
goto propagate_arg;
13731418
}
1374-
break;
1419+
/* break missing intentionally */
13751420
case ZEND_SEND_VAL:
1376-
case ZEND_SEND_VAL_EX:
13771421
case ZEND_SEND_VAR:
1378-
case ZEND_SEND_VAR_EX:
13791422
case ZEND_SEND_VAR_NO_REF:
1380-
case ZEND_SEND_VAR_NO_REF_EX:
13811423
case ZEND_SEND_FUNC_ARG:
1382-
if (tssa->ops[idx].op1_use >= 0 && op1_type != IS_UNKNOWN) {
1383-
zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx].op1_use];
1384-
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op1_type)) {
1385-
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(op1_type, info->type);
1386-
}
1387-
}
1424+
ADD_OP1_TRACE_GUARD();
1425+
propagate_arg:
13881426
/* Propagate argument type */
13891427
if (frame->call
13901428
&& frame->call->func->type == ZEND_USER_FUNCTION
@@ -1422,12 +1460,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
14221460
}
14231461
break;
14241462
case ZEND_RETURN:
1425-
if (tssa->ops[idx].op1_use >= 0 && op1_type != IS_UNKNOWN) {
1426-
zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx].op1_use];
1427-
if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op1_type)) {
1428-
info->type = MAY_BE_GUARD | zend_jit_trace_type_to_info_ex(op1_type, info->type);
1429-
}
1430-
}
1463+
ADD_OP1_TRACE_GUARD();
14311464
/* Propagate return value types */
14321465
if (opline->op1_type == IS_UNUSED) {
14331466
return_value_info.type = MAY_BE_NULL;

0 commit comments

Comments
 (0)