@@ -2407,20 +2407,67 @@ void _ir_BEGIN(ir_ctx *ctx, ir_ref src)
24072407 }
24082408}
24092409
2410- ir_ref _ir_fold_condition (ir_ctx * ctx , ir_ref ref )
2410+ static ir_ref _ir_fold_condition (ir_ctx * ctx , ir_ref ref )
24112411{
24122412 ir_insn * insn = & ctx -> ir_base [ref ];
24132413
24142414 if (insn -> op == IR_NE && IR_IS_CONST_REF (insn -> op2 )) {
24152415 ir_insn * op2_insn = & ctx -> ir_base [insn -> op2 ];
24162416
24172417 if (IR_IS_TYPE_INT (op2_insn -> type ) && op2_insn -> val .u64 == 0 ) {
2418- return insn -> op1 ;
2418+ ref = insn -> op1 ;
2419+ insn = & ctx -> ir_base [ref ];
24192420 }
2421+ } else if (insn -> op == IR_EQ && insn -> op2 == IR_TRUE ) {
2422+ ref = insn -> op1 ;
2423+ insn = & ctx -> ir_base [ref ];
24202424 }
2425+ // while (insn->op == IR_SEXT || insn->op == IR_ZEXT || insn->op == IR_BITCAST) {
2426+ // ref = insn->op1;
2427+ // insn = &ctx->ir_base[ref];
2428+ // }
24212429 return ref ;
24222430}
24232431
2432+ IR_ALWAYS_INLINE ir_ref ir_check_dominating_predicates_i (ir_ctx * ctx , ir_ref ref , ir_ref condition , ir_ref limit )
2433+ {
2434+ ir_insn * prev = NULL ;
2435+ ir_insn * insn ;
2436+
2437+ while (ref > limit ) {
2438+ insn = & ctx -> ir_base [ref ];
2439+ if (insn -> op == IR_GUARD_NOT ) {
2440+ if (insn -> op2 == condition ) {
2441+ return IR_FALSE ;
2442+ }
2443+ } else if (insn -> op == IR_GUARD ) {
2444+ if (insn -> op2 == condition ) {
2445+ return IR_TRUE ;
2446+ }
2447+ } else if (insn -> op == IR_IF ) {
2448+ if (insn -> op2 == condition ) {
2449+ if (prev -> op == IR_IF_TRUE ) {
2450+ return IR_TRUE ;
2451+ } else if (prev -> op == IR_IF_FALSE ) {
2452+ return IR_FALSE ;
2453+ }
2454+ }
2455+ } else if (insn -> op == IR_START || insn -> op == IR_MERGE || insn -> op == IR_LOOP_BEGIN ) {
2456+ break ;
2457+ }
2458+ prev = insn ;
2459+ ref = insn -> op1 ;
2460+ }
2461+
2462+ return condition ;
2463+ }
2464+
2465+ ir_ref ir_check_dominating_predicates (ir_ctx * ctx , ir_ref ref , ir_ref condition )
2466+ {
2467+ IR_ASSERT (!IR_IS_CONST_REF (condition ));
2468+ return ir_check_dominating_predicates_i (ctx , ref , condition , (condition < ref ) ? condition : 1 );
2469+ }
2470+
24242471ir_ref _ir_IF (ir_ctx * ctx , ir_ref condition )
24252472{
24262473 ir_ref if_ref ;
@@ -2436,38 +2483,7 @@ ir_ref _ir_IF(ir_ctx *ctx, ir_ref condition)
24362483 if (IR_IS_CONST_REF (condition )) {
24372484 condition = ir_ref_is_true (ctx , condition ) ? IR_TRUE : IR_FALSE ;
24382485 } else {
2439- ir_insn * prev = NULL ;
2440- ir_ref ref = ctx -> control ;
2441- ir_insn * insn ;
2442-
2443- while (ref > condition ) {
2444- insn = & ctx -> ir_base [ref ];
2445- if (insn -> op == IR_GUARD_NOT ) {
2446- if (insn -> op2 == condition ) {
2447- condition = IR_FALSE ;
2448- break ;
2449- }
2450- } else if (insn -> op == IR_GUARD ) {
2451- if (insn -> op2 == condition ) {
2452- condition = IR_TRUE ;
2453- break ;
2454- }
2455- } else if (insn -> op == IR_IF ) {
2456- if (insn -> op2 == condition ) {
2457- if (prev -> op == IR_IF_TRUE ) {
2458- condition = IR_TRUE ;
2459- break ;
2460- } else if (prev -> op == IR_IF_FALSE ) {
2461- condition = IR_FALSE ;
2462- break ;
2463- }
2464- }
2465- } else if (insn -> op == IR_START || insn -> op == IR_MERGE || insn -> op == IR_LOOP_BEGIN ) {
2466- break ;
2467- }
2468- prev = insn ;
2469- ref = insn -> op1 ;
2470- }
2486+ condition = ir_check_dominating_predicates_i (ctx , ctx -> control , condition , condition );
24712487 }
24722488 if_ref = ir_emit2 (ctx , IR_IF , ctx -> control , condition );
24732489 ctx -> control = IR_UNUSED ;
@@ -2986,35 +3002,9 @@ void _ir_GUARD(ir_ctx *ctx, ir_ref condition, ir_ref addr)
29863002 }
29873003 condition = IR_FALSE ;
29883004 } else if (EXPECTED (ctx -> flags & IR_OPT_FOLDING )) {
2989- ir_insn * prev = NULL ;
2990- ir_ref ref = ctx -> control ;
2991- ir_insn * insn ;
2992-
2993- while (ref > condition ) {
2994- insn = & ctx -> ir_base [ref ];
2995- if (insn -> op == IR_GUARD ) {
2996- if (insn -> op2 == condition ) {
2997- return ;
2998- }
2999- } else if (insn -> op == IR_GUARD_NOT ) {
3000- if (insn -> op2 == condition ) {
3001- condition = IR_FALSE ;
3002- break ;
3003- }
3004- } else if (insn -> op == IR_IF ) {
3005- if (insn -> op2 == condition ) {
3006- if (prev -> op == IR_IF_TRUE ) {
3007- return ;
3008- } else if (prev -> op == IR_IF_FALSE ) {
3009- condition = IR_FALSE ;
3010- break ;
3011- }
3012- }
3013- } else if (insn -> op == IR_START || insn -> op == IR_MERGE || insn -> op == IR_LOOP_BEGIN ) {
3014- break ;
3015- }
3016- prev = insn ;
3017- ref = insn -> op1 ;
3005+ condition = ir_check_dominating_predicates_i (ctx , ctx -> control , condition , condition );
3006+ if (condition == IR_TRUE ) {
3007+ return ;
30183008 }
30193009 }
30203010 if (ctx -> snapshot_create ) {
@@ -3032,35 +3022,9 @@ void _ir_GUARD_NOT(ir_ctx *ctx, ir_ref condition, ir_ref addr)
30323022 }
30333023 condition = IR_TRUE ;
30343024 } else if (EXPECTED (ctx -> flags & IR_OPT_FOLDING )) {
3035- ir_insn * prev = NULL ;
3036- ir_ref ref = ctx -> control ;
3037- ir_insn * insn ;
3038-
3039- while (ref > condition ) {
3040- insn = & ctx -> ir_base [ref ];
3041- if (insn -> op == IR_GUARD_NOT ) {
3042- if (insn -> op2 == condition ) {
3043- return ;
3044- }
3045- } else if (insn -> op == IR_GUARD ) {
3046- if (insn -> op2 == condition ) {
3047- condition = IR_TRUE ;
3048- break ;
3049- }
3050- } else if (insn -> op == IR_IF ) {
3051- if (insn -> op2 == condition ) {
3052- if (prev -> op == IR_IF_TRUE ) {
3053- condition = IR_TRUE ;
3054- break ;
3055- } else if (prev -> op == IR_IF_FALSE ) {
3056- return ;
3057- }
3058- }
3059- } else if (insn -> op == IR_START || insn -> op == IR_MERGE || insn -> op == IR_LOOP_BEGIN ) {
3060- break ;
3061- }
3062- prev = insn ;
3063- ref = insn -> op1 ;
3025+ condition = ir_check_dominating_predicates_i (ctx , ctx -> control , condition , condition );
3026+ if (condition == IR_FALSE ) {
3027+ return ;
30643028 }
30653029 }
30663030 if (ctx -> snapshot_create ) {
0 commit comments