15#define IR_COMBO_COPY_PROPAGATION 1
17#define IR_TOP IR_UNUSED
18#define IR_BOTTOM IR_LAST_OP
20#define IR_MAKE_TOP(ref) do {IR_ASSERT(ref > 0); _values[ref].optx = IR_TOP;} while (0)
21#define IR_MAKE_BOTTOM(ref) do {IR_ASSERT(ref > 0); _values[ref].optx = IR_BOTTOM;} while (0)
23#define IR_IS_TOP(ref) (ref >= 0 && _values[ref].op == IR_TOP)
24#define IR_IS_BOTTOM(ref) (ref >= 0 && _values[ref].op == IR_BOTTOM)
25#define IR_IS_REACHABLE(ref) _ir_is_reachable_ctrl(ctx, _values, ref)
26#define IR_IS_CONST(ref) (IR_IS_CONST_REF(ref) || IR_IS_CONST_OP(_values[ref].op))
32 return _values[ref].op !=
IR_TOP;
56 if (!_values[ref].
op1) {
62#if IR_COMBO_COPY_PROPAGATION
65 if (
a > 0 && _values[
a].op == IR_COPY) {
69 }
while (_values[
a].op == IR_COPY);
78 ir_ref member = _values[ref].op2;
79 while (member != ref) {
81 member = _values[member].op2;
86# define CHECK_LIST(_values, ref)
95 _values[dst].optx = IR_COPY;
96 _values[dst].op1 = src;
100 if (_values[src].
op1 != src) {
101 _values[src].op1 = src;
102 _values[src].op2 = src;
103 _values[src].op3 = src;
111 _values[dst].op2 = src;
112 _values[dst].op3 =
prev;
113 _values[src].op3 = dst;
114 _values[
prev].op2 = dst;
124 _values[ref].op1 = ref;
126 member = _values[ref].op2;
128 while (member != ref) {
134 next = _values[member].op2;
137 prev = _values[member].op3;
145 _values[
tail].op2 = member;
146 _values[member].op3 =
tail;
154 next = _values[ref].op2;
155 prev = _values[ref].op3;
162 _values[ref].op2 =
head;
163 _values[ref].op3 =
tail;
164 _values[
tail].op2 = ref;
165 _values[
head].op3 = ref;
167 _values[ref].op2 = ref;
168 _values[ref].op3 = ref;
175 if (_values[ref].op == IR_COPY) {
176 ir_sccp_split_partition(ctx, _values, worklist, ref);
182# define IR_MAKE_BOTTOM_EX(ref) ir_sccp_make_bottom_ex(ctx, _values, worklist, ref)
184# define ir_sccp_identity(_ctx, _values, ref) (ref)
185# define IR_MAKE_BOTTOM_EX(ref) IR_MAKE_BOTTOM(ref)
192 if (_values[ref].op ==
IR_TOP) {
194 _values[ref].optx = val_insn->opt;
197 }
else if (_values[ref].opt == val_insn->opt) {
199 if (_values[ref].
val.u64 == val_insn->
val.
u64) {
214 val_insn = &ctx->
ir_base[val_identity];
216 val_insn = &_values[val_identity];
219#if IR_COMBO_COPY_PROPAGATION
220 if (_values[ref].op == IR_COPY) {
226 ir_sccp_split_partition(ctx, _values, worklist, ref);
232 ir_sccp_add_identity(ctx, _values,
val, ref);
247 ir_insn *op1_insn, *op2_insn, *op3_insn;
249 uint32_t opt = insn->opt;
258 op3_insn = (op3 > 0 &&
IR_IS_CONST_OP(_values[op3].op)) ? _values + op3 : ctx->ir_base + op3;
260 switch (
ir_folding(ctx, opt,
op1,
op2, op3, op1_insn, op2_insn, op3_insn)) {
286#if IR_COMBO_COPY_PROPAGATION
295 n = insn->inputs_count;
296 if (
n > 3 && _values[i].op ==
IR_TOP) {
297 for (
j = 0;
j < (
n>>2);
j++) {
303 merge_input = ctx->
ir_base[insn->op1].ops + 1;
304 for (; --
n > 0;
p++, merge_input++) {
313 }
else if (input == i) {
320#if IR_COMBO_COPY_PROPAGATION
321 }
else if (
v->op == IR_COPY) {
324 if (new_copy_identity == phi_identity) {
332#if IR_COMBO_COPY_PROPAGATION
333 if (input == phi_identity) {
336 new_copy = new_copy_identity = input;
353 for (; --
n > 0;
p++, merge_input++) {
361#if IR_COMBO_COPY_PROPAGATION
367 }
else if (input == i) {
374#if IR_COMBO_COPY_PROPAGATION
375 }
else if (
v->op == IR_COPY) {
378 if (identity == phi_identity || identity == new_copy_identity) {
384#if IR_COMBO_COPY_PROPAGATION
385 if (input == phi_identity || input == new_copy_identity) {
392 if (!new_const || new_const->opt !=
v->opt || new_const->
val.
u64 !=
v->val.u64) {
397#if IR_COMBO_COPY_PROPAGATION
399 return ir_sccp_meet(ctx, _values, worklist, i, new_copy);
414 }
else if (insn->op == IR_ALLOCA || insn->op == IR_BLOCK_BEGIN) {
427 }
else if (ctx->
ir_base[ref].op == IR_ALLOCA) {
439 return ir_is_dead_load(ctx, ref);
470#if IR_COMBO_COPY_PROPAGATION
471 }
else if (_values[i].op == IR_COPY) {
476 }
else if (_values[i].op == IR_IF) {
478 }
else if (_values[i].op == IR_MERGE) {
481 fprintf(stderr,
"%d", _values[i].op);
488 ir_sccp_trace_val(ctx, _values, i);
494 ir_sccp_trace_val(ctx, _values, i);
498# define ir_sccp_trace_start(c, v, i)
499# define ir_sccp_trace_end(c, v, i)
521 }
else if (insn->op == IR_PHI) {
522 if (!ir_sccp_analyze_phi(ctx, _values, worklist, i, insn)) {
526 bool may_benefit = 0;
529 if (_values[i].op !=
IR_TOP) {
535 for (
p = insn->ops + 1;
n > 0;
p++,
n--) {
538 if (_values[input].op ==
IR_TOP) {
541 }
else if (_values[input].op !=
IR_BOTTOM) {
556 if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC) {
559 }
else if (!ir_sccp_fold(ctx, _values, worklist, i, insn)) {
564 if (insn->op == IR_FP2FP || insn->op == IR_FP2INT || insn->op == IR_TRUNC) {
572 if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN || insn->op == IR_BEGIN) {
575 if (insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN) {
576 ir_ref unfeasible_inputs = 0;
578 n = insn->inputs_count;
579 if (
n > 3 && _values[i].op ==
IR_TOP) {
580 for (
j = 0;
j < (
n>>2);
j++) {
584 for (
p = insn->ops + 1;
n > 0;
p++,
n--) {
591 if (unfeasible_inputs == 0) {
593 }
else if (_values[i].op != IR_MERGE || _values[i].
op1 != unfeasible_inputs) {
594 _values[i].optx = IR_MERGE;
595 _values[i].op1 = unfeasible_inputs;
606 if (ctx->
ir_base[use].op == IR_PHI) {
609 if (ir_sccp_analyze_phi(ctx, _values, worklist, use, &ctx->
ir_base[use])) {
630 if (insn->op == IR_IF) {
636 bool b = ir_sccp_is_true(ctx, _values, insn->op2);
642 IR_ASSERT(use_insn->op == IR_IF_TRUE || use_insn->op == IR_IF_FALSE);
643 if ((use_insn->op == IR_IF_TRUE) != b) {
647 if (_values[i].op ==
IR_TOP) {
648 _values[i].optx = IR_IF;
649 _values[i].op1 = use;
652 }
else if (_values[i].op == IR_IF && _values[i].
op1 == use) {
658 }
else if (insn->op == IR_SWITCH) {
672 if (use_insn->op == IR_CASE_VAL) {
673 if (ir_sccp_is_equal(ctx, _values, insn->op2, use_insn->op2)) {
677 }
else if (use_insn->op == IR_CASE_DEFAULT) {
682 use_insn = &ctx->
ir_base[use_case];
683 if (_values[i].op ==
IR_TOP) {
684 _values[i].optx = IR_IF;
685 _values[i].op1 = use_case;
688 }
else if (_values[i].op == IR_IF || _values[i].
op1 == use_case) {
694 }
else if (ir_is_dead_load_ex(ctx, i,
flags, insn)) {
699 if (_values[i].op ==
IR_TOP) {
705 for (
j = 0;
j < (
n>>2);
j++) {
708 for (
j = 2,
p = insn->ops +
j;
j <=
n;
j++,
p++) {
711 if (use > 0 && _values[use].op ==
IR_TOP) {
719 if (use > 0 && _values[use].op ==
IR_TOP) {
727 if (use > 0 && _values[use].op ==
IR_TOP) {
736 if (_values[use].op ==
IR_TOP) {
739 if (!_values[use].
op1) {
740 _values[use].op1 = 1;
754 if (ctx->
flags & IR_DEBUG_SCCP) {
757 fprintf(stderr,
"%d. CONST(", i);
760#if IR_COMBO_COPY_PROPAGATION
761 }
else if (_values[i].op == IR_COPY) {
762 fprintf(stderr,
"%d. COPY(%d)\n", i, _values[i].
op1);
765 fprintf(stderr,
"%d. TOP\n", i);
766 }
else if (_values[i].op == IR_IF) {
767 fprintf(stderr,
"%d. IF(%d)\n", i, _values[i].
op1);
768 }
else if (_values[i].op == IR_MERGE) {
769 fprintf(stderr,
"%d. MERGE(%d)\n", i, _values[i].
op1);
771 fprintf(stderr,
"%d. %d\n", i, _values[i].op);
789 n = insn->inputs_count;
791 for (
j = 1,
p = insn->ops +
j;
j <=
n;
j++,
p++) {
803 n = insn->inputs_count;
805 for (
j = 1,
p = insn->ops +
j;
j <=
n;
j++,
p++) {
809 if (input > 0 && _values[input].op > IR_COPY) {
811 if (ir_is_dead(ctx, input)) {
829#if IR_COMBO_COPY_PROPAGATION
841 n = insn->inputs_count;
843 for (
j = 1,
p = insn->ops + 1;
j <=
n;
j++,
p++) {
847 if (input > 0 && _values[input].op > IR_COPY) {
849 if (ir_is_dead(ctx, input)) {
861 for (;
n;
p++,
n--) {
864 if (_values[use].op > IR_COPY) {
875 for (
j = 0;
j <
n;
j++,
p++) {
907 next_insn->op1 = insn->op1;
910 ir_sccp_make_nop(ctx, ref);
911 ir_sccp_make_nop(ctx, dst);
915 next_insn = &ctx->
ir_base[dst];
916 next_insn->op = IR_BEGIN;
922 ir_ref old_merge_inputs, new_merge_inputs, i, *
p;
927 IR_ASSERT(insn->op == IR_MERGE || insn->op == IR_LOOP_BEGIN);
928 old_merge_inputs = insn->inputs_count;
929 new_merge_inputs = 0;
932 for (i = 1; i <= old_merge_inputs; i++) {
937 if (new_merge_inputs != i) {
944 if (new_merge_inputs == old_merge_inputs) {
946 if (life_inputs != &holder) {
952 for (i = new_merge_inputs + 1; i <= old_merge_inputs; i++) {
956 if (new_merge_inputs <= 1) {
958 if (new_merge_inputs == 1
959 && insn->op == IR_LOOP_BEGIN
960 && insn->op1 > ref) {
964 new_merge_inputs = 0;
970 insn->inputs_count = new_merge_inputs;
975 if (use_list->
count > 1) {
976 ir_ref use_count = 0;
979 for (i = 0, p = q = &ctx->use_edges[use_list->refs]; i < use_list->count; p++, i++) {
981 ir_insn *use_insn = &ctx->ir_base[use];
983 if (use_insn->op == IR_PHI) {
987 for (j = k = 1; j <= old_merge_inputs; j++) {
988 ir_ref input = ir_insn_op(use_insn, j + 1);
990 if (ir_bitset_in(life_inputs, j)) {
993 ir_insn_set_op(use_insn, k + 1, input);
996 } else if (input > 0) {
997 ir_use_list_remove_one(ctx, input, use);
1000 while (k <= old_merge_inputs) {
1002 ir_insn_set_op(use_insn, k, IR_UNUSED);
1005 if (new_merge_inputs == 0) {
1008 use_insn->op1 = IR_UNUSED;
1009 ir_iter_remove_insn(ctx, use, worklist);
1014 } else if (new_merge_inputs == 1) {
1016 use_insn->optx = IR_OPTX(IR_COPY, use_insn->type, 1);
1017 use_insn->op1 = use_insn->op2;
1018 use_insn->op2 = IR_UNUSED;
1019 ir_bitqueue_add(worklist, use);
1022 use_insn->inputs_count = new_merge_inputs + 1;
1031 for (i = use_count; i < use_list->
count; q++, i++) {
1034 use_list->
count = use_count;
1037 if (life_inputs != &holder) {
1055 ir_sccp_replace_insn(ctx, _values, i,
j, iter_worklist);
1059 ir_sccp_replace_insn(ctx, _values, i,
j, iter_worklist);
1060#if IR_COMBO_COPY_PROPAGATION
1061 }
else if (
value->op == IR_COPY) {
1068 if (insn->op == IR_NOP) {
1071 if (insn->op != IR_PARAM) {
1072 ir_sccp_remove_insn(ctx, _values, i, iter_worklist);
1079 ctx->
ir_base[1].op1 = insn->op3;
1090 ir_sccp_replace_insn(ctx, _values, i,
IR_UNUSED, iter_worklist);
1092 }
else if (
value->op == IR_IF) {
1094 ir_sccp_remove_if(ctx, _values, i,
value->op1);
1095 }
else if (
value->op == IR_MERGE) {
1103 ir_sccp_remove_unfeasible_merge_inputs(ctx, i, &ctx->
ir_base[i], iter_worklist);
1126 if (insn->op == IR_ADD || insn->op == IR_SUB) {
1129 if (use_list->
count == 1) {
1133 if (use_insn->op == IR_ADD || use_insn->op == IR_SUB) {
1147 n = insn->inputs_count;
1149 for (
j = 1,
p = insn->ops +
j;
j <=
n;
j++,
p++) {
1154 if (ir_is_dead(ctx, input)) {
1178 for (;
n;
p++,
n--) {
1187 ir_iter_add_related_uses(ctx, use, worklist);
1190 for (
j = 0;
j <
n;
j++,
p++) {
1215 n = insn->inputs_count;
1217 for (
j = 1,
p = insn->ops + 1;
j <=
n;
j++,
p++) {
1222 if (ir_is_dead(ctx, input)) {
1249 if (ir_is_dead(ctx, old_val)) {
1267 if (use_insn->optx == optx) {
1294 use_insn = &ctx->
ir_base[use];
1295 if (use_insn->opt == opt && use_insn->op1 ==
op1 && use_insn->op2 ==
op2) {
1314 use_insn = &ctx->
ir_base[use];
1315 if (use_insn->opt == opt) {
1344 use_insn = &ctx->
ir_base[use];
1345 if (use_insn->opt == opt && use_insn->op1 ==
op1 && use_insn->op2 ==
op2 && use_insn->op3 == op3) {
1363 ir_insn *op1_insn, *op2_insn, *op3_insn, *insn;
1374 op3_insn = ctx->
ir_base + op3;
1376 switch (
ir_folding(ctx, opt,
op1,
op2, op3, op1_insn, op2_insn, op3_insn)) {
1387 ir_iter_replace_insn(ctx, ref,
copy, worklist);
1405 if (insn->op1 > 0) {
1413 if (insn->op2 > 0) {
1421 if (insn->op3 > 0) {
1442 ir_iter_replace_insn(ctx, ref,
op1, worklist);
1446 ir_iter_replace_insn(ctx, ref,
op1, worklist);
1470 ir_may_promote_d2f(ctx, insn->op1);
1478 ir_may_promote_d2f(ctx, insn->op1) &&
1479 ir_may_promote_d2f(ctx, insn->op2);
1503 ir_may_promote_f2d(ctx, insn->op1);
1511 ir_may_promote_f2d(ctx, insn->op1) &&
1512 ir_may_promote_f2d(ctx, insn->op2);
1539 }
while (--
count > 1);
1550 }
while (--
count > 1);
1559 insn->op1 = ir_promote_d2f(ctx, insn->op1, ref, worklist);
1560 insn->type = IR_FLOAT;
1568 if (insn->op1 == insn->op2) {
1569 insn->op2 = insn->op1 = ir_promote_d2f(ctx, insn->op1, ref, worklist);
1571 insn->op1 = ir_promote_d2f(ctx, insn->op1, ref, worklist);
1572 insn->op2 = ir_promote_d2f(ctx, insn->op2, ref, worklist);
1574 insn->type = IR_FLOAT;
1604 }
while (--
count > 1);
1615 }
while (--
count > 1);
1620 old_ref = ir_iter_find_cse1(ctx,
IR_OPTX(IR_INT2FP, IR_DOUBLE, 1), insn->op1);
1629 insn->type = IR_DOUBLE;
1633 insn->op1 = ir_promote_f2d(ctx, insn->op1, ref, worklist);
1634 insn->type = IR_DOUBLE;
1642 if (insn->op1 == insn->op2) {
1643 insn->op2 = insn->op1 = ir_promote_f2d(ctx, insn->op1, ref, worklist);
1645 insn->op1 = ir_promote_f2d(ctx, insn->op1, ref, worklist);
1646 insn->op2 = ir_promote_f2d(ctx, insn->op2, ref, worklist);
1648 insn->type = IR_DOUBLE;
1675 ir_may_promote_trunc(ctx,
type, insn->op1);
1686 ir_may_promote_trunc(ctx,
type, insn->op1) &&
1687 ir_may_promote_trunc(ctx,
type, insn->op2);
1696 ir_may_promote_trunc(ctx,
type, insn->op2) &&
1697 ir_may_promote_trunc(ctx,
type, insn->op3);
1712 for (
p = insn->ops + 2,
n = insn->inputs_count - 1;
n > 0;
p++,
n--) {
1715 if (!ir_may_promote_trunc(ctx,
type, input)) {
1745 insn->op = IR_BITCAST;
1747 insn->op = IR_TRUNC;
1749 if (insn->op != IR_SEXT && insn->op != IR_ZEXT) {
1764 }
while (--
count > 1);
1775 }
while (--
count > 1);
1782 insn->op1 = ir_promote_i2i(ctx,
type, insn->op1, ref, worklist);
1794 if (insn->op1 == insn->op2) {
1795 insn->op2 = insn->op1 = ir_promote_i2i(ctx,
type, insn->op1, ref, worklist);
1797 insn->op1 = ir_promote_i2i(ctx,
type, insn->op1, ref, worklist);
1798 insn->op2 = ir_promote_i2i(ctx,
type, insn->op2, ref, worklist);
1809 if (insn->op2 == insn->op3) {
1810 insn->op3 = insn->op2 = ir_promote_i2i(ctx,
type, insn->op2, ref, worklist);
1812 insn->op2 = ir_promote_i2i(ctx,
type, insn->op2, ref, worklist);
1813 insn->op3 = ir_promote_i2i(ctx,
type, insn->op3, ref, worklist);
1818 for (
p = insn->ops + 2,
n = insn->inputs_count - 1;
n > 0;
p++,
n--) {
1821 *
p = ir_promote_i2i(ctx,
type, input, ref, worklist);
1838 switch (val_insn->type) {
1844 if (op == IR_SEXT) {
1845 new_val.
i64 = (int64_t)val_insn->
val.i8;
1847 new_val.
u64 = (uint64_t)val_insn->
val.u8;
1852 if (op == IR_SEXT) {
1853 new_val.
i64 = (int64_t)val_insn->
val.i16;
1855 new_val.
u64 = (uint64_t)val_insn->
val.u16;
1860 if (op == IR_SEXT) {
1861 new_val.
i64 = (int64_t)val_insn->
val.i32;
1863 new_val.
u64 = (uint64_t)val_insn->
val.u32;
1876 ref = ir_iter_find_cse1(ctx, optx, src_ref);
1887 ref =
ir_emit1(ctx, optx, src_ref);
1916 n = insn->inputs_count;
1920 for (;
n > 0;
p++,
n--) {
1922 ctrl = _ir_estimated_control(ctx, input);
1932 ref = _ir_estimated_control(ctx, ref);
1943 if (insn->op == IR_LOAD) {
1944 if (ir_is_loop_invariant(ctx, ref, loop)) {
1956 if (use != ext_ref) {
1959 if (use_insn->op != op
1961 || use_insn->op1 != ref)) {
1971 return ir_is_loop_invariant(ctx, ref, loop);
1990 if (use == op_ref || use == ext_ref) {
1995 if (use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) {
1996 if (use_insn->op1 == phi_ref) {
1997 if (ir_is_cheaper_ext(ctx, use_insn->op2, ctx->
ir_base[phi_ref].op1, ext_ref, op)) {
2000 }
else if (use_insn->op2 == phi_ref) {
2001 if (ir_is_cheaper_ext(ctx, use_insn->op1, ctx->
ir_base[phi_ref].op1, ext_ref, op)) {
2006 }
else if (use_insn->op == IR_IF) {
2008 }
else if (!ext_ref_2 && use_insn->op == op && use_insn->type ==
type) {
2023 if (use == phi_ref || use == ext_ref) {
2028 if (use_insn->op >= IR_EQ && use_insn->op <= IR_UGT) {
2029 if (use_insn->op1 == phi_ref) {
2030 if (ir_is_cheaper_ext(ctx, use_insn->op2, ctx->
ir_base[phi_ref].op1, ext_ref, op)) {
2033 }
else if (use_insn->op2 == phi_ref) {
2034 if (ir_is_cheaper_ext(ctx, use_insn->op1, ctx->
ir_base[phi_ref].op1, ext_ref, op)) {
2039 }
else if (use_insn->op == IR_IF) {
2041 }
else if (!ext_ref_2 && use_insn->op == op && use_insn->type ==
type) {
2054 if (use == ext_ref) {
2059 if (use_insn->op == IR_IF) {
2061 }
else if (use_insn->op == op) {
2065 IR_ASSERT(((use_insn->op >= IR_EQ && use_insn->op <= IR_UGT)
2066 || use_insn->op == IR_ADD || use_insn->op == IR_SUB || use_insn->op == IR_MUL)
2067 && (use_insn->op1 == phi_ref || use_insn->op2 == phi_ref));
2068 if (use_insn->op1 != phi_ref) {
2073 ctx->
ir_base[use].op1 = ir_ext_ref(ctx, use, use_insn->op1, op,
type, worklist);
2077 if (use_insn->op2 != phi_ref) {
2082 ctx->
ir_base[use].op2 = ir_ext_ref(ctx, use, use_insn->op2, op,
type, worklist);
2093 if (use == ext_ref || use == phi_ref) {
2098 if (use_insn->op == IR_IF) {
2100 }
else if (use_insn->op == op) {
2104 IR_ASSERT(use_insn->op >= IR_EQ && use_insn->op <= IR_UGT);
2105 if (use_insn->op1 != op_ref) {
2110 ctx->
ir_base[use].op1 = ir_ext_ref(ctx, use, use_insn->op1, op,
type, worklist);
2114 if (use_insn->op2 != op_ref) {
2119 ctx->
ir_base[use].op2 = ir_ext_ref(ctx, use, use_insn->op2, op,
type, worklist);
2127 ir_iter_replace_insn(ctx, ext_ref, ctx->
ir_base[ext_ref].op1, worklist);
2130 ir_iter_replace_insn(ctx, ext_ref_2, ctx->
ir_base[ext_ref_2].op1, worklist);
2135 phi_insn = &ctx->
ir_base[phi_ref];
2136 phi_insn->type =
type;
2139 ctx->
ir_base[phi_ref].op2 = ir_ext_const(ctx, &ctx->
ir_base[phi_insn->op2], op,
type);
2141 ctx->
ir_base[phi_ref].op2 = ir_ext_ref(ctx, phi_ref, phi_insn->op2, op,
type, worklist);
2153 if (insn->op == IR_PHI
2154 && insn->inputs_count == 3
2155 && ctx->
ir_base[insn->op1].op == IR_LOOP_BEGIN) {
2156 ir_ref op_ref = insn->op3;
2159 if (op_insn->op == IR_ADD || op_insn->op == IR_SUB || op_insn->op == IR_MUL) {
2160 if (op_insn->op1 == ref) {
2161 if (ir_is_loop_invariant(ctx, op_insn->op2, insn->op1)) {
2162 return ir_try_promote_induction_var_ext(ctx, ext_ref, ref, op_ref, worklist);
2164 }
else if (op_insn->op2 == ref) {
2165 if (ir_is_loop_invariant(ctx, op_insn->op1, insn->op1)) {
2166 return ir_try_promote_induction_var_ext(ctx, ext_ref, ref, op_ref, worklist);
2170 }
else if (insn->op == IR_ADD || insn->op == IR_SUB || insn->op == IR_MUL) {
2172 && ctx->
ir_base[insn->op1].op == IR_PHI
2173 && ctx->
ir_base[insn->op1].inputs_count == 3
2174 && ctx->
ir_base[insn->op1].op3 == ref
2176 && ir_is_loop_invariant(ctx, insn->op2, ctx->
ir_base[insn->op1].op1)) {
2177 return ir_try_promote_induction_var_ext(ctx, ext_ref, insn->op1, ref, worklist);
2179 && ctx->
ir_base[insn->op2].op == IR_PHI
2180 && ctx->
ir_base[insn->op2].inputs_count == 3
2181 && ctx->
ir_base[insn->op2].op3 == ref
2183 && ir_is_loop_invariant(ctx, insn->op1, ctx->
ir_base[insn->op2].op1)) {
2184 return ir_try_promote_induction_var_ext(ctx, ext_ref, insn->op2, ref, worklist);
2197 if (ctx->
ir_base[*
p].op == IR_IF_TRUE) {
2200 *if_false_ref = *(
p + 1);
2205 *if_true_ref = *(
p + 1);
2221 region = ctx->
ir_base[region].op1;
2228 use_insn = &ctx->
ir_base[use];
2235 use_insn->op1 = region;
2247 use_list->
count = 1;
2292 if (insn->inputs_count == 2) {
2293 ir_ref end1_ref = insn->op1, end2_ref = insn->op2;
2297 if (end1->op != IR_END || end2->op != IR_END) {
2301 ir_ref start1_ref = end1->op1, start2_ref = end2->op1;
2305 if (start1->op1 != start2->op1) {
2309 ir_ref root_ref = start1->op1;
2312 if (root->op != IR_IF
2313 && !(root->op == IR_SWITCH && ctx->
use_lists[root_ref].
count == 2)) {
2340 ir_remove_unused_vars(ctx, start1_ref, end1_ref);
2343 ir_remove_unused_vars(ctx, start2_ref, end2_ref);
2346 next->op1 = root->op1;
2350 if (ir_is_dead(ctx, root->op2)) {
2371 for (i = 0; i <
count; i++) {
2372 ir_ref end_ref, start_ref;
2377 if (
end->op != IR_END) {
2380 start_ref =
end->op1;
2382 if (
start->op != IR_CASE_VAL &&
start->op != IR_CASE_DEFAULT) {
2386 ir_remove_unused_vars(ctx, start_ref, end_ref);
2389 root_ref =
start->op1;
2393 }
else if (
start->op1 != root_ref) {
2403 next->op1 = root->op1;
2408 if (ir_is_dead(ctx, root->op2)) {
2415 for (i = 0; i <
count; i++) {
2447 ir_ref end1_ref = merge->op1, end2_ref = merge->op2;
2451 if (end1->op == IR_END && end2->op == IR_END) {
2452 ir_ref start1_ref = end1->op1, start2_ref = end2->op1;
2456 if (start1->op1 == start2->op1) {
2457 ir_ref root_ref = start1->op1;
2461 ir_ref cond_ref = root->op2;
2464 bool is_cmp, is_less;
2467 is_cmp = (cond->op == IR_LT || cond->op == IR_LE || cond->op == IR_GT || cond->op == IR_GE ||
2468 cond->op == IR_ULT || cond->op == IR_ULE || cond->op == IR_UGT || cond->op == IR_UGE);
2469 is_less = (cond->op == IR_LT || cond->op == IR_LE ||
2470 cond->op == IR_ULT || cond->op == IR_ULE);
2472 is_cmp = (cond->op == IR_LT || cond->op == IR_LE || cond->op == IR_GT || cond->op == IR_GE);
2473 is_less = (cond->op == IR_LT || cond->op == IR_LE);
2476 is_cmp = (cond->op == IR_ULT || cond->op == IR_ULE || cond->op == IR_UGT || cond->op == IR_UGE);
2477 is_less = (cond->op == IR_ULT || cond->op == IR_ULE);
2481 && ((insn->op2 == cond->op1 && insn->op3 == cond->op2)
2482 || (insn->op2 == cond->op2 && insn->op3 == cond->op1))) {
2505 if (next_ref == ref) {
2511 ir_remove_unused_vars(ctx, start1_ref, end1_ref);
2514 ir_remove_unused_vars(ctx, start2_ref, end2_ref);
2518 (is_less ? cond->op1 : cond->op2)
2520 ((start1->op == IR_IF_TRUE) ? insn->op2 : insn->op3)
2522 insn->inputs_count = 2;
2523 if (insn->op2 > insn->op3) {
2524 insn->op1 = insn->op2;
2525 insn->op2 = insn->op3;
2527 insn->op1 = insn->op3;
2531 next->op1 = root->op1;
2554 && ((ctx->
ir_base[insn->op2].op == IR_NEG
2556 && ctx->
ir_base[insn->op2].op1 == insn->op3
2557 && ((cond->op1 == insn->op3
2558 && ir_is_zero(ctx, cond->op2)
2559 && is_less == (start1->op == IR_IF_TRUE))
2560 || (cond->op2 == insn->op3
2561 && ir_is_zero(ctx, cond->op1)
2562 && is_less != (start1->op == IR_IF_TRUE))))
2563 || (ctx->
ir_base[insn->op3].op == IR_NEG
2565 && ctx->
ir_base[insn->op3].op1 == insn->op2
2566 && ((cond->op1 == insn->op2
2567 && ir_is_zero(ctx, cond->op2)
2568 && is_less != (start1->op == IR_IF_TRUE))
2569 || (cond->op2 == insn->op2
2570 && ir_is_zero(ctx, cond->op1)
2571 && is_less == (start1->op == IR_IF_TRUE)))))) {
2595 if (next_ref == ref) {
2601 ir_remove_unused_vars(ctx, start1_ref, end1_ref);
2604 ir_remove_unused_vars(ctx, start2_ref, end2_ref);
2608 insn->inputs_count = 1;
2609 if (ctx->
ir_base[insn->op2].op == IR_NEG) {
2610 neg_ref = insn->op2;
2611 insn->op1 = insn->op3;
2613 neg_ref = insn->op3;
2614 insn->op1 = insn->op2;
2619 next->op1 = root->op1;
2664 if (next_ref == ref) {
2670 ir_remove_unused_vars(ctx, start1_ref, end1_ref);
2673 ir_remove_unused_vars(ctx, start2_ref, end2_ref);
2677 insn->inputs_count = 3;
2678 insn->op1 = cond_ref;
2679 if (start1->op == IR_IF_FALSE) {
2683 next->op1 = root->op1;
2714 return op1->val.u64 ==
op2->val.u64;
2715 }
else if (op == IR_NE) {
2716 return op1->val.u64 !=
op2->val.u64;
2717 }
else if (op == IR_LT) {
2719 return op1->val.i64 <
op2->val.i64;
2721 return op1->val.u64 <
op2->val.u64;
2723 }
else if (op == IR_GE) {
2725 return op1->val.i64 >=
op2->val.i64;
2727 return op1->val.u64 >=
op2->val.u64;
2729 }
else if (op == IR_LE) {
2731 return op1->val.i64 <=
op2->val.i64;
2733 return op1->val.u64 <=
op2->val.u64;
2735 }
else if (op == IR_GT) {
2737 return op1->val.i64 >
op2->val.i64;
2739 return op1->val.u64 >
op2->val.u64;
2741 }
else if (op == IR_ULT) {
2742 return op1->val.u64 <
op2->val.u64;
2743 }
else if (op == IR_UGE) {
2744 return op1->val.u64 >=
op2->val.u64;
2745 }
else if (op == IR_ULE) {
2746 return op1->val.u64 <=
op2->val.u64;
2747 }
else if (op == IR_UGT) {
2748 return op1->val.u64 >
op2->val.u64;
2753 }
else if (
op1->type == IR_DOUBLE) {
2755 return op1->val.d ==
op2->val.d;
2756 }
else if (op == IR_NE) {
2757 return op1->val.d !=
op2->val.d;
2758 }
else if (op == IR_LT) {
2759 return op1->val.d <
op2->val.d;
2760 }
else if (op == IR_GE) {
2761 return op1->val.d >=
op2->val.d;
2762 }
else if (op == IR_LE) {
2763 return op1->val.d <=
op2->val.d;
2764 }
else if (op == IR_GT) {
2765 return op1->val.d >
op2->val.d;
2766 }
else if (op == IR_ULT) {
2767 return !(
op1->val.d >=
op2->val.d);
2768 }
else if (op == IR_UGE) {
2769 return !(
op1->val.d <
op2->val.d);
2770 }
else if (op == IR_ULE) {
2771 return !(
op1->val.d >
op2->val.d);
2772 }
else if (op == IR_UGT) {
2773 return !(
op1->val.d <=
op2->val.d);
2781 return op1->val.f ==
op2->val.f;
2782 }
else if (op == IR_NE) {
2783 return op1->val.f !=
op2->val.f;
2784 }
else if (op == IR_LT) {
2785 return op1->val.f <
op2->val.f;
2786 }
else if (op == IR_GE) {
2787 return op1->val.f >=
op2->val.f;
2788 }
else if (op == IR_LE) {
2789 return op1->val.f <=
op2->val.f;
2790 }
else if (op == IR_GT) {
2791 return op1->val.f >
op2->val.f;
2792 }
else if (op == IR_ULT) {
2793 return !(
op1->val.f >=
op2->val.f);
2794 }
else if (op == IR_UGE) {
2795 return !(
op1->val.f <
op2->val.f);
2796 }
else if (op == IR_ULE) {
2797 return !(
op1->val.f >
op2->val.f);
2798 }
else if (op == IR_UGT) {
2799 return !(
op1->val.f <=
op2->val.f);
2809 ir_ref cond_ref = insn->op2;
2812 if (cond->op == IR_PHI
2813 && cond->inputs_count == 3
2814 && cond->op1 == insn->op1
2817 ir_ref merge_ref = insn->op1;
2821 ir_ref end1_ref = merge->op1, end2_ref = merge->op2;
2825 if (end1->op == IR_END && end2->op == IR_END) {
2826 ir_ref if_true_ref, if_false_ref;
2828 ir_op op = IR_IF_FALSE;
2830 ir_get_true_false_refs(ctx, ref, &if_true_ref, &if_false_ref);
2843 if_true = &ctx->
ir_base[if_true_ref];
2844 if_false = &ctx->
ir_base[if_false_ref];
2874 if_false->op1 = end1_ref;
2877 if_true->op1 = end2_ref;
2910 if_false->op1 = end1_ref;
2911 if_false->op2 = end2_ref;
2913 if_true->optx = IR_BEGIN;
2951 end2->op2 = cond->op3;
2954 merge->op1 = end2_ref;
2961 insn->op1 = merge_ref;
2964 if_true->op1 = end2_ref;
2967 if_false->op1 = end1_ref;
2968 if_false->op2 = ref;
2971 if (ctx->
ir_base[end2->op1].op == IR_BEGIN || ctx->
ir_base[end2->op1].op == IR_MERGE) {
2985 ir_ref cond_ref = insn->op2;
2988 if (cond->op >= IR_EQ && cond->op <= IR_UGT
2992 ir_ref phi_ref = cond->op1;
2995 if (phi->op == IR_PHI
2996 && phi->inputs_count == 3
2997 && phi->op1 == insn->op1
3001 ir_ref merge_ref = insn->op1;
3005 ir_ref end1_ref = merge->op1, end2_ref = merge->op2;
3009 if (end1->op == IR_END && end2->op == IR_END) {
3010 ir_ref if_true_ref, if_false_ref;
3012 ir_op op = IR_IF_FALSE;
3014 ir_get_true_false_refs(ctx, ref, &if_true_ref, &if_false_ref);
3023 if (ir_cmp_is_true(cond->op, &ctx->
ir_base[phi->op2], &ctx->
ir_base[cond->op2])) {
3027 if_true = &ctx->
ir_base[if_true_ref];
3028 if_false = &ctx->
ir_base[if_false_ref];
3031 if (ir_cmp_is_true(cond->op, &ctx->
ir_base[phi->op3], &ctx->
ir_base[cond->op2]) ^ (op == IR_IF_TRUE)) {
3062 if_false->op1 = end1_ref;
3065 if_true->op1 = end2_ref;
3102 if_false->op1 = end1_ref;
3103 if_false->op2 = end2_ref;
3105 if_true->optx = IR_BEGIN;
3146 end2->op2 = insn->op2;
3149 merge->op1 = end2_ref;
3152 cond->op1 = phi->op3;
3157 insn->op1 = merge_ref;
3160 if_true->op1 = end2_ref;
3163 if_false->op1 = end1_ref;
3164 if_false->op2 = ref;
3167 if (ctx->
ir_base[end2->op1].op == IR_BEGIN || ctx->
ir_base[end2->op1].op == IR_MERGE) {
3185 if (use_list->
count == 1) {
3186 ir_try_remove_empty_diamond(ctx, merge_ref, merge, worklist);
3187 }
else if (use_list->
count == 2) {
3188 if (merge->inputs_count == 2) {
3195 if (
next->op == IR_PHI) {
3200 if (phi->op == IR_PHI &&
next->op != IR_PHI) {
3202 if (
next->op2 == phi_ref) {
3203 if (ir_try_split_if(ctx, next_ref,
next, worklist)) {
3209 if (cmp->op >= IR_EQ && cmp->op <= IR_UGT
3210 && cmp->op1 == phi_ref
3214 if (ir_try_split_if_cmp(ctx, next_ref,
next, worklist)) {
3220 ir_optimize_phi(ctx, merge_ref, merge, phi_ref, phi, worklist);
3234 use_insn = &ctx->
ir_base[use];
3235 if (use_insn->op == IR_SEXT || use_insn->op == IR_ZEXT) {
3246 ext_ref = ir_find_ext_use(ctx, phi_ref);
3248 ext_ref = ir_find_ext_use(ctx, op_ref);
3251 ir_try_promote_induction_var_ext(ctx, ext_ref, phi_ref, op_ref, worklist);
3259 if (loop->inputs_count != 2 || ctx->
use_lists[loop_ref].
count <= 1) {
3269 if (use_insn->op == IR_PHI) {
3270 ir_ref op_ref = use_insn->op3;
3273 if (op_insn->op == IR_ADD || op_insn->op == IR_SUB || op_insn->op == IR_MUL) {
3274 if (op_insn->op1 == use) {
3275 if (ir_is_loop_invariant(ctx, op_insn->op2, loop_ref)) {
3276 ir_iter_optimize_induction_var(ctx, use, op_ref, worklist);
3278 }
else if (op_insn->op2 == use) {
3279 if (ir_is_loop_invariant(ctx, op_insn->op1, loop_ref)) {
3280 ir_iter_optimize_induction_var(ctx, use, op_ref, worklist);
3292 while ((condition_insn->op == IR_BITCAST
3293 || condition_insn->op == IR_ZEXT
3294 || condition_insn->op == IR_SEXT)
3296 condition = condition_insn->op1;
3297 condition_insn = &ctx->
ir_base[condition];
3300 if (condition_insn->opt ==
IR_OPT(IR_NOT, IR_BOOL)) {
3302 condition = condition_insn->op1;
3303 condition_insn = &ctx->
ir_base[condition];
3306 if (condition_insn->op == IR_NE &&
IR_IS_CONST_REF(condition_insn->op2)) {
3310 condition = condition_insn->op1;
3311 condition_insn = &ctx->
ir_base[condition];
3313 }
else if (condition_insn->op == IR_EQ &&
IR_IS_CONST_REF(condition_insn->op2)) {
3316 if (condition_insn->op2 ==
IR_TRUE) {
3317 condition = condition_insn->op1;
3318 condition_insn = &ctx->
ir_base[condition];
3320 condition = condition_insn->op1;
3321 condition_insn = &ctx->
ir_base[condition];
3326 while ((condition_insn->op == IR_BITCAST
3327 || condition_insn->op == IR_ZEXT
3328 || condition_insn->op == IR_SEXT)
3330 condition = condition_insn->op1;
3331 condition_insn = &ctx->
ir_base[condition];
3334 if (condition_insn->op == IR_ALLOCA || condition_insn->op == IR_VADDR) {
3348 ir_ref condition = ir_iter_optimize_condition(ctx, insn->op1, insn->op2, &swap);
3357 if (ctx->
ir_base[use].op == IR_IF_TRUE) {
3358 ctx->
ir_base[use].op = IR_IF_FALSE;
3360 ctx->
ir_base[use].op = IR_IF_TRUE;
3362 ctx->
ir_base[use].op = IR_IF_TRUE;
3364 ctx->
ir_base[use].op = IR_IF_FALSE;
3378 ir_ref if_true_ref, if_false_ref;
3388 ir_get_true_false_refs(ctx, ref, &if_true_ref, &if_false_ref);
3389 if_true = &ctx->
ir_base[if_true_ref];
3390 if_false = &ctx->
ir_base[if_false_ref];
3391 if_true->op = IR_BEGIN;
3392 if_false->op = IR_BEGIN;
3403 }
else if (insn->op2 != condition) {
3411 ir_ref condition = ir_iter_optimize_condition(ctx, insn->op1, insn->op2, &swap);
3414 if (insn->op == IR_GUARD) {
3415 insn->op = IR_GUARD_NOT;
3417 insn->op = IR_GUARD;
3422 if (insn->op == IR_GUARD) {
3436 if (ir_is_dead(ctx, insn->op2)) {
3444 ir_iter_remove_insn(ctx, insn->op3, worklist);
3461 if (insn->op2 != condition) {
3475 if (insn->op == IR_PHI) {
3478 ir_iter_remove_insn(ctx, i, worklist);
3483 if (insn->type == IR_FLOAT) {
3484 if (ir_may_promote_d2f(ctx, insn->op1)) {
3485 ir_ref ref = ir_promote_d2f(ctx, insn->op1, i, worklist);
3487 ir_iter_replace_insn(ctx, i, ref, worklist);
3491 if (ir_may_promote_f2d(ctx, insn->op1)) {
3492 ir_ref ref = ir_promote_f2d(ctx, insn->op1, i, worklist);
3494 ir_iter_replace_insn(ctx, i, ref, worklist);
3500 if (ctx->
ir_base[insn->op1].type == IR_DOUBLE) {
3501 if (ir_may_promote_d2f(ctx, insn->op1)) {
3502 insn->op1 = ir_promote_d2f(ctx, insn->op1, i, worklist);
3505 if (ir_may_promote_f2d(ctx, insn->op1)) {
3506 insn->op1 = ir_promote_f2d(ctx, insn->op1, i, worklist);
3511 if (ir_may_promote_trunc(ctx, insn->type, insn->op1)) {
3512 ir_ref ref = ir_promote_i2i(ctx, insn->type, insn->op1, i, worklist);
3514 ir_iter_replace_insn(ctx, i, ref, worklist);
3520 if (ir_try_promote_ext(ctx, i, insn, worklist)) {
3528 ir_iter_fold(ctx, i, worklist);
3535 }
else if (insn->op == IR_BEGIN) {
3536 if (insn->op1 && ctx->
ir_base[insn->op1].op == IR_END) {
3537 ir_merge_blocks(ctx, insn->op1, i, worklist);
3539 }
else if (insn->op == IR_MERGE) {
3540 ir_iter_optimize_merge(ctx, i, insn, worklist);
3541 }
else if (insn->op == IR_LOOP_BEGIN) {
3542 ir_iter_optimize_loop(ctx, i, insn, worklist);
3544 }
else if (ir_is_dead_load(ctx, i)) {
3554 ir_iter_remove_insn(ctx, i, worklist);
3555 }
else if (insn->op == IR_LOAD) {
3570 if (val_insn->type == insn->type) {
3571 ir_iter_replace_insn(ctx, i,
val, worklist);
3575 if (ir_is_dead(ctx, insn->op2)) {
3584 insn->optx =
IR_OPTX(IR_BITCAST, insn->type, 1);
3587 insn->optx =
IR_OPTX(IR_TRUNC, insn->type, 1);
3594 }
else if (insn->op == IR_STORE) {
3596 goto remove_mem_insn;
3603 if (val_insn->op == IR_BITCAST
3605 insn->op3 = val_insn->op1;
3611 ir_iter_remove_insn(ctx,
val, worklist);
3619 }
else if (insn->op == IR_VLOAD) {
3622 goto remove_aliased_load;
3624 }
else if (insn->op == IR_VSTORE) {
3626 goto remove_mem_insn;
3628 goto remove_bitcast;
3630 }
else if (insn->op == IR_IF) {
3631 ir_iter_optimize_if(ctx, i, insn, worklist);
3632 }
else if (insn->op == IR_GUARD || insn->op == IR_GUARD_NOT) {
3633 ir_iter_optimize_guard(ctx, i, insn, worklist);
3648 ir_sccp_analyze(ctx, _values, &sccp_worklist, &iter_worklist);
3649 ir_sccp_transform(ctx, _values, &sccp_worklist, &iter_worklist);
fprintf($stream, string $format, mixed ... $values)
prev(array|object &$array)
copy(string $from, string $to, $context=null)
count(Countable|array $value, int $mode=COUNT_NORMAL)
const php_stream_filter_ops * ops
bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref)
void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use)
ir_ref ir_check_dominating_predicates(ir_ctx *ctx, ir_ref ref, ir_ref condition)
ir_ref ir_const_ex(ir_ctx *ctx, ir_val val, uint8_t type, uint32_t optx)
ir_ref ir_const_double(ir_ctx *ctx, double c)
ir_ref ir_emit1(ir_ctx *ctx, uint32_t opt, ir_ref op1)
ir_ref ir_find_aliasing_load(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref addr)
ir_ref ir_find_aliasing_vload(ir_ctx *ctx, ir_ref ref, ir_type type, ir_ref var)
ir_ref ir_find_aliasing_vstore(ir_ctx *ctx, ir_ref ref, ir_ref var, ir_ref val)
ir_ref ir_const(ir_ctx *ctx, ir_val val, uint8_t type)
ir_ref ir_find_aliasing_store(ir_ctx *ctx, ir_ref ref, ir_ref addr, ir_ref val)
const uint32_t ir_op_flags[IR_LAST_OP]
void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref)
void ir_print_const(const ir_ctx *ctx, const ir_insn *insn, FILE *f, bool quoted)
void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref ref)
ir_ref ir_folding(ir_ctx *ctx, uint32_t opt, ir_ref op1, ir_ref op2, ir_ref op3, ir_insn *op1_insn, ir_insn *op2_insn, ir_insn *op3_insn)
ir_ref ir_const_float(ir_ctx *ctx, float c)
const uint8_t ir_type_size[IR_LAST_TYPE]
#define IR_OPTX(op, type, n)
#define IR_IS_TYPE_INT(t)
IR_ALWAYS_INLINE uint32_t ir_insn_find_op(const ir_insn *insn, ir_ref val)
#define IR_IS_TYPE_UNSIGNED(t)
IR_ALWAYS_INLINE ir_ref ir_insn_op(const ir_insn *insn, int32_t n)
#define IR_IS_CONST_REF(ref)
#define IR_IS_TYPE_SIGNED(t)
IR_ALWAYS_INLINE void ir_insn_set_op(ir_insn *insn, int32_t n, ir_ref val)
struct _ir_use_list ir_use_list
IR_ALWAYS_INLINE void ir_bitqueue_grow(ir_bitqueue *q, uint32_t n)
#define SWAP_REFS(_ref1, _ref2)
IR_ALWAYS_INLINE bool ir_const_is_true(const ir_insn *v)
#define IR_IS_CONST_OP(op)
ir_bitset_base_t * ir_bitset
#define SWAP_INSNS(_insn1, _insn2)
IR_ALWAYS_INLINE void ir_bitqueue_del(ir_bitqueue *q, uint32_t n)
IR_ALWAYS_INLINE void ir_bitqueue_add(ir_bitqueue *q, uint32_t n)
#define IR_OPND_CONTROL_DEP
#define IR_OP_FLAG_MEM_MASK
IR_ALWAYS_INLINE ir_bitset ir_bitset_malloc(uint32_t n)
IR_ALWAYS_INLINE void ir_bitset_incl(ir_bitset set, uint32_t n)
#define IR_IS_SYM_CONST(op)
#define IR_IS_BB_START(op)
#define IR_IS_FOLDABLE_OP(op)
IR_ALWAYS_INLINE void ir_bitqueue_init(ir_bitqueue *q, uint32_t n)
#define IR_OPND_KIND(flags, i)
IR_ALWAYS_INLINE int ir_bitqueue_pop(ir_bitqueue *q)
#define IR_INPUT_EDGES_COUNT(flags)
IR_ALWAYS_INLINE bool ir_ref_is_true(ir_ctx *ctx, ir_ref ref)
#define IR_OP_FLAG_CONTROL
IR_ALWAYS_INLINE void ir_bitqueue_free(ir_bitqueue *q)
IR_ALWAYS_INLINE ir_ref ir_next_control(const ir_ctx *ctx, ir_ref ref)
#define IR_OP_FLAG_BB_START
struct _ir_bitqueue ir_bitqueue
#define IR_OP_FLAG_BB_END
#define IR_OP_FLAG_MEM_LOAD
#define IR_OP_FLAG_TERMINATOR
#define IR_OP_HAS_VAR_INPUTS(flags)
void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist)
IR_ALWAYS_INLINE void ir_sccp_add_uses(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref)
#define IR_MAKE_BOTTOM_EX(ref)
#define IR_IS_REACHABLE(ref)
IR_ALWAYS_INLINE bool ir_sccp_meet(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref, ir_ref val)
#define ir_sccp_trace_start(c, v, i)
#define CHECK_LIST(_values, ref)
#define ir_sccp_trace_end(c, v, i)
void ir_iter_update_op(ir_ctx *ctx, ir_ref ref, uint32_t idx, ir_ref new_val, ir_bitqueue *worklist)
IR_ALWAYS_INLINE void ir_sccp_make_bottom_ex(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref)
IR_ALWAYS_INLINE ir_ref ir_sccp_identity(ir_ctx *ctx, ir_insn *_values, ir_ref a)
IR_ALWAYS_INLINE bool _ir_is_reachable_ctrl(ir_ctx *ctx, ir_insn *_values, ir_ref ref)
IR_ALWAYS_INLINE void ir_sccp_add_input(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref)
void ir_iter_replace(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bitqueue *worklist)
#define IR_IS_BOTTOM(ref)
IR_ALWAYS_INLINE bool ir_sccp_meet_const(ir_ctx *ctx, ir_insn *_values, ir_bitqueue *worklist, ir_ref ref, ir_insn *val_insn)
#define IR_MAKE_BOTTOM(ref)
unsigned const char * end
struct php_pcntl_pending_signal * head
struct php_pcntl_pending_signal * tail
#define EXPECTED(condition)