Lines Matching refs:ctx

38 static ir_ref ir_sccp_fold(ir_ctx *ctx, ir_insn *_values, ir_ref res, uint32_t opt, ir_ref op1, ir_…  in ir_sccp_fold()  argument
49 op1_insn = (op1 > 0 && IR_IS_CONST_OP(_values[op1].op)) ? _values + op1 : ctx->ir_base + op1; in ir_sccp_fold()
50 op2_insn = (op2 > 0 && IR_IS_CONST_OP(_values[op2].op)) ? _values + op2 : ctx->ir_base + op2; in ir_sccp_fold()
51 op3_insn = (op3 > 0 && IR_IS_CONST_OP(_values[op3].op)) ? _values + op3 : ctx->ir_base + op3; in ir_sccp_fold()
53 switch (ir_folding(ctx, opt, op1, op2, op3, op1_insn, op2_insn, op3_insn)) { in ir_sccp_fold()
55 opt = ctx->fold_insn.optx; in ir_sccp_fold()
56 op1 = ctx->fold_insn.op1; in ir_sccp_fold()
57 op2 = ctx->fold_insn.op2; in ir_sccp_fold()
58 op3 = ctx->fold_insn.op3; in ir_sccp_fold()
64 op1 = ctx->fold_insn.op1; in ir_sccp_fold()
68 insn = (op1 > 0 && IR_IS_CONST_OP(_values[op1].op)) ? _values + op1 : ctx->ir_base + op1; in ir_sccp_fold()
92 insn = &ctx->fold_insn; in ir_sccp_fold()
110 static bool ir_sccp_meet_phi(ir_ctx *ctx, ir_insn *_values, ir_ref i, ir_insn *insn, ir_bitqueue *w… in ir_sccp_meet_phi() argument
129 merge_input = ctx->ir_base[insn->op1].ops + 1; in ir_sccp_meet_phi()
138 v = &ctx->ir_base[input]; in ir_sccp_meet_phi()
186 v = &ctx->ir_base[input]; in ir_sccp_meet_phi()
235 _values[i].optx = IR_OPT(IR_COPY, ctx->ir_base[new_copy].type); in ir_sccp_meet_phi()
254 static bool ir_is_dead_load_ex(ir_ctx *ctx, ir_ref ref, uint32_t flags, ir_insn *insn) in ir_is_dead_load_ex() argument
257 return ctx->use_lists[ref].count == 1; in ir_is_dead_load_ex()
259 return ctx->use_lists[ref].count == 1; in ir_is_dead_load_ex()
264 static bool ir_is_dead_load(ir_ctx *ctx, ir_ref ref) in ir_is_dead_load() argument
266 if (ctx->use_lists[ref].count == 1) { in ir_is_dead_load()
267 uint32_t flags = ir_op_flags[ctx->ir_base[ref].op]; in ir_is_dead_load()
271 } else if (ctx->ir_base[ref].op == IR_ALLOCA) { in ir_is_dead_load()
278 static bool ir_is_dead(ir_ctx *ctx, ir_ref ref) in ir_is_dead() argument
280 if (ctx->use_lists[ref].count == 0) { in ir_is_dead()
281 return IR_IS_FOLDABLE_OP(ctx->ir_base[ref].op); in ir_is_dead()
283 return ir_is_dead_load(ctx, ref); in ir_is_dead()
288 static ir_ref ir_find1(ir_ctx *ctx, uint32_t optx, ir_ref op1) in ir_find1() argument
292 ir_use_list *use_list = &ctx->use_lists[op1]; in ir_find1()
295 for (p = ctx->use_edges + use_list->refs; n > 0; p++, n--) { in ir_find1()
297 ir_insn *use_insn = &ctx->ir_base[use]; in ir_find1()
307 static bool ir_sccp_is_true(ir_ctx *ctx, ir_insn *_values, ir_ref a) in ir_sccp_is_true() argument
309 ir_insn *v = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a]; in ir_sccp_is_true()
314 static bool ir_sccp_is_equal(ir_ctx *ctx, ir_insn *_values, ir_ref a, ir_ref b) in ir_sccp_is_equal() argument
316 ir_insn *v1 = IR_IS_CONST_REF(a) ? &ctx->ir_base[a] : &_values[a]; in ir_sccp_is_equal()
317 ir_insn *v2 = IR_IS_CONST_REF(b) ? &ctx->ir_base[b] : &_values[b]; in ir_sccp_is_equal()
324 static void ir_sccp_make_nop(ir_ctx *ctx, ir_ref ref) in ir_sccp_make_nop() argument
330 insn = &ctx->ir_base[ref]; in ir_sccp_make_nop()
338 static void ir_sccp_remove_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_bitqueue *worklist) in ir_sccp_remove_insn() argument
344 insn = &ctx->ir_base[ref]; in ir_sccp_remove_insn()
352 ir_use_list_remove_all(ctx, input, ref); in ir_sccp_remove_insn()
353 if (ir_is_dead(ctx, input)) { in ir_sccp_remove_insn()
361 static void ir_sccp_remove_insn2(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) in ir_sccp_remove_insn2() argument
367 insn = &ctx->ir_base[ref]; in ir_sccp_remove_insn2()
374 ir_use_list_remove_all(ctx, input, ref); in ir_sccp_remove_insn2()
375 if (ir_is_dead(ctx, input)) { in ir_sccp_remove_insn2()
378 } else if (ctx->ir_base[input].op == IR_PHI && ctx->use_lists[input].count == 1) { in ir_sccp_remove_insn2()
380 ir_bitqueue_add(worklist, ctx->ir_base[input].op1); in ir_sccp_remove_insn2()
386 static void ir_sccp_replace_insn(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_ref new_ref, ir_bitq… in ir_sccp_replace_insn() argument
394 insn = &ctx->ir_base[ref]; in ir_sccp_replace_insn()
402 ir_use_list_remove_all(ctx, input, ref); in ir_sccp_replace_insn()
403 if (ir_is_dead(ctx, input)) { in ir_sccp_replace_insn()
410 use_list = &ctx->use_lists[ref]; in ir_sccp_replace_insn()
412 for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { in ir_sccp_replace_insn()
415 insn = &ctx->ir_base[use]; in ir_sccp_replace_insn()
424 if (ir_use_list_add(ctx, new_ref, use)) { in ir_sccp_replace_insn()
426 use_list = &ctx->use_lists[ref]; in ir_sccp_replace_insn()
428 p = &ctx->use_edges[use_list->refs + j]; in ir_sccp_replace_insn()
443 static void ir_sccp_replace_insn2(ir_ctx *ctx, ir_ref ref, ir_ref new_ref, ir_bitqueue *worklist) in ir_sccp_replace_insn2() argument
451 insn = &ctx->ir_base[ref]; in ir_sccp_replace_insn2()
458 ir_use_list_remove_all(ctx, input, ref); in ir_sccp_replace_insn2()
459 if (ir_is_dead(ctx, input)) { in ir_sccp_replace_insn2()
462 } else if (ctx->ir_base[input].op == IR_PHI && ctx->use_lists[input].count == 1) { in ir_sccp_replace_insn2()
469 use_list = &ctx->use_lists[ref]; in ir_sccp_replace_insn2()
471 for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { in ir_sccp_replace_insn2()
473 insn = &ctx->ir_base[use]; in ir_sccp_replace_insn2()
482 if (ir_use_list_add(ctx, new_ref, use)) { in ir_sccp_replace_insn2()
484 use_list = &ctx->use_lists[ref]; in ir_sccp_replace_insn2()
486 p = &ctx->use_edges[use_list->refs + j]; in ir_sccp_replace_insn2()
497 static void ir_sccp_fold2(ir_ctx *ctx, ir_ref ref, ir_bitqueue *worklist) in ir_sccp_fold2() argument
503 insn = &ctx->ir_base[ref]; in ir_sccp_fold2()
510 op1_insn = ctx->ir_base + op1; in ir_sccp_fold2()
511 op2_insn = ctx->ir_base + op2; in ir_sccp_fold2()
512 op3_insn = ctx->ir_base + op3; in ir_sccp_fold2()
514 switch (ir_folding(ctx, opt, op1, op2, op3, op1_insn, op2_insn, op3_insn)) { in ir_sccp_fold2()
516 opt = ctx->fold_insn.optx; in ir_sccp_fold2()
517 op1 = ctx->fold_insn.op1; in ir_sccp_fold2()
518 op2 = ctx->fold_insn.op2; in ir_sccp_fold2()
519 op3 = ctx->fold_insn.op3; in ir_sccp_fold2()
522 insn = &ctx->ir_base[ref]; in ir_sccp_fold2()
523 if (insn->opt != ctx->fold_insn.opt in ir_sccp_fold2()
524 || insn->op1 != ctx->fold_insn.op1 in ir_sccp_fold2()
525 || insn->op2 != ctx->fold_insn.op2 in ir_sccp_fold2()
526 || insn->op3 != ctx->fold_insn.op3) { in ir_sccp_fold2()
531 insn->optx = ctx->fold_insn.opt; in ir_sccp_fold2()
534 if (insn->op1 != ctx->fold_insn.op1) { in ir_sccp_fold2()
536 ir_use_list_remove_one(ctx, insn->op1, ref); in ir_sccp_fold2()
538 if (ctx->fold_insn.op1 > 0) { in ir_sccp_fold2()
539 ir_use_list_add(ctx, ctx->fold_insn.op1, ref); in ir_sccp_fold2()
542 if (insn->op2 != ctx->fold_insn.op2) { in ir_sccp_fold2()
544 ir_use_list_remove_one(ctx, insn->op2, ref); in ir_sccp_fold2()
546 if (ctx->fold_insn.op2 > 0) { in ir_sccp_fold2()
547 ir_use_list_add(ctx, ctx->fold_insn.op2, ref); in ir_sccp_fold2()
550 if (insn->op3 != ctx->fold_insn.op3) { in ir_sccp_fold2()
552 ir_use_list_remove_one(ctx, insn->op3, ref); in ir_sccp_fold2()
554 if (ctx->fold_insn.op3 > 0) { in ir_sccp_fold2()
555 ir_use_list_add(ctx, ctx->fold_insn.op3, ref); in ir_sccp_fold2()
558 insn->op1 = ctx->fold_insn.op1; in ir_sccp_fold2()
559 insn->op2 = ctx->fold_insn.op2; in ir_sccp_fold2()
560 insn->op3 = ctx->fold_insn.op3; in ir_sccp_fold2()
562 use_list = &ctx->use_lists[ref]; in ir_sccp_fold2()
564 for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { in ir_sccp_fold2()
571 op1 = ctx->fold_insn.op1; in ir_sccp_fold2()
572 ir_sccp_replace_insn2(ctx, ref, op1, worklist); in ir_sccp_fold2()
575 op1 = ir_const(ctx, ctx->fold_insn.val, ctx->fold_insn.type); in ir_sccp_fold2()
576 ir_sccp_replace_insn2(ctx, ref, op1, worklist); in ir_sccp_fold2()
584 static void ir_sccp_remove_if(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_ref dst) in ir_sccp_remove_if() argument
589 insn = &ctx->ir_base[ref]; in ir_sccp_remove_if()
590 if (ctx->use_lists[dst].count == 1) { in ir_sccp_remove_if()
591 next = ctx->use_edges[ctx->use_lists[dst].refs]; in ir_sccp_remove_if()
592 next_insn = &ctx->ir_base[next]; in ir_sccp_remove_if()
595 ir_use_list_replace_one(ctx, insn->op1, ref, next); in ir_sccp_remove_if()
597 ir_sccp_make_nop(ctx, ref); in ir_sccp_remove_if()
598 ir_sccp_make_nop(ctx, dst); in ir_sccp_remove_if()
602 next_insn = &ctx->ir_base[dst]; in ir_sccp_remove_if()
607 static void ir_sccp_remove_unfeasible_merge_inputs(ir_ctx *ctx, ir_insn *_values, ir_ref ref, ir_re… in ir_sccp_remove_unfeasible_merge_inputs() argument
614 insn = &ctx->ir_base[ref]; in ir_sccp_remove_unfeasible_merge_inputs()
622 ir_insn *input_insn = &ctx->ir_base[input]; in ir_sccp_remove_unfeasible_merge_inputs()
632 use_list = &ctx->use_lists[ref]; in ir_sccp_remove_unfeasible_merge_inputs()
634 next = ctx->use_edges[use_list->refs]; in ir_sccp_remove_unfeasible_merge_inputs()
635 next_insn = &ctx->ir_base[next]; in ir_sccp_remove_unfeasible_merge_inputs()
637 for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { in ir_sccp_remove_unfeasible_merge_inputs()
639 use_insn = &ctx->ir_base[use]; in ir_sccp_remove_unfeasible_merge_inputs()
649 while (!IR_IS_BB_START(ctx->ir_base[region].op)) { in ir_sccp_remove_unfeasible_merge_inputs()
650 region = ctx->ir_base[region].op1; in ir_sccp_remove_unfeasible_merge_inputs()
653 ir_use_list_add(ctx, region, use); in ir_sccp_remove_unfeasible_merge_inputs()
654 p = &ctx->use_edges[use_list->refs + k]; in ir_sccp_remove_unfeasible_merge_inputs()
661 ir_use_list_replace_one(ctx, prev, input, next); in ir_sccp_remove_unfeasible_merge_inputs()
663 ir_sccp_make_nop(ctx, ref); in ir_sccp_remove_unfeasible_merge_inputs()
664 ir_sccp_make_nop(ctx, input); in ir_sccp_remove_unfeasible_merge_inputs()
707 use_list = &ctx->use_lists[ref]; in ir_sccp_remove_unfeasible_merge_inputs()
709 for (k = 0, p = &ctx->use_edges[use_list->refs]; k < use_list->count; k++, p++) { in ir_sccp_remove_unfeasible_merge_inputs()
711 use_insn = &ctx->ir_base[use]; in ir_sccp_remove_unfeasible_merge_inputs()
724 ir_use_list_remove_one(ctx, input, use); in ir_sccp_remove_unfeasible_merge_inputs()
739 static bool ir_may_promote_d2f(ir_ctx *ctx, ir_ref ref) in ir_may_promote_d2f() argument
741 ir_insn *insn = &ctx->ir_base[ref]; in ir_may_promote_d2f()
754 return ctx->use_lists[ref].count == 1 && in ir_may_promote_d2f()
755 ir_may_promote_d2f(ctx, insn->op1); in ir_may_promote_d2f()
762 return ctx->use_lists[ref].count == 1 && in ir_may_promote_d2f()
763 ir_may_promote_d2f(ctx, insn->op1) && in ir_may_promote_d2f()
764 ir_may_promote_d2f(ctx, insn->op2); in ir_may_promote_d2f()
772 static bool ir_may_promote_f2d(ir_ctx *ctx, ir_ref ref) in ir_may_promote_f2d() argument
774 ir_insn *insn = &ctx->ir_base[ref]; in ir_may_promote_f2d()
784 return ctx->use_lists[ref].count == 1; in ir_may_promote_f2d()
787 return ctx->use_lists[ref].count == 1 && in ir_may_promote_f2d()
788 ir_may_promote_f2d(ctx, insn->op1); in ir_may_promote_f2d()
795 return ctx->use_lists[ref].count == 1 && in ir_may_promote_f2d()
796 ir_may_promote_f2d(ctx, insn->op1) && in ir_may_promote_f2d()
797 ir_may_promote_f2d(ctx, insn->op2); in ir_may_promote_f2d()
805 static ir_ref ir_promote_d2f(ir_ctx *ctx, ir_ref ref, ir_ref use) in ir_promote_d2f() argument
807 ir_insn *insn = &ctx->ir_base[ref]; in ir_promote_d2f()
812 return ir_const_float(ctx, (float)insn->val.d); in ir_promote_d2f()
816 count = ctx->use_lists[ref].count; in ir_promote_d2f()
817 ir_use_list_remove_all(ctx, ref, use); in ir_promote_d2f()
818 if (ctx->use_lists[ref].count == 0) { in ir_promote_d2f()
819 ir_use_list_replace_one(ctx, insn->op1, ref, use); in ir_promote_d2f()
822 ir_use_list_add(ctx, insn->op1, use); in ir_promote_d2f()
829 ir_use_list_add(ctx, insn->op1, use); in ir_promote_d2f()
830 count -= ctx->use_lists[ref].count; in ir_promote_d2f()
833 ir_use_list_add(ctx, insn->op1, use); in ir_promote_d2f()
843 insn->op1 = ir_promote_d2f(ctx, insn->op1, ref); in ir_promote_d2f()
853 insn->op2 = insn->op1 = ir_promote_d2f(ctx, insn->op1, ref); in ir_promote_d2f()
855 insn->op1 = ir_promote_d2f(ctx, insn->op1, ref); in ir_promote_d2f()
856 insn->op2 = ir_promote_d2f(ctx, insn->op2, ref); in ir_promote_d2f()
868 static ir_ref ir_promote_f2d(ir_ctx *ctx, ir_ref ref, ir_ref use) in ir_promote_f2d() argument
870 ir_insn *insn = &ctx->ir_base[ref]; in ir_promote_f2d()
876 return ir_const_double(ctx, (double)insn->val.f); in ir_promote_f2d()
880 count = ctx->use_lists[ref].count; in ir_promote_f2d()
881 ir_use_list_remove_all(ctx, ref, use); in ir_promote_f2d()
882 if (ctx->use_lists[ref].count == 0) { in ir_promote_f2d()
883 ir_use_list_replace_one(ctx, insn->op1, ref, use); in ir_promote_f2d()
886 ir_use_list_add(ctx, insn->op1, use); in ir_promote_f2d()
893 ir_use_list_add(ctx, insn->op1, use); in ir_promote_f2d()
894 count -= ctx->use_lists[ref].count; in ir_promote_f2d()
897 ir_use_list_add(ctx, insn->op1, use); in ir_promote_f2d()
903 old_ref = ir_find1(ctx, IR_OPTX(IR_INT2FP, IR_DOUBLE, 1), insn->op1); in ir_promote_f2d()
905 IR_ASSERT(ctx->use_lists[ref].count == 1); in ir_promote_f2d()
906 ir_use_list_remove_one(ctx, insn->op1, ref); in ir_promote_f2d()
909 ir_use_list_add(ctx, old_ref, use); in ir_promote_f2d()
916 insn->op1 = ir_promote_f2d(ctx, insn->op1, ref); in ir_promote_f2d()
926 insn->op2 = insn->op1 = ir_promote_f2d(ctx, insn->op1, ref); in ir_promote_f2d()
928 insn->op1 = ir_promote_f2d(ctx, insn->op1, ref); in ir_promote_f2d()
929 insn->op2 = ir_promote_f2d(ctx, insn->op2, ref); in ir_promote_f2d()
941 static bool ir_may_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref) in ir_may_promote_i2i() argument
943 ir_insn *insn = &ctx->ir_base[ref]; in ir_may_promote_i2i()
951 return ctx->ir_base[insn->op1].type == type; in ir_may_promote_i2i()
955 return ctx->use_lists[ref].count == 1 && in ir_may_promote_i2i()
956 ir_may_promote_i2i(ctx, type, insn->op1); in ir_may_promote_i2i()
966 return ctx->use_lists[ref].count == 1 && in ir_may_promote_i2i()
967 ir_may_promote_i2i(ctx, type, insn->op1) && in ir_may_promote_i2i()
968 ir_may_promote_i2i(ctx, type, insn->op2); in ir_may_promote_i2i()
976 static ir_ref ir_promote_i2i(ir_ctx *ctx, ir_type type, ir_ref ref, ir_ref use) in ir_promote_i2i() argument
978 ir_insn *insn = &ctx->ir_base[ref]; in ir_promote_i2i()
982 return ir_const(ctx, insn->val, type); in ir_promote_i2i()
987 count = ctx->use_lists[ref].count; in ir_promote_i2i()
988 ir_use_list_remove_all(ctx, ref, use); in ir_promote_i2i()
989 if (ctx->use_lists[ref].count == 0) { in ir_promote_i2i()
990 ir_use_list_replace_one(ctx, insn->op1, ref, use); in ir_promote_i2i()
993 ir_use_list_add(ctx, insn->op1, use); in ir_promote_i2i()
1000 ir_use_list_add(ctx, insn->op1, use); in ir_promote_i2i()
1001 count -= ctx->use_lists[ref].count; in ir_promote_i2i()
1004 ir_use_list_add(ctx, insn->op1, use); in ir_promote_i2i()
1012 insn->op1 = ir_promote_i2i(ctx, type, insn->op1, ref); in ir_promote_i2i()
1025 insn->op2 = insn->op1 = ir_promote_i2i(ctx, type, insn->op1, ref); in ir_promote_i2i()
1027 insn->op1 = ir_promote_i2i(ctx, type, insn->op1, ref); in ir_promote_i2i()
1028 insn->op2 = ir_promote_i2i(ctx, type, insn->op2, ref); in ir_promote_i2i()
1040 static ir_ref ir_ext_const(ir_ctx *ctx, ir_insn *val_insn, ir_op op, ir_type type) in ir_ext_const() argument
1073 return ir_const(ctx, new_val, type); in ir_ext_const()
1076 static ir_ref ir_ext_ref(ir_ctx *ctx, ir_ref var_ref, ir_ref src_ref, ir_op op, ir_type type, ir_bi… in ir_ext_ref() argument
1082 ref = ir_find1(ctx, optx, src_ref); in ir_ext_ref()
1084 ir_use_list_add(ctx, ref, var_ref); in ir_ext_ref()
1086 ir_use_list_remove_one(ctx, src_ref, var_ref); in ir_ext_ref()
1093 ref = ir_emit1(ctx, optx, src_ref); in ir_ext_ref()
1094 ctx->use_lists = ir_mem_realloc(ctx->use_lists, ctx->insns_count * sizeof(ir_use_list)); in ir_ext_ref()
1095 ctx->use_lists[ref].count = 0; in ir_ext_ref()
1096 ctx->use_lists[ref].refs = IR_UNUSED; in ir_ext_ref()
1097 ir_use_list_add(ctx, ref, var_ref); in ir_ext_ref()
1099 ir_use_list_replace_one(ctx, src_ref, var_ref, ref); in ir_ext_ref()
1106 static bool ir_try_promote_ext(ir_ctx *ctx, ir_ref ext_ref, ir_insn *insn, ir_bitqueue *worklist) in ir_try_promote_ext() argument
1111 ir_insn *phi_insn = &ctx->ir_base[ref]; in ir_try_promote_ext()
1119 || ctx->ir_base[phi_insn->op1].op != IR_LOOP_BEGIN) { in ir_try_promote_ext()
1124 op_insn = &ctx->ir_base[op_ref]; in ir_try_promote_ext()
1127 || ctx->use_lists[op_ref].count != 1) { in ir_try_promote_ext()
1132 use_list = &ctx->use_lists[ref]; in ir_try_promote_ext()
1134 for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { in ir_try_promote_ext()
1139 ir_insn *use_insn = &ctx->ir_base[use]; in ir_try_promote_ext()
1155 for (n = 0; n < ctx->use_lists[ref].count; n++) { in ir_try_promote_ext()
1157 use = ctx->use_edges[ctx->use_lists[ref].refs + n]; in ir_try_promote_ext()
1161 ir_insn *use_insn = &ctx->ir_base[use]; in ir_try_promote_ext()
1171 && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op1].op)) { in ir_try_promote_ext()
1172 ctx->ir_base[use].op1 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op1], op, type); in ir_try_promote_ext()
1174 ctx->ir_base[use].op1 = ir_ext_ref(ctx, use, use_insn->op1, op, type, worklist); in ir_try_promote_ext()
1179 && !IR_IS_SYM_CONST(ctx->ir_base[use_insn->op2].op)) { in ir_try_promote_ext()
1180 ctx->ir_base[use].op2 = ir_ext_const(ctx, &ctx->ir_base[use_insn->op2], op, type); in ir_try_promote_ext()
1182 ctx->ir_base[use].op2 = ir_ext_ref(ctx, use, use_insn->op2, op, type, worklist); in ir_try_promote_ext()
1188 ir_sccp_replace_insn2(ctx, ext_ref, ref, worklist); in ir_try_promote_ext()
1190 phi_insn = &ctx->ir_base[ref]; in ir_try_promote_ext()
1192 && !IR_IS_SYM_CONST(ctx->ir_base[phi_insn->op2].op)) { in ir_try_promote_ext()
1193 ctx->ir_base[ref].op2 = ir_ext_const(ctx, &ctx->ir_base[phi_insn->op2], op, type); in ir_try_promote_ext()
1195 ctx->ir_base[ref].op2 = ir_ext_ref(ctx, ref, phi_insn->op2, op, type, worklist); in ir_try_promote_ext()
1201 static void ir_get_true_false_refs(const ir_ctx *ctx, ir_ref if_ref, ir_ref *if_true_ref, ir_ref *i… in ir_get_true_false_refs() argument
1203 ir_use_list *use_list = &ctx->use_lists[if_ref]; in ir_get_true_false_refs()
1204 ir_ref *p = &ctx->use_edges[use_list->refs]; in ir_get_true_false_refs()
1207 if (ctx->ir_base[*p].op == IR_IF_TRUE) { in ir_get_true_false_refs()
1208 IR_ASSERT(ctx->ir_base[*(p + 1)].op == IR_IF_FALSE); in ir_get_true_false_refs()
1212 IR_ASSERT(ctx->ir_base[*p].op == IR_IF_FALSE); in ir_get_true_false_refs()
1213 IR_ASSERT(ctx->ir_base[*(p + 1)].op == IR_IF_TRUE); in ir_get_true_false_refs()
1219 static void ir_merge_blocks(ir_ctx *ctx, ir_ref end, ir_ref begin, ir_bitqueue *worklist2) in ir_merge_blocks() argument
1224 IR_ASSERT(ctx->ir_base[begin].op == IR_BEGIN); in ir_merge_blocks()
1225 IR_ASSERT(ctx->ir_base[end].op == IR_END); in ir_merge_blocks()
1226 IR_ASSERT(ctx->ir_base[begin].op1 == end); in ir_merge_blocks()
1227 IR_ASSERT(ctx->use_lists[end].count == 1); in ir_merge_blocks()
1229 prev = ctx->ir_base[end].op1; in ir_merge_blocks()
1231 use_list = &ctx->use_lists[begin]; in ir_merge_blocks()
1233 next = ctx->use_edges[use_list->refs]; in ir_merge_blocks()
1236 MAKE_NOP(&ctx->ir_base[begin]); CLEAR_USES(begin); in ir_merge_blocks()
1237 MAKE_NOP(&ctx->ir_base[end]); CLEAR_USES(end); in ir_merge_blocks()
1240 ctx->ir_base[next].op1 = prev; in ir_merge_blocks()
1241 ir_use_list_replace_one(ctx, prev, end, next); in ir_merge_blocks()
1243 if (ctx->ir_base[prev].op == IR_BEGIN || ctx->ir_base[prev].op == IR_MERGE) { in ir_merge_blocks()
1248 static void ir_remove_unused_vars(ir_ctx *ctx, ir_ref start, ir_ref end) in ir_remove_unused_vars() argument
1250 ir_use_list *use_list = &ctx->use_lists[start]; in ir_remove_unused_vars()
1253 for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { in ir_remove_unused_vars()
1256 ir_insn *use_insn = &ctx->ir_base[use]; in ir_remove_unused_vars()
1258 IR_ASSERT(ctx->use_lists[use].count == 0); in ir_remove_unused_vars()
1264 static bool ir_try_remove_empty_diamond(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue *workli… in ir_try_remove_empty_diamond() argument
1268 ir_insn *end1 = &ctx->ir_base[end1_ref]; in ir_try_remove_empty_diamond()
1269 ir_insn *end2 = &ctx->ir_base[end2_ref]; in ir_try_remove_empty_diamond()
1276 ir_insn *start1 = &ctx->ir_base[start1_ref]; in ir_try_remove_empty_diamond()
1277 ir_insn *start2 = &ctx->ir_base[start2_ref]; in ir_try_remove_empty_diamond()
1284 ir_insn *root = &ctx->ir_base[root_ref]; in ir_try_remove_empty_diamond()
1287 && !(root->op == IR_SWITCH && ctx->use_lists[root_ref].count == 2)) { in ir_try_remove_empty_diamond()
1310 ir_ref next_ref = ctx->use_edges[ctx->use_lists[ref].refs]; in ir_try_remove_empty_diamond()
1311 ir_insn *next = &ctx->ir_base[next_ref]; in ir_try_remove_empty_diamond()
1313 if (ctx->use_lists[start1_ref].count != 1) { in ir_try_remove_empty_diamond()
1314 ir_remove_unused_vars(ctx, start1_ref, end1_ref); in ir_try_remove_empty_diamond()
1316 if (ctx->use_lists[start2_ref].count != 1) { in ir_try_remove_empty_diamond()
1317 ir_remove_unused_vars(ctx, start2_ref, end2_ref); in ir_try_remove_empty_diamond()
1321 ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); in ir_try_remove_empty_diamond()
1323 ir_use_list_remove_all(ctx, root->op2, root_ref); in ir_try_remove_empty_diamond()
1324 if (ir_is_dead(ctx, root->op2)) { in ir_try_remove_empty_diamond()
1336 if (ctx->ir_base[next->op1].op == IR_BEGIN || ctx->ir_base[next->op1].op == IR_MERGE) { in ir_try_remove_empty_diamond()
1350 end = &ctx->ir_base[end_ref]; in ir_try_remove_empty_diamond()
1355 start = &ctx->ir_base[start_ref]; in ir_try_remove_empty_diamond()
1359 if (ctx->use_lists[start_ref].count != 1) { in ir_try_remove_empty_diamond()
1360 ir_remove_unused_vars(ctx, start_ref, end_ref); in ir_try_remove_empty_diamond()
1364 if (ctx->use_lists[root_ref].count != count) { in ir_try_remove_empty_diamond()
1373 ir_ref next_ref = ctx->use_edges[ctx->use_lists[ref].refs]; in ir_try_remove_empty_diamond()
1374 ir_insn *next = &ctx->ir_base[next_ref]; in ir_try_remove_empty_diamond()
1375 ir_insn *root = &ctx->ir_base[root_ref]; in ir_try_remove_empty_diamond()
1378 ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); in ir_try_remove_empty_diamond()
1381 ir_use_list_remove_all(ctx, root->op2, root_ref); in ir_try_remove_empty_diamond()
1382 if (ir_is_dead(ctx, root->op2)) { in ir_try_remove_empty_diamond()
1391 ir_insn *end = &ctx->ir_base[end_ref]; in ir_try_remove_empty_diamond()
1393 ir_insn *start = &ctx->ir_base[start_ref]; in ir_try_remove_empty_diamond()
1401 if (ctx->ir_base[next->op1].op == IR_BEGIN || ctx->ir_base[next->op1].op == IR_MERGE) { in ir_try_remove_empty_diamond()
1409 static bool ir_is_zero(ir_ctx *ctx, ir_ref ref) in ir_is_zero() argument
1412 && !IR_IS_SYM_CONST(ctx->ir_base[ref].op) in ir_is_zero()
1413 && ctx->ir_base[ref].val.u32 == 0; in ir_is_zero()
1416 static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_ref ref, ir_insn *ins… in ir_optimize_phi() argument
1419 IR_ASSERT(ctx->use_lists[merge_ref].count == 2); in ir_optimize_phi()
1422 ir_insn *end1 = &ctx->ir_base[end1_ref]; in ir_optimize_phi()
1423 ir_insn *end2 = &ctx->ir_base[end2_ref]; in ir_optimize_phi()
1427 ir_insn *start1 = &ctx->ir_base[start1_ref]; in ir_optimize_phi()
1428 ir_insn *start2 = &ctx->ir_base[start2_ref]; in ir_optimize_phi()
1432 ir_insn *root = &ctx->ir_base[root_ref]; in ir_optimize_phi()
1434 if (root->op == IR_IF && ctx->use_lists[root->op2].count == 1) { in ir_optimize_phi()
1436 ir_insn *cond = &ctx->ir_base[cond_ref]; in ir_optimize_phi()
1476 ir_ref next_ref = ctx->use_edges[ctx->use_lists[merge_ref].refs]; in ir_optimize_phi()
1480 next_ref = ctx->use_edges[ctx->use_lists[merge_ref].refs + 1]; in ir_optimize_phi()
1482 next = &ctx->ir_base[next_ref]; in ir_optimize_phi()
1484 if (ctx->use_lists[start1_ref].count != 1) { in ir_optimize_phi()
1485 ir_remove_unused_vars(ctx, start1_ref, end1_ref); in ir_optimize_phi()
1487 if (ctx->use_lists[start2_ref].count != 1) { in ir_optimize_phi()
1488 ir_remove_unused_vars(ctx, start2_ref, end2_ref); in ir_optimize_phi()
1506 ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); in ir_optimize_phi()
1508 ir_use_list_remove_all(ctx, insn->op1, cond_ref); in ir_optimize_phi()
1511 ir_use_list_remove_all(ctx, insn->op2, cond_ref); in ir_optimize_phi()
1522 if (ctx->ir_base[next->op1].op == IR_BEGIN || ctx->ir_base[next->op1].op == IR_MERGE) { in ir_optimize_phi()
1528 && ((ctx->ir_base[insn->op2].op == IR_NEG in ir_optimize_phi()
1529 && ctx->use_lists[insn->op2].count == 1 in ir_optimize_phi()
1530 && ctx->ir_base[insn->op2].op1 == insn->op3 in ir_optimize_phi()
1532 && ir_is_zero(ctx, cond->op2) in ir_optimize_phi()
1535 && ir_is_zero(ctx, cond->op1) in ir_optimize_phi()
1537 || (ctx->ir_base[insn->op3].op == IR_NEG in ir_optimize_phi()
1538 && ctx->use_lists[insn->op3].count == 1 in ir_optimize_phi()
1539 && ctx->ir_base[insn->op3].op1 == insn->op2 in ir_optimize_phi()
1541 && ir_is_zero(ctx, cond->op2) in ir_optimize_phi()
1544 && ir_is_zero(ctx, cond->op1) in ir_optimize_phi()
1566 ir_ref next_ref = ctx->use_edges[ctx->use_lists[merge_ref].refs]; in ir_optimize_phi()
1570 next_ref = ctx->use_edges[ctx->use_lists[merge_ref].refs + 1]; in ir_optimize_phi()
1572 next = &ctx->ir_base[next_ref]; in ir_optimize_phi()
1574 if (ctx->use_lists[start1_ref].count != 1) { in ir_optimize_phi()
1575 ir_remove_unused_vars(ctx, start1_ref, end1_ref); in ir_optimize_phi()
1577 if (ctx->use_lists[start2_ref].count != 1) { in ir_optimize_phi()
1578 ir_remove_unused_vars(ctx, start2_ref, end2_ref); in ir_optimize_phi()
1583 if (ctx->ir_base[insn->op2].op == IR_NEG) { in ir_optimize_phi()
1594 ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); in ir_optimize_phi()
1595 ir_use_list_remove_one(ctx, insn->op1, neg_ref); in ir_optimize_phi()
1597 ir_use_list_remove_all(ctx, insn->op1, cond_ref); in ir_optimize_phi()
1607 MAKE_NOP(&ctx->ir_base[neg_ref]); CLEAR_USES(neg_ref); in ir_optimize_phi()
1609 if (ctx->ir_base[next->op1].op == IR_BEGIN || ctx->ir_base[next->op1].op == IR_MERGE) { in ir_optimize_phi()
1635 ir_ref next_ref = ctx->use_edges[ctx->use_lists[merge_ref].refs]; in ir_optimize_phi()
1639 next_ref = ctx->use_edges[ctx->use_lists[merge_ref].refs + 1]; in ir_optimize_phi()
1641 next = &ctx->ir_base[next_ref]; in ir_optimize_phi()
1643 if (ctx->use_lists[start1_ref].count != 1) { in ir_optimize_phi()
1644 ir_remove_unused_vars(ctx, start1_ref, end1_ref); in ir_optimize_phi()
1646 if (ctx->use_lists[start2_ref].count != 1) { in ir_optimize_phi()
1647 ir_remove_unused_vars(ctx, start2_ref, end2_ref); in ir_optimize_phi()
1658 ir_use_list_replace_one(ctx, cond_ref, root_ref, ref); in ir_optimize_phi()
1659 ir_use_list_replace_one(ctx, root->op1, root_ref, next_ref); in ir_optimize_phi()
1660 ir_use_list_remove_all(ctx, root->op2, root_ref); in ir_optimize_phi()
1669 if (ctx->ir_base[next->op1].op == IR_BEGIN || ctx->ir_base[next->op1].op == IR_MERGE) { in ir_optimize_phi()
1781 static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist) in ir_try_split_if() argument
1784 ir_insn *cond = &ctx->ir_base[cond_ref]; in ir_try_split_if()
1789 && ((IR_IS_CONST_REF(cond->op2) && !IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op)) in ir_try_split_if()
1790 || (IR_IS_CONST_REF(cond->op3) && !IR_IS_SYM_CONST(ctx->ir_base[cond->op3].op)))) { in ir_try_split_if()
1792 ir_insn *merge = &ctx->ir_base[merge_ref]; in ir_try_split_if()
1794 if (ctx->use_lists[merge_ref].count == 2) { in ir_try_split_if()
1796 ir_insn *end1 = &ctx->ir_base[end1_ref]; in ir_try_split_if()
1797 ir_insn *end2 = &ctx->ir_base[end2_ref]; in ir_try_split_if()
1804 ir_get_true_false_refs(ctx, ref, &if_true_ref, &if_false_ref); in ir_try_split_if()
1806 if (!IR_IS_CONST_REF(cond->op2) || IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op)) { in ir_try_split_if()
1813 if (ir_const_is_true(&ctx->ir_base[cond->op2])) { in ir_try_split_if()
1817 if_true = &ctx->ir_base[if_true_ref]; in ir_try_split_if()
1818 if_false = &ctx->ir_base[if_false_ref]; in ir_try_split_if()
1820 if (IR_IS_CONST_REF(cond->op3) && !IR_IS_SYM_CONST(ctx->ir_base[cond->op3].op)) { in ir_try_split_if()
1821 if (ir_const_is_true(&ctx->ir_base[cond->op3]) ^ (op == IR_IF_TRUE)) { in ir_try_split_if()
1840 ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref); in ir_try_split_if()
1841 ir_use_list_replace_one(ctx, end2_ref, merge_ref, if_true_ref); in ir_try_split_if()
1876 ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref); in ir_try_split_if()
1877 ir_use_list_replace_one(ctx, end2_ref, merge_ref, if_false_ref); in ir_try_split_if()
1890 ctx->flags2 &= ~IR_CFG_REACHABLE; in ir_try_split_if()
1916 ir_use_list_remove_all(ctx, merge_ref, cond_ref); in ir_try_split_if()
1917 ir_use_list_remove_all(ctx, ref, if_true_ref); in ir_try_split_if()
1919 ir_use_list_replace_one(ctx, cond->op3, cond_ref, end2_ref); in ir_try_split_if()
1921 ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref); in ir_try_split_if()
1922 ir_use_list_add(ctx, end2_ref, if_true_ref); in ir_try_split_if()
1945 if (ctx->ir_base[end2->op1].op == IR_BEGIN || ctx->ir_base[end2->op1].op == IR_MERGE) { in ir_try_split_if()
1957 static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue *worklist) in ir_try_split_if_cmp() argument
1960 ir_insn *cond = &ctx->ir_base[cond_ref]; in ir_try_split_if_cmp()
1964 && !IR_IS_SYM_CONST(ctx->ir_base[cond->op2].op) in ir_try_split_if_cmp()
1965 && ctx->use_lists[insn->op2].count == 1) { in ir_try_split_if_cmp()
1967 ir_insn *phi = &ctx->ir_base[phi_ref]; in ir_try_split_if_cmp()
1972 && ctx->use_lists[phi_ref].count == 1 in ir_try_split_if_cmp()
1973 && ((IR_IS_CONST_REF(phi->op2) && !IR_IS_SYM_CONST(ctx->ir_base[phi->op2].op)) in ir_try_split_if_cmp()
1974 || (IR_IS_CONST_REF(phi->op3) && !IR_IS_SYM_CONST(ctx->ir_base[phi->op3].op)))) { in ir_try_split_if_cmp()
1976 ir_insn *merge = &ctx->ir_base[merge_ref]; in ir_try_split_if_cmp()
1978 if (ctx->use_lists[merge_ref].count == 2) { in ir_try_split_if_cmp()
1980 ir_insn *end1 = &ctx->ir_base[end1_ref]; in ir_try_split_if_cmp()
1981 ir_insn *end2 = &ctx->ir_base[end2_ref]; in ir_try_split_if_cmp()
1988 ir_get_true_false_refs(ctx, ref, &if_true_ref, &if_false_ref); in ir_try_split_if_cmp()
1990 if (!IR_IS_CONST_REF(phi->op2) || IR_IS_SYM_CONST(ctx->ir_base[phi->op2].op)) { in ir_try_split_if_cmp()
1997 if (ir_cmp_is_true(cond->op, &ctx->ir_base[phi->op2], &ctx->ir_base[cond->op2])) { in ir_try_split_if_cmp()
2001 if_true = &ctx->ir_base[if_true_ref]; in ir_try_split_if_cmp()
2002 if_false = &ctx->ir_base[if_false_ref]; in ir_try_split_if_cmp()
2004 if (IR_IS_CONST_REF(phi->op3) && !IR_IS_SYM_CONST(ctx->ir_base[phi->op3].op)) { in ir_try_split_if_cmp()
2005 …if (ir_cmp_is_true(cond->op, &ctx->ir_base[phi->op3], &ctx->ir_base[cond->op2]) ^ (op == IR_IF_TRU… in ir_try_split_if_cmp()
2027 ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref); in ir_try_split_if_cmp()
2028 ir_use_list_replace_one(ctx, end2_ref, merge_ref, if_true_ref); in ir_try_split_if_cmp()
2067 ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref); in ir_try_split_if_cmp()
2068 ir_use_list_replace_one(ctx, end2_ref, merge_ref, if_false_ref); in ir_try_split_if_cmp()
2082 ctx->flags2 &= ~IR_CFG_REACHABLE; in ir_try_split_if_cmp()
2110 ir_use_list_remove_all(ctx, merge_ref, phi_ref); in ir_try_split_if_cmp()
2111 ir_use_list_remove_all(ctx, ref, if_true_ref); in ir_try_split_if_cmp()
2113 ir_use_list_replace_one(ctx, phi->op3, phi_ref, insn->op2); in ir_try_split_if_cmp()
2115 ir_use_list_replace_one(ctx, end1_ref, merge_ref, if_false_ref); in ir_try_split_if_cmp()
2116 ir_use_list_replace_one(ctx, cond_ref, ref, end2_ref); in ir_try_split_if_cmp()
2117 ir_use_list_add(ctx, end2_ref, if_true_ref); in ir_try_split_if_cmp()
2141 if (ctx->ir_base[end2->op1].op == IR_BEGIN || ctx->ir_base[end2->op1].op == IR_MERGE) { in ir_try_split_if_cmp()
2155 static void ir_optimize_merge(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_bitqueue *worklist) in ir_optimize_merge() argument
2157 ir_use_list *use_list = &ctx->use_lists[merge_ref]; in ir_optimize_merge()
2160 ir_try_remove_empty_diamond(ctx, merge_ref, merge, worklist); in ir_optimize_merge()
2163 ir_ref phi_ref = ctx->use_edges[use_list->refs]; in ir_optimize_merge()
2164 ir_insn *phi = &ctx->ir_base[phi_ref]; in ir_optimize_merge()
2166 ir_ref next_ref = ctx->use_edges[use_list->refs + 1]; in ir_optimize_merge()
2167 ir_insn *next = &ctx->ir_base[next_ref]; in ir_optimize_merge()
2175 if (next->op == IR_IF && next->op1 == merge_ref && ctx->use_lists[phi_ref].count == 1) { in ir_optimize_merge()
2177 if (ir_try_split_if(ctx, next_ref, next, worklist)) { in ir_optimize_merge()
2181 ir_insn *cmp = &ctx->ir_base[next->op2]; in ir_optimize_merge()
2186 && !IR_IS_SYM_CONST(ctx->ir_base[cmp->op2].op) in ir_optimize_merge()
2187 && ctx->use_lists[next->op2].count == 1) { in ir_optimize_merge()
2188 if (ir_try_split_if_cmp(ctx, next_ref, next, worklist)) { in ir_optimize_merge()
2194 ir_optimize_phi(ctx, merge_ref, merge, phi_ref, phi, worklist); in ir_optimize_merge()
2200 int ir_sccp(ir_ctx *ctx) in ir_sccp() argument
2207 ir_insn *_values = ir_mem_calloc(ctx->insns_count, sizeof(ir_insn)); in ir_sccp()
2209 ctx->flags2 |= IR_OPT_IN_SCCP; in ir_sccp()
2212 ir_bitqueue_init(&worklist2, ctx->insns_count); in ir_sccp()
2213 ir_bitqueue_init(&worklist, ctx->insns_count); in ir_sccp()
2217 insn = &ctx->ir_base[i]; in ir_sccp()
2220 if (ctx->use_lists[i].count == 0) { in ir_sccp()
2224 if (!ir_sccp_meet_phi(ctx, _values, i, insn, &worklist)) { in ir_sccp()
2262 } else if (!ir_sccp_fold(ctx, _values, i, insn->opt, insn->op1, insn->op2, insn->op3)) { in ir_sccp()
2266 insn = &ctx->ir_base[i]; in ir_sccp()
2327 bool b = ir_sccp_is_true(ctx, _values, insn->op2); in ir_sccp()
2328 use_list = &ctx->use_lists[i]; in ir_sccp()
2330 p = &ctx->use_edges[use_list->refs]; in ir_sccp()
2332 use_insn = &ctx->ir_base[use]; in ir_sccp()
2336 IR_ASSERT(ctx->ir_base[use].op == IR_IF_TRUE || ctx->ir_base[use].op == IR_IF_FALSE); in ir_sccp()
2366 use_list = &ctx->use_lists[i]; in ir_sccp()
2368 for (j = 0, p = &ctx->use_edges[use_list->refs]; j < n; j++, p++) { in ir_sccp()
2371 use_insn = &ctx->ir_base[use]; in ir_sccp()
2373 if (ir_sccp_is_equal(ctx, _values, insn->op2, use_insn->op2)) { in ir_sccp()
2382 use_insn = &ctx->ir_base[use_case]; in ir_sccp()
2398 } else if (ir_is_dead_load_ex(ctx, i, flags, insn)) { in ir_sccp()
2434 use_list = &ctx->use_lists[i]; in ir_sccp()
2436 for (p = &ctx->use_edges[use_list->refs]; n > 0; p++, n--) { in ir_sccp()
2445 if (ctx->flags & IR_DEBUG_SCCP) { in ir_sccp()
2446 for (i = 1; i < ctx->insns_count; i++) { in ir_sccp()
2449 ir_print_const(ctx, &_values[i], stderr, true); in ir_sccp()
2468 for (i = 1, value = _values + i; i < ctx->insns_count; value++, i++) { in ir_sccp()
2473 j = ir_const(ctx, value->val, value->type); in ir_sccp()
2474 ir_sccp_replace_insn(ctx, _values, i, j, &worklist2); in ir_sccp()
2477 j = ir_const_ex(ctx, value->val, value->type, value->optx); in ir_sccp()
2478 ir_sccp_replace_insn(ctx, _values, i, j, &worklist2); in ir_sccp()
2481 ir_sccp_replace_insn(ctx, _values, i, value->op1, &worklist2); in ir_sccp()
2485 insn = &ctx->ir_base[i]; in ir_sccp()
2488 ir_sccp_remove_insn(ctx, _values, i, &worklist2); in ir_sccp()
2493 ir_ref prev = ctx->ir_base[1].op1; in ir_sccp()
2495 ctx->ir_base[1].op1 = insn->op3; in ir_sccp()
2498 if (ctx->ir_base[prev].op3 == i) { in ir_sccp()
2499 ctx->ir_base[prev].op3 = insn->op3; in ir_sccp()
2502 prev = ctx->ir_base[prev].op3; in ir_sccp()
2506 ir_sccp_replace_insn(ctx, _values, i, IR_UNUSED, &worklist2); in ir_sccp()
2510 ir_sccp_remove_if(ctx, _values, i, value->op1); in ir_sccp()
2522 ir_sccp_remove_unfeasible_merge_inputs(ctx, _values, i, _values[i].op1); in ir_sccp()
2525 ctx->flags2 |= IR_CFG_REACHABLE; in ir_sccp()
2528 insn = &ctx->ir_base[i]; in ir_sccp()
2530 if (ctx->use_lists[i].count == 0) { in ir_sccp()
2534 ir_sccp_remove_insn2(ctx, i, &worklist2); in ir_sccp()
2536 insn = &ctx->ir_base[i]; in ir_sccp()
2540 if (ir_may_promote_d2f(ctx, insn->op1)) { in ir_sccp()
2541 ir_ref ref = ir_promote_d2f(ctx, insn->op1, i); in ir_sccp()
2543 ir_sccp_replace_insn2(ctx, i, ref, &worklist2); in ir_sccp()
2547 if (ir_may_promote_f2d(ctx, insn->op1)) { in ir_sccp()
2548 ir_ref ref = ir_promote_f2d(ctx, insn->op1, i); in ir_sccp()
2550 ir_sccp_replace_insn2(ctx, i, ref, &worklist2); in ir_sccp()
2556 if (ctx->ir_base[insn->op1].type == IR_DOUBLE) { in ir_sccp()
2557 if (ir_may_promote_d2f(ctx, insn->op1)) { in ir_sccp()
2558 insn->op1 = ir_promote_d2f(ctx, insn->op1, i); in ir_sccp()
2561 if (ir_may_promote_f2d(ctx, insn->op1)) { in ir_sccp()
2562 insn->op1 = ir_promote_f2d(ctx, insn->op1, i); in ir_sccp()
2567 if (ir_may_promote_i2i(ctx, insn->type, insn->op1)) { in ir_sccp()
2568 ir_ref ref = ir_promote_i2i(ctx, insn->type, insn->op1, i); in ir_sccp()
2570 ir_sccp_replace_insn2(ctx, i, ref, &worklist2); in ir_sccp()
2576 if (ir_try_promote_ext(ctx, i, insn, &worklist2)) { in ir_sccp()
2584 ir_sccp_fold2(ctx, i, &worklist2); in ir_sccp()
2589 if (!(ctx->flags & IR_OPT_CFG)) { in ir_sccp()
2592 if (ctx->ir_base[insn->op1].op == IR_END in ir_sccp()
2593 && ctx->use_lists[i].count == 1) { in ir_sccp()
2594 ir_merge_blocks(ctx, insn->op1, i, &worklist2); in ir_sccp()
2597 ir_optimize_merge(ctx, i, insn, &worklist2); in ir_sccp()
2599 } else if (ir_is_dead_load(ctx, i)) { in ir_sccp()
2600 ir_ref next = ctx->use_edges[ctx->use_lists[i].refs]; in ir_sccp()
2603 ctx->ir_base[next].op1 = insn->op1; in ir_sccp()
2604 ir_use_list_replace_one(ctx, insn->op1, i, next); in ir_sccp()
2606 ir_sccp_remove_insn2(ctx, i, &worklist2); in ir_sccp()
2614 ctx->flags2 &= ~IR_OPT_IN_SCCP; in ir_sccp()
2615 ctx->flags2 |= IR_SCCP_DONE; in ir_sccp()