Lines Matching refs:ssa

191 static bool zend_ssa_is_last_use(const zend_op_array *op_array, const zend_ssa *ssa, int var, int u…  in zend_ssa_is_last_use()  argument
195 if (ssa->vars[var].phi_use_chain) { in zend_ssa_is_last_use()
196 zend_ssa_phi *phi = ssa->vars[var].phi_use_chain; in zend_ssa_is_last_use()
198 if (!ssa->vars[phi->ssa_var].no_val) { in zend_ssa_is_last_use()
201 phi = zend_ssa_next_use_phi(ssa, var, phi); in zend_ssa_is_last_use()
205 if (ssa->cfg.blocks[ssa->cfg.map[use]].loop_header > 0 in zend_ssa_is_last_use()
206 || (ssa->cfg.blocks[ssa->cfg.map[use]].flags & ZEND_BB_LOOP_HEADER)) { in zend_ssa_is_last_use()
207 int b = ssa->cfg.map[use]; in zend_ssa_is_last_use()
208 int prev_use = ssa->vars[var].use_chain; in zend_ssa_is_last_use()
211 if (b != ssa->cfg.map[prev_use] in zend_ssa_is_last_use()
212 && dominates(ssa->cfg.blocks, b, ssa->cfg.map[prev_use]) in zend_ssa_is_last_use()
213 && !zend_ssa_is_no_val_use(op_array->opcodes + prev_use, ssa->ops + prev_use, var)) { in zend_ssa_is_last_use()
216 prev_use = zend_ssa_next_use(ssa->ops, var, prev_use); in zend_ssa_is_last_use()
220 next_use = zend_ssa_next_use(ssa->ops, var, use); in zend_ssa_is_last_use()
223 } else if (zend_ssa_is_no_val_use(op_array->opcodes + next_use, ssa->ops + next_use, var)) { in zend_ssa_is_last_use()
331 …call_info *call_info, uint32_t b, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op … in zend_jit_needs_call_chain() argument
388 if (zend_may_throw(opline, ssa_op, op_array, ssa)) { in zend_jit_needs_call_chain()
410 if (zend_may_throw(opline, ssa_op, op_array, ssa)) { in zend_jit_needs_call_chain()
460 if (end - op_array->opcodes >= ssa->cfg.blocks[b].start + ssa->cfg.blocks[b].len) { in zend_jit_needs_call_chain()
475 if (!end || end - op_array->opcodes >= ssa->cfg.blocks[b].start + ssa->cfg.blocks[b].len) { in zend_jit_needs_call_chain()
502 if (zend_may_throw(opline, ssa_op, op_array, ssa)) { in zend_jit_needs_call_chain()
514 static uint32_t skip_valid_arguments(const zend_op_array *op_array, zend_ssa *ssa, const zend_call_… in skip_valid_arguments() argument
527 zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; in skip_valid_arguments()
541 static uint32_t zend_ssa_cv_info(const zend_op_array *op_array, zend_ssa *ssa, uint32_t var) in zend_ssa_cv_info() argument
545 if (ssa->vars && ssa->var_info) { in zend_ssa_cv_info()
546 info = ssa->var_info[var].type; in zend_ssa_cv_info()
547 for (j = op_array->last_var; j < ssa->vars_count; j++) { in zend_ssa_cv_info()
548 if (ssa->vars[j].var == var) { in zend_ssa_cv_info()
549 info |= ssa->var_info[j].type; in zend_ssa_cv_info()
560 for (j = 0; j < ssa->cfg.blocks_count; j++) { in zend_ssa_cv_info()
561 if ((ssa->cfg.blocks[j].flags & ZEND_BB_REACHABLE) && in zend_ssa_cv_info()
562 ssa->cfg.blocks[j].len > 0) { in zend_ssa_cv_info()
563 … const zend_op *opline = op_array->opcodes + ssa->cfg.blocks[j].start + ssa->cfg.blocks[j].len - 1; in zend_ssa_cv_info()
731 ssa->var_info && \
733 ssa->var_info[(ssa_op)->opN##_use].has_range) ? \
734 &ssa->var_info[(ssa_op)->opN##_use].range : NULL)
918 zend_ssa *ssa, in dasm_link_and_encode() argument
933 if (rt_opline && ssa && ssa->cfg.map) { in dasm_link_and_encode()
937 int b = ssa->cfg.map[rt_opline - op_array->opcodes]; in dasm_link_and_encode()
942 if (!(ssa->cfg.blocks[b].flags & (ZEND_BB_START|ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY))) { in dasm_link_and_encode()
944 zend_jit_label(dasm_state, ssa->cfg.blocks_count + b); in dasm_link_and_encode()
952 for (i = 0; i < ssa->vars_count; i++) { in dasm_link_and_encode()
959 if (!zend_jit_load_var(dasm_state, ssa->var_info[i].type, ssa->vars[i].var, ival->reg)) { in dasm_link_and_encode()
1018 if (op_array && ssa) { in dasm_link_and_encode()
1021 for (b = 0; b < ssa->cfg.blocks_count; b++) { in dasm_link_and_encode()
1025 if (ssa->cfg.blocks[b].flags & (ZEND_BB_START|ZEND_BB_ENTRY|ZEND_BB_RECV_ENTRY)) { in dasm_link_and_encode()
1027 zend_op *opline = op_array->opcodes + ssa->cfg.blocks[b].start; in dasm_link_and_encode()
1028 int offset = dasm_getpclabel(dasm_state, ssa->cfg.blocks_count + b); in dasm_link_and_encode()
1035 if (rt_opline && ssa && ssa->cfg.map) { in dasm_link_and_encode()
1036 int b = ssa->cfg.map[rt_opline - op_array->opcodes]; in dasm_link_and_encode()
1038 int offset = dasm_getpclabel(dasm_state, ssa->cfg.blocks_count + b); in dasm_link_and_encode()
1061 &ssa->cfg, in dasm_link_and_encode()
1073 ssa ? &ssa->cfg : NULL, in dasm_link_and_encode()
1134 …low(const zend_op *opline, const zend_ssa_op *ssa_op, const zend_op_array *op_array, zend_ssa *ssa) in zend_may_overflow() argument
1139 if (!ssa->ops || !ssa->var_info) { in zend_may_overflow()
1147 || !ssa->var_info[res].has_range in zend_may_overflow()
1148 || ssa->var_info[res].range.overflow) { in zend_may_overflow()
1162 || !ssa->var_info[res].has_range in zend_may_overflow()
1163 || ssa->var_info[res].range.underflow) { in zend_may_overflow()
1176 || !ssa->var_info[res].has_range in zend_may_overflow()
1177 || ssa->var_info[res].range.underflow) { in zend_may_overflow()
1188 || !ssa->var_info[res].has_range in zend_may_overflow()
1189 || ssa->var_info[res].range.overflow) { in zend_may_overflow()
1203 || !ssa->var_info[res].has_range in zend_may_overflow()
1204 || ssa->var_info[res].range.underflow) { in zend_may_overflow()
1215 || !ssa->var_info[res].has_range in zend_may_overflow()
1216 || ssa->var_info[res].range.overflow) { in zend_may_overflow()
1230 !ssa->var_info[res].has_range || in zend_may_overflow()
1231 ssa->var_info[res].range.underflow || in zend_may_overflow()
1232 ssa->var_info[res].range.overflow); in zend_may_overflow()
1237 || !ssa->var_info[res].has_range in zend_may_overflow()
1238 || ssa->var_info[res].range.underflow) { in zend_may_overflow()
1249 || !ssa->var_info[res].has_range in zend_may_overflow()
1250 || ssa->var_info[res].range.overflow) { in zend_may_overflow()
1264 || !ssa->var_info[res].has_range in zend_may_overflow()
1265 || ssa->var_info[res].range.underflow) { in zend_may_overflow()
1276 || !ssa->var_info[res].has_range in zend_may_overflow()
1277 || ssa->var_info[res].range.overflow) { in zend_may_overflow()
1291 !ssa->var_info[res].has_range || in zend_may_overflow()
1292 ssa->var_info[res].range.underflow || in zend_may_overflow()
1293 ssa->var_info[res].range.overflow); in zend_may_overflow()
1327 …c int zend_jit_op_array_analyze1(const zend_op_array *op_array, zend_script *script, zend_ssa *ssa) in zend_jit_op_array_analyze1() argument
1329 if (zend_jit_build_cfg(op_array, &ssa->cfg) != SUCCESS) { in zend_jit_op_array_analyze1()
1335 if ((ssa->cfg.flags & ZEND_FUNC_HAS_EXTENDED_INFO)) { in zend_jit_op_array_analyze1()
1342 ssa->cfg.flags |= ZEND_FUNC_INDIRECT_VAR_ACCESS; in zend_jit_op_array_analyze1()
1346 && ssa->cfg.blocks in zend_jit_op_array_analyze1()
1349 && !(ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS)) { in zend_jit_op_array_analyze1()
1350 …a(&CG(arena), script, op_array, ZEND_SSA_RC_INFERENCE | ZEND_SSA_USE_CV_RESULTS, ssa) != SUCCESS) { in zend_jit_op_array_analyze1()
1354 zend_ssa_compute_use_def_chains(&CG(arena), op_array, ssa); in zend_jit_op_array_analyze1()
1356 zend_ssa_find_false_dependencies(op_array, ssa); in zend_jit_op_array_analyze1()
1358 zend_ssa_find_sccs(op_array, ssa); in zend_jit_op_array_analyze1()
1364 …ray_analyze2(const zend_op_array *op_array, zend_script *script, zend_ssa *ssa, uint32_t optimizat… in zend_jit_op_array_analyze2() argument
1367 && ssa->cfg.blocks in zend_jit_op_array_analyze2()
1370 && !(ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS)) { in zend_jit_op_array_analyze2()
1371 if (zend_ssa_inference(&CG(arena), op_array, script, ssa, in zend_jit_op_array_analyze2()
1621 static int *zend_jit_compute_block_order_int(zend_ssa *ssa, int n, int *block_order) in zend_jit_compute_block_order_int() argument
1623 zend_basic_block *b = ssa->cfg.blocks + n; in zend_jit_compute_block_order_int()
1631 b = ssa->cfg.blocks + n; in zend_jit_compute_block_order_int()
1635 block_order = zend_jit_compute_block_order_int(ssa, n, block_order); in zend_jit_compute_block_order_int()
1642 static int zend_jit_compute_block_order(zend_ssa *ssa, int *block_order) in zend_jit_compute_block_order() argument
1644 int *end = zend_jit_compute_block_order_int(ssa, 0, block_order); in zend_jit_compute_block_order()
1649 static bool zend_jit_in_loop(zend_ssa *ssa, int header, zend_basic_block *b) in zend_jit_in_loop() argument
1655 b = ssa->cfg.blocks + b->loop_header; in zend_jit_in_loop()
1660 static void zend_jit_compute_loop_body(zend_ssa *ssa, int header, int n, zend_bitset loop_body) in zend_jit_compute_loop_body() argument
1662 zend_basic_block *b = ssa->cfg.blocks + n; in zend_jit_compute_loop_body()
1674 b = ssa->cfg.blocks + n; in zend_jit_compute_loop_body()
1675 if (zend_jit_in_loop(ssa, header, b)) { in zend_jit_compute_loop_body()
1679 zend_jit_compute_loop_body(ssa, header, n, loop_body); in zend_jit_compute_loop_body()
1708 static int zend_jit_compute_liveness(const zend_op_array *op_array, zend_ssa *ssa, zend_bitset cand… in zend_jit_compute_liveness() argument
1719 set_size = zend_bitset_len(ssa->vars_count); in zend_jit_compute_liveness()
1721 ZEND_MM_ALIGNED_SIZE(ssa->vars_count * sizeof(zend_lifetime_interval*)) + in zend_jit_compute_liveness()
1722 ZEND_MM_ALIGNED_SIZE((set_size * ssa->cfg.blocks_count) * ZEND_BITSET_ELM_SIZE) + in zend_jit_compute_liveness()
1726 ZEND_MM_ALIGNED_SIZE(ssa->cfg.blocks_count * sizeof(int)); in zend_jit_compute_liveness()
1733 …live_in = (zend_bitset)((char*)intervals + ZEND_MM_ALIGNED_SIZE(ssa->vars_count * sizeof(zend_life… in zend_jit_compute_liveness()
1734 …live = (zend_bitset)((char*)live_in + ZEND_MM_ALIGNED_SIZE((set_size * ssa->cfg.blocks_count) * ZE… in zend_jit_compute_liveness()
1739 memset(intervals, 0, ssa->vars_count * sizeof(zend_lifetime_interval*)); in zend_jit_compute_liveness()
1740 zend_bitset_clear(live_in, set_size * ssa->cfg.blocks_count); in zend_jit_compute_liveness()
1746 for (l = zend_jit_compute_block_order(ssa, block_order) - 1; l >= 0; l--) { in zend_jit_compute_liveness()
1750 b = ssa->cfg.blocks + i; in zend_jit_compute_liveness()
1760 for (phi = ssa->blocks[succ].phis; phi; phi = phi->next) { in zend_jit_compute_liveness()
1761 if (ssa->vars[phi->ssa_var].no_val) { in zend_jit_compute_liveness()
1771 for (k = 0; k < ssa->cfg.blocks[succ].predecessors_count; k++) { in zend_jit_compute_liveness()
1772 if (ssa->cfg.predecessors[ssa->cfg.blocks[succ].predecessor_offset + k] == i) { in zend_jit_compute_liveness()
1799 op = ssa->ops + n; in zend_jit_compute_liveness()
1860 for (phi = ssa->blocks[i].phis; phi; phi = phi->next) { in zend_jit_compute_liveness()
1868 for (i = ssa->cfg.blocks_count - 1; i >= 0; i--) { in zend_jit_compute_liveness()
1869 zend_basic_block *b = ssa->cfg.blocks + i; in zend_jit_compute_liveness()
1879 zend_jit_compute_loop_body(ssa, i, i, loop_body); in zend_jit_compute_liveness()
1903 for (i = 0; i < ssa->vars_count; i++) { in zend_jit_compute_liveness()
1907 if (ssa->vars[i].definition_phi) { in zend_jit_compute_liveness()
1908 zend_ssa_phi *phi = ssa->vars[i].definition_phi; in zend_jit_compute_liveness()
1916 for (k = 0; k < ssa->cfg.blocks[phi->block].predecessors_count; k++) { in zend_jit_compute_liveness()
1919 if (ssa->vars[src].definition_phi in zend_jit_compute_liveness()
1920 && ssa->vars[src].definition_phi->pi >= 0 in zend_jit_compute_liveness()
1921 && phi->block == ssa->vars[src].definition_phi->block) { in zend_jit_compute_liveness()
1923 src = ssa->vars[src].definition_phi->sources[0]; in zend_jit_compute_liveness()
1934 for (i = 0; i < ssa->vars_count; i++) { in zend_jit_compute_liveness()
1937 if (ssa->vars[i].definition >= 0) { in zend_jit_compute_liveness()
1938 uint32_t line = ssa->vars[i].definition; in zend_jit_compute_liveness()
1945 if (ssa->ops[line].op1_use >= 0 && in zend_jit_compute_liveness()
1946 intervals[ssa->ops[line].op1_use] && in zend_jit_compute_liveness()
1947 (i == ssa->ops[line].op1_def || in zend_jit_compute_liveness()
1948 (i == ssa->ops[line].result_def && in zend_jit_compute_liveness()
1949 (ssa->ops[line].op1_def < 0 || in zend_jit_compute_liveness()
1950 !intervals[ssa->ops[line].op1_def])))) { in zend_jit_compute_liveness()
1951 zend_jit_add_hint(intervals, i, ssa->ops[line].op1_use); in zend_jit_compute_liveness()
1957 if (i == ssa->ops[line].op1_def && in zend_jit_compute_liveness()
1958 ssa->ops[line].op1_use >= 0 && in zend_jit_compute_liveness()
1959 intervals[ssa->ops[line].op1_use]) { in zend_jit_compute_liveness()
1960 zend_jit_add_hint(intervals, i, ssa->ops[line].op1_use); in zend_jit_compute_liveness()
1964 if (ssa->ops[line].op2_use >= 0 && in zend_jit_compute_liveness()
1965 intervals[ssa->ops[line].op2_use] && in zend_jit_compute_liveness()
1966 (i == ssa->ops[line].op2_def || in zend_jit_compute_liveness()
1967 (i == ssa->ops[line].op1_def && in zend_jit_compute_liveness()
1968 (ssa->ops[line].op2_def < 0 || in zend_jit_compute_liveness()
1969 !intervals[ssa->ops[line].op2_def])) || in zend_jit_compute_liveness()
1970 (i == ssa->ops[line].result_def && in zend_jit_compute_liveness()
1971 (ssa->ops[line].op2_def < 0 || in zend_jit_compute_liveness()
1972 !intervals[ssa->ops[line].op2_def]) && in zend_jit_compute_liveness()
1973 (ssa->ops[line].op1_def < 0 || in zend_jit_compute_liveness()
1974 !intervals[ssa->ops[line].op1_def])))) { in zend_jit_compute_liveness()
1975 zend_jit_add_hint(intervals, i, ssa->ops[line].op2_use); in zend_jit_compute_liveness()
1984 if (i == ssa->ops[line].result_def) { in zend_jit_compute_liveness()
1985 if (ssa->ops[line].op1_use >= 0 && in zend_jit_compute_liveness()
1986 intervals[ssa->ops[line].op1_use] && in zend_jit_compute_liveness()
1987 ssa->ops[line].op1_use_chain < 0 && in zend_jit_compute_liveness()
1988 !ssa->vars[ssa->ops[line].op1_use].phi_use_chain && in zend_jit_compute_liveness()
1989 (ssa->var_info[i].type & MAY_BE_ANY) == in zend_jit_compute_liveness()
1990 (ssa->var_info[ssa->ops[line].op1_use].type & MAY_BE_ANY)) { in zend_jit_compute_liveness()
1991 zend_jit_add_hint(intervals, i, ssa->ops[line].op1_use); in zend_jit_compute_liveness()
1993 ssa->ops[line].op2_use >= 0 && in zend_jit_compute_liveness()
1994 intervals[ssa->ops[line].op2_use] && in zend_jit_compute_liveness()
1995 ssa->ops[line].op2_use_chain < 0 && in zend_jit_compute_liveness()
1996 !ssa->vars[ssa->ops[line].op2_use].phi_use_chain && in zend_jit_compute_liveness()
1997 (ssa->var_info[i].type & MAY_BE_ANY) == in zend_jit_compute_liveness()
1998 (ssa->var_info[ssa->ops[line].op2_use].type & MAY_BE_ANY)) { in zend_jit_compute_liveness()
1999 zend_jit_add_hint(intervals, i, ssa->ops[line].op2_use); in zend_jit_compute_liveness()
2009 *list = zend_jit_sort_intervals(intervals, ssa->vars_count); in zend_jit_compute_liveness()
2076 …_reg(const zend_op_array *op_array, const zend_op **ssa_opcodes, zend_ssa *ssa, zend_lifetime_inte… in zend_jit_try_allocate_free_reg() argument
2086 if ((ssa->var_info[current->ssa_var].type & MAY_BE_ANY) == MAY_BE_DOUBLE) { in zend_jit_try_allocate_free_reg()
2105 if (ssa->vars[current->ssa_var].definition == current->range.start) { in zend_jit_try_allocate_free_reg()
2111 ssa->ops + current->range.start, ssa, current->ssa_var, it->ssa_var)) { in zend_jit_try_allocate_free_reg()
2169 if (ssa->ops[line].op1_def == current->ssa_var || in zend_jit_try_allocate_free_reg()
2170 ssa->ops[line].op2_def == current->ssa_var || in zend_jit_try_allocate_free_reg()
2171 ssa->ops[line].result_def == current->ssa_var) { in zend_jit_try_allocate_free_reg()
2174 ssa->ops + line, in zend_jit_try_allocate_free_reg()
2175 op_array, ssa, current->ssa_var, line == last_use_line); in zend_jit_try_allocate_free_reg()
2186 ssa->ops + line, in zend_jit_try_allocate_free_reg()
2187 op_array, ssa, current->ssa_var, line == last_use_line); in zend_jit_try_allocate_free_reg()
2200 if (ssa->vars[current->ssa_var].definition == current->start) { in zend_jit_try_allocate_free_reg()
2206 hint = ssa->ops[current->start].op2_use; in zend_jit_try_allocate_free_reg()
2208 hint = ssa->ops[current->start].op1_use; in zend_jit_try_allocate_free_reg()
2213 hint = ssa->ops[current->start].op1_use; in zend_jit_try_allocate_free_reg()
2219 hint = ssa->ops[current->start].op1_use; in zend_jit_try_allocate_free_reg()
2314 …scan(const zend_op_array *op_array, const zend_op **ssa_opcodes, zend_ssa *ssa, zend_lifetime_inte… in zend_jit_linear_scan() argument
2373 …if (zend_jit_try_allocate_free_reg(op_array, ssa_opcodes, ssa, current, available, &hints, active,… in zend_jit_linear_scan()
2403 static void zend_jit_dump_lifetime_interval(const zend_op_array *op_array, const zend_ssa *ssa, con… in zend_jit_dump_lifetime_interval() argument
2406 int var_num = ssa->vars[ival->ssa_var].var; in zend_jit_dump_lifetime_interval()
2431 var_num = ssa->vars[ival->hint->ssa_var].var; in zend_jit_dump_lifetime_interval()
2442 … zend_lifetime_interval** zend_jit_allocate_registers(const zend_op_array *op_array, zend_ssa *ssa) in zend_jit_allocate_registers() argument
2451 if (!ssa->var_info) { in zend_jit_allocate_registers()
2456 set_size = zend_bitset_len(ssa->vars_count); in zend_jit_allocate_registers()
2463 for (i = 0; i < ssa->vars_count; i++) { in zend_jit_allocate_registers()
2464 if (zend_jit_may_be_in_reg(op_array, ssa, i)) { in zend_jit_allocate_registers()
2477 if (zend_jit_compute_liveness(op_array, ssa, candidates, &list) != SUCCESS) { in zend_jit_allocate_registers()
2490 if (zend_ssa_is_last_use(op_array, ssa, ival->ssa_var, range->end)) { in zend_jit_allocate_registers()
2502 zend_jit_dump_lifetime_interval(op_array, ssa, ival); in zend_jit_allocate_registers()
2509 list = zend_jit_linear_scan(op_array, NULL, ssa, list); in zend_jit_allocate_registers()
2512 intervals = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_lifetime_interval*)); in zend_jit_allocate_registers()
2528 for (i = 0; i < ssa->vars_count; i++) { in zend_jit_allocate_registers()
2529 if (ssa->vars[i].definition_phi && !ssa->vars[i].no_val) { in zend_jit_allocate_registers()
2530 zend_ssa_phi *phi = ssa->vars[i].definition_phi; in zend_jit_allocate_registers()
2534 if (!ssa->vars[i].phi_use_chain in zend_jit_allocate_registers()
2535 || ssa->vars[i].phi_use_chain->block != phi->block) { in zend_jit_allocate_registers()
2551 for (k = 0; k < ssa->cfg.blocks[phi->block].predecessors_count; k++) { in zend_jit_allocate_registers()
2554 if (ssa->vars[src].definition_phi in zend_jit_allocate_registers()
2555 && ssa->vars[src].definition_phi->pi >= 0 in zend_jit_allocate_registers()
2556 && phi->block == ssa->vars[src].definition_phi->block) { in zend_jit_allocate_registers()
2558 src = ssa->vars[src].definition_phi->sources[0]; in zend_jit_allocate_registers()
2575 for (k = 0; k < ssa->cfg.blocks[phi->block].predecessors_count; k++) { in zend_jit_allocate_registers()
2578 if (ssa->vars[src].definition_phi in zend_jit_allocate_registers()
2579 && ssa->vars[src].definition_phi->pi >= 0 in zend_jit_allocate_registers()
2580 && phi->block == ssa->vars[src].definition_phi->block) { in zend_jit_allocate_registers()
2582 src = ssa->vars[src].definition_phi->sources[0]; in zend_jit_allocate_registers()
2594 for (i = 0; i < ssa->vars_count; i++) { in zend_jit_allocate_registers()
2597 ((intervals[i]->flags & ZREG_STORE) && ssa->vars[i].definition >= 0)) && in zend_jit_allocate_registers()
2598 ssa->vars[i].use_chain < 0) { in zend_jit_allocate_registers()
2600 zend_ssa_phi *phi = ssa->vars[i].phi_use_chain; in zend_jit_allocate_registers()
2608 phi = zend_ssa_next_use_phi(ssa, i, phi); in zend_jit_allocate_registers()
2616 for (i = 0; i < ssa->vars_count; i++) { in zend_jit_allocate_registers()
2620 (ssa->vars[i].use_chain < 0 || in zend_jit_allocate_registers()
2621 zend_ssa_next_use(ssa->ops, i, ssa->vars[i].use_chain) < 0)) { in zend_jit_allocate_registers()
2623 zend_ssa_phi *phi = ssa->vars[i].phi_use_chain; in zend_jit_allocate_registers()
2631 phi = zend_ssa_next_use_phi(ssa, i, phi); in zend_jit_allocate_registers()
2642 for (i = 0; i < ssa->vars_count; i++) { in zend_jit_allocate_registers()
2645 zend_jit_dump_lifetime_interval(op_array, ssa, ival); in zend_jit_allocate_registers()
2703 static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op *rt_opline) in zend_jit() argument
2738 ra = zend_jit_allocate_registers(op_array, ssa); in zend_jit()
2742 for (b = 0; b < ssa->cfg.blocks_count; b++) { in zend_jit()
2743 if (ssa->cfg.blocks[b].flags & ZEND_BB_REACHABLE && in zend_jit()
2744 ssa->cfg.blocks[b].len > 1) { in zend_jit()
2746 opline = op_array->opcodes + ssa->cfg.blocks[b].start + ssa->cfg.blocks[b].len - 1; in zend_jit()
2749 ssa->cfg.blocks[ssa->cfg.blocks[b].successors[0]].flags |= ZEND_BB_TARGET; in zend_jit()
2758 dasm_growpc(&dasm_state, ssa->cfg.blocks_count * 2 + 1); in zend_jit()
2761 for (b = 0; b < ssa->cfg.blocks_count; b++) { in zend_jit()
2762 if ((ssa->cfg.blocks[b].flags & ZEND_BB_REACHABLE) == 0) { in zend_jit()
2766 if (ssa->cfg.blocks[b].flags & ZEND_BB_ENTRY) { in zend_jit()
2767 if (ssa->cfg.blocks[b].flags & ZEND_BB_TARGET) { in zend_jit()
2770 ssa->cfg.blocks[b].len == 1 && in zend_jit()
2771 (ssa->cfg.blocks[b].flags & ZEND_BB_EXIT) && in zend_jit()
2772 op_array->opcodes[ssa->cfg.blocks[b].start].opcode != ZEND_JMP) { in zend_jit()
2776 if (ssa->cfg.blocks[b].flags & ZEND_BB_FOLLOW) { in zend_jit()
2781 zend_jit_label(&dasm_state, ssa->cfg.blocks_count + b); in zend_jit()
2785 if (ssa->cfg.blocks[b].flags & (ZEND_BB_START|ZEND_BB_RECV_ENTRY)) { in zend_jit()
2786 opline = op_array->opcodes + ssa->cfg.blocks[b].start; in zend_jit()
2787 if (ssa->cfg.flags & ZEND_CFG_RECV_ENTRY) { in zend_jit()
2794 zend_jit_label(&dasm_state, ssa->cfg.blocks_count + b); in zend_jit()
2796 zend_jit_label(&dasm_state, ssa->cfg.blocks_count + b + i); in zend_jit()
2807 zend_jit_label(&dasm_state, ssa->cfg.blocks_count + b); in zend_jit()
2824 zend_jit_label(&dasm_state, ssa->cfg.blocks_count + b); in zend_jit()
2832 ssa->cfg.blocks[b].len == 1 && in zend_jit()
2833 (ssa->cfg.blocks[b].flags & ZEND_BB_EXIT)) { in zend_jit()
2842 zend_jit_label(&dasm_state, ssa->cfg.blocks_count + b); in zend_jit()
2847 ssa->cfg.blocks[b].len == 1 && in zend_jit()
2848 (ssa->cfg.blocks[b].flags & ZEND_BB_EXIT)) { in zend_jit()
2857 zend_jit_label(&dasm_state, ssa->cfg.blocks_count + b); in zend_jit()
2866 if ((ssa->cfg.blocks[b].flags & ZEND_BB_FOLLOW) in zend_jit()
2867 && ssa->cfg.blocks[b].start != 0 in zend_jit()
2868 && (op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_NOP in zend_jit()
2869 || op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_SWITCH_LONG in zend_jit()
2870 || op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_SWITCH_STRING in zend_jit()
2871 || op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_MATCH)) { in zend_jit()
2873 if (!zend_jit_set_ip(&dasm_state, op_array->opcodes + ssa->cfg.blocks[b].start)) { in zend_jit()
2877 zend_jit_set_last_valid_opline(op_array->opcodes + ssa->cfg.blocks[b].start); in zend_jit()
2879 } else if (ssa->cfg.blocks[b].flags & ZEND_BB_TARGET) { in zend_jit()
2881 } else if (ssa->cfg.blocks[b].flags & (ZEND_BB_START|ZEND_BB_RECV_ENTRY|ZEND_BB_ENTRY)) { in zend_jit()
2882 zend_jit_set_last_valid_opline(op_array->opcodes + ssa->cfg.blocks[b].start); in zend_jit()
2884 if (ssa->cfg.blocks[b].flags & ZEND_BB_LOOP_HEADER) { in zend_jit()
2885 if (!zend_jit_check_timeout(&dasm_state, op_array->opcodes + ssa->cfg.blocks[b].start, NULL)) { in zend_jit()
2889 if (!ssa->cfg.blocks[b].len) { in zend_jit()
2893 zend_ssa_phi *phi = ssa->blocks[b].phis; in zend_jit()
2902 …if (!zend_jit_load_var(&dasm_state, ssa->var_info[phi->ssa_var].type, ssa->vars[phi->ssa_var].var,… in zend_jit()
2908 …if (!zend_jit_store_var(&dasm_state, ssa->var_info[phi->ssa_var].type, ssa->vars[phi->ssa_var].var… in zend_jit()
2916 end = ssa->cfg.blocks[b].start + ssa->cfg.blocks[b].len - 1; in zend_jit()
2917 for (i = ssa->cfg.blocks[b].start; i <= end; i++) { in zend_jit()
2918 zend_ssa_op *ssa_op = ssa->ops ? &ssa->ops[i] : NULL; in zend_jit()
2949 && ssa->vars in zend_jit()
2951 && !ssa->vars[ssa_op->result_use].no_val) { in zend_jit()
2973 …MAY_BE_LONG) && (op1_def_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, ssa_op, op_array, ssa), in zend_jit()
2974 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
2984 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3010 && ssa->vars in zend_jit()
3012 && !ssa->vars[ssa_op->result_use].no_val) { in zend_jit()
3026 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3034 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3064 && ssa->vars in zend_jit()
3066 && !ssa->vars[ssa_op->result_use].no_val) { in zend_jit()
3088 …o & MAY_BE_LONG) && (res_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, ssa_op, op_array, ssa), in zend_jit()
3089 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3096 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3119 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3127 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3140 …MAY_BE_LONG) && (op1_def_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, ssa_op, op_array, ssa), in zend_jit()
3141 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3149 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3159 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3167 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3172 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3185 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3203 if (ssa->var_info && ssa->ops) { in zend_jit()
3204 zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; in zend_jit()
3206 zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; in zend_jit()
3214 if (!zend_jit_incdec_obj(&dasm_state, opline, op_array, ssa, ssa_op, in zend_jit()
3229 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3251 if (ssa->var_info && ssa->ops) { in zend_jit()
3252 zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; in zend_jit()
3254 zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; in zend_jit()
3262 if (!zend_jit_assign_obj_op(&dasm_state, opline, op_array, ssa, ssa_op, in zend_jit()
3274 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3292 if (ssa->var_info && ssa->ops) { in zend_jit()
3293 zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; in zend_jit()
3295 zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; in zend_jit()
3303 if (!zend_jit_assign_obj(&dasm_state, opline, op_array, ssa, ssa_op, in zend_jit()
3306 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3314 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3319 && ssa->ops[opline - op_array->opcodes].op2_def >= 0 in zend_jit()
3320 && !ssa->vars[ssa->ops[opline - op_array->opcodes].op2_def].no_val) { in zend_jit()
3326 if (ra && ssa->vars[ssa_op->op1_use].no_val) { in zend_jit()
3351 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3358 && ssa->ops[opline - op_array->opcodes].op1_def >= 0 in zend_jit()
3359 && !ssa->vars[ssa->ops[opline - op_array->opcodes].op1_def].no_val) { in zend_jit()
3373 … if (!zend_jit_init_fcall(&dasm_state, opline, b, op_array, ssa, ssa_op, call_level, NULL, 0)) { in zend_jit()
3418 && ssa->ops[opline - op_array->opcodes].op1_def >= 0 in zend_jit()
3419 && !ssa->vars[ssa->ops[opline - op_array->opcodes].op1_def].no_val) { in zend_jit()
3452 if (!zend_jit_do_fcall(&dasm_state, opline, op_array, ssa, call_level, b + 1, NULL)) { in zend_jit()
3472 target_label = ssa->cfg.blocks[b].successors[0]; in zend_jit()
3473 target_label2 = ssa->cfg.blocks[b].successors[1]; in zend_jit()
3487 zend_may_throw(opline, ssa_op, op_array, ssa), in zend_jit()
3505 target_label = ssa->cfg.blocks[b].successors[0]; in zend_jit()
3506 target_label2 = ssa->cfg.blocks[b].successors[1]; in zend_jit()
3515 zend_may_throw(opline, ssa_op, op_array, ssa), in zend_jit()
3530 target_label = ssa->cfg.blocks[b].successors[0]; in zend_jit()
3531 target_label2 = ssa->cfg.blocks[b].successors[1]; in zend_jit()
3553 target_label = ssa->cfg.blocks[b].successors[0]; in zend_jit()
3554 target_label2 = ssa->cfg.blocks[b].successors[1]; in zend_jit()
3565 if ((PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) in zend_jit()
3588 jit_return_label = ssa->cfg.blocks_count * 2; in zend_jit()
3601 uint32_t info = zend_ssa_cv_info(op_array, ssa, j); in zend_jit()
3617 NULL, NULL, (ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0, 1)) { in zend_jit()
3627 zend_may_throw(opline, ssa_op, op_array, ssa), in zend_jit()
3634 if (opline > op_array->opcodes + ssa->cfg.blocks[b].start && in zend_jit()
3637 if (!zend_jit_cond_jmp(&dasm_state, opline + 1, ssa->cfg.blocks[b].successors[0])) { in zend_jit()
3652 ssa->cfg.blocks[b].successors[0], ssa->cfg.blocks[b].successors[1], in zend_jit()
3653 zend_may_throw(opline, ssa_op, op_array, ssa), in zend_jit()
3671 target_label = ssa->cfg.blocks[b].successors[0]; in zend_jit()
3672 target_label2 = ssa->cfg.blocks[b].successors[1]; in zend_jit()
3700 target_label = ssa->cfg.blocks[b].successors[0]; in zend_jit()
3701 target_label2 = ssa->cfg.blocks[b].successors[1]; in zend_jit()
3716 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3719 if (!zend_jit_fetch_dim_read(&dasm_state, opline, ssa, ssa_op, in zend_jit()
3729 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3745 if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { in zend_jit()
3756 target_label = ssa->cfg.blocks[b].successors[0]; in zend_jit()
3757 target_label2 = ssa->cfg.blocks[b].successors[1]; in zend_jit()
3765 zend_may_throw(opline, ssa_op, op_array, ssa), in zend_jit()
3794 if (ssa->var_info && ssa->ops) { in zend_jit()
3795 zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; in zend_jit()
3797 zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; in zend_jit()
3805 if (!zend_jit_fetch_obj(&dasm_state, opline, op_array, ssa, ssa_op, in zend_jit()
3808 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3813 if (!ssa->ops || !ssa->var_info) { in zend_jit()
3830 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3837 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3864 …opline, op1_info, OP1_REG_ADDR(), RES_REG_ADDR(), zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
3876 if (!zend_jit_switch(&dasm_state, opline, op_array, ssa, NULL, NULL)) { in zend_jit()
3916 ssa->cfg.blocks[b].successors[0], opline->opcode, NULL)) { in zend_jit()
3921 if (!zend_jit_fetch_constant(&dasm_state, opline, op_array, ssa, ssa_op, RES_REG_ADDR())) { in zend_jit()
3945 if (ssa->var_info && ssa->ops) { in zend_jit()
3946 zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; in zend_jit()
3948 zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; in zend_jit()
3956 if (!zend_jit_init_method_call(&dasm_state, opline, b, op_array, ssa, ssa_op, call_level, in zend_jit()
3985 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
4005 if (!zend_jit_jmp(&dasm_state, ssa->cfg.blocks[b].successors[0])) { in zend_jit()
4039 if (opline > op_array->opcodes + ssa->cfg.blocks[b].start && in zend_jit()
4042 if (!zend_jit_cond_jmp(&dasm_state, opline + 1, ssa->cfg.blocks[b].successors[0])) { in zend_jit()
4060 zend_may_throw(opline, ssa_op, op_array, ssa)) || in zend_jit()
4061 !zend_jit_cond_jmp(&dasm_state, opline + 1, ssa->cfg.blocks[b].successors[0])) { in zend_jit()
4073 if (ssa->ops && ssa->var_info) { in zend_jit()
4074 … zend_ssa_var_info *res_ssa = &ssa->var_info[ssa->ops[opline - op_array->opcodes].result_def]; in zend_jit()
4094 zend_jit_cond_jmp(&dasm_state, next_opline, ssa->cfg.blocks[b].successors[0]); in zend_jit()
4099 zend_jit_do_fcall(&dasm_state, next_opline, op_array, ssa, call_level, b + 1, NULL); in zend_jit()
4109 zend_may_throw(opline, ssa_op, op_array, ssa))) { in zend_jit()
4115 if (!zend_jit_cond_jmp(&dasm_state, opline + 2, ssa->cfg.blocks[b+1].successors[0])) { in zend_jit()
4118 if (!zend_jit_jmp(&dasm_state, ssa->cfg.blocks[b+1].successors[1])) { in zend_jit()
4136 handler = dasm_link_and_encode(&dasm_state, op_array, ssa, rt_opline, ra, NULL, 0, in zend_jit()
4190 memset(&func_info->ssa, 0, sizeof(zend_func_info) - offsetof(zend_func_info, ssa)); in zend_jit_cleanup_func_info()
4212 zend_ssa ssa; in zend_real_jit_func() local
4223 memset(&ssa, 0, sizeof(zend_ssa)); in zend_real_jit_func()
4225 if (zend_jit_op_array_analyze1(op_array, script, &ssa) != SUCCESS) { in zend_real_jit_func()
4238 …if (zend_jit_op_array_analyze2(op_array, script, &ssa, ZCG(accel_directives).optimization_level) !… in zend_real_jit_func()
4243 …p_op_array(op_array, ZEND_DUMP_HIDE_UNREACHABLE|ZEND_DUMP_RC_INFERENCE|ZEND_DUMP_SSA, "JIT", &ssa); in zend_real_jit_func()
4246 if (zend_jit(op_array, &ssa, rt_opline) != SUCCESS) { in zend_real_jit_func()
4564 if (zend_jit_op_array_analyze1(call_graph.op_arrays[i], script, &info->ssa) != SUCCESS) { in zend_jit_script()
4567 info->flags = info->ssa.cfg.flags; in zend_jit_script()
4584 …if (zend_jit_op_array_analyze2(call_graph.op_arrays[i], script, &info->ssa, ZCG(accel_directives).… in zend_jit_script()
4587 info->flags = info->ssa.cfg.flags; in zend_jit_script()
4595 ….op_arrays[i], ZEND_DUMP_HIDE_UNREACHABLE|ZEND_DUMP_RC_INFERENCE|ZEND_DUMP_SSA, "JIT", &info->ssa); in zend_jit_script()
4597 if (zend_jit(call_graph.op_arrays[i], &info->ssa, NULL) != SUCCESS) { in zend_jit_script()