@@ -603,7 +603,7 @@ static IR_NEVER_INLINE void ir_sccp_analyze(const ir_ctx *ctx, ir_sccp_val *_val
603603 bool may_benefit = 0 ;
604604 bool has_top = 0 ;
605605
606- if (_values [i ].op != IR_TOP ) {
606+ if (_values [i ].op != IR_TOP || insn -> op == IR_COPY ) {
607607 may_benefit = 1 ;
608608 }
609609
@@ -987,6 +987,7 @@ static void ir_sccp_remove_if(ir_ctx *ctx, const ir_sccp_val *_values, ir_ref re
987987 insn -> optx = IR_OPTX (IR_END , IR_VOID , 1 );
988988 next_insn = & ctx -> ir_base [dst ];
989989 next_insn -> op = IR_BEGIN ;
990+ next_insn -> op2 = IR_UNUSED ;
990991 }
991992}
992993
@@ -2726,7 +2727,16 @@ static bool ir_optimize_phi(ir_ctx *ctx, ir_ref merge_ref, ir_insn *merge, ir_re
27262727 }
27272728
27282729 return 1 ;
2729- } else if (cond -> op != IR_OVERFLOW && insn -> op2 <= cond_ref && insn -> op3 <= cond_ref ) {
2730+ } else if (insn -> op2 <= cond_ref && insn -> op3 <= cond_ref
2731+ && cond -> op != IR_OVERFLOW
2732+ // TODO: temporary disable IF-conversion for RLOAD.
2733+ // We don't track anti-dependencies in GCM and Local Scheduling.
2734+ // As result COND may be scheduled below the following RSTORE.
2735+ // See: https://github.com/dstogov/ir/issues/132
2736+ && cond -> op != IR_RLOAD
2737+ && !((cond -> op >= IR_EQ && cond -> op <= IR_UNORDERED )
2738+ && ((!IR_IS_CONST_REF (cond -> op1 ) && ctx -> ir_base [cond -> op1 ].op == IR_RLOAD )
2739+ || (!IR_IS_CONST_REF (cond -> op2 ) && ctx -> ir_base [cond -> op2 ].op == IR_RLOAD )))) {
27302740 /* COND
27312741 *
27322742 * prev prev
@@ -2968,9 +2978,11 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue
29682978
29692979 if_false -> optx = IR_OPTX (IR_BEGIN , IR_VOID , 1 );
29702980 if_false -> op1 = end1_ref ;
2981+ if_false -> op2 = IR_UNUSED ;
29712982
29722983 if_true -> optx = IR_OPTX (IR_BEGIN , IR_VOID , 1 );
29732984 if_true -> op1 = end2_ref ;
2985+ if_true -> op2 = IR_UNUSED ;
29742986
29752987 ir_bitqueue_add (worklist , if_false_ref );
29762988 ir_bitqueue_add (worklist , if_true_ref );
@@ -3008,6 +3020,7 @@ static bool ir_try_split_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqueue
30083020
30093021 if_true -> optx = IR_BEGIN ;
30103022 if_true -> op1 = IR_UNUSED ;
3023+ if_true -> op2 = IR_UNUSED ;
30113024
30123025 ctx -> flags2 &= ~IR_CFG_REACHABLE ;
30133026
@@ -3157,9 +3170,11 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu
31573170
31583171 if_false -> optx = IR_OPTX (IR_BEGIN , IR_VOID , 1 );
31593172 if_false -> op1 = end1_ref ;
3173+ if_false -> op2 = IR_UNUSED ;
31603174
31613175 if_true -> optx = IR_OPTX (IR_BEGIN , IR_VOID , 1 );
31623176 if_true -> op1 = end2_ref ;
3177+ if_true -> op2 = IR_UNUSED ;
31633178
31643179 ir_bitqueue_add (worklist , if_false_ref );
31653180 ir_bitqueue_add (worklist , if_true_ref );
@@ -3201,6 +3216,7 @@ static bool ir_try_split_if_cmp(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu
32013216
32023217 if_true -> optx = IR_BEGIN ;
32033218 if_true -> op1 = IR_UNUSED ;
3219+ if_true -> op2 = IR_UNUSED ;
32043220
32053221 ctx -> flags2 &= ~IR_CFG_REACHABLE ;
32063222
@@ -3487,7 +3503,9 @@ static void ir_iter_optimize_if(ir_ctx *ctx, ir_ref ref, ir_insn *insn, ir_bitqu
34873503 if_true = & ctx -> ir_base [if_true_ref ];
34883504 if_false = & ctx -> ir_base [if_false_ref ];
34893505 if_true -> op = IR_BEGIN ;
3506+ if_true -> op2 = IR_UNUSED ;
34903507 if_false -> op = IR_BEGIN ;
3508+ if_false -> op2 = IR_UNUSED ;
34913509 if (ir_ref_is_true (ctx , condition )) {
34923510 if_false -> op1 = IR_UNUSED ;
34933511 ir_use_list_remove_one (ctx , ref , if_false_ref );
@@ -3750,6 +3768,47 @@ void ir_iter_opt(ir_ctx *ctx, ir_bitqueue *worklist)
37503768 }
37513769}
37523770
3771+ void ir_iter_cleanup (ir_ctx * ctx )
3772+ {
3773+ ir_bitqueue iter_worklist ;
3774+ ir_bitqueue cfg_worklist ;
3775+ ir_ref i , n ;
3776+ ir_insn * insn ;
3777+
3778+ ir_bitqueue_init (& cfg_worklist , ctx -> insns_count );
3779+ ir_bitqueue_init (& iter_worklist , ctx -> insns_count );
3780+
3781+ /* Remove unused nodes */
3782+ for (i = IR_UNUSED + 1 , insn = ctx -> ir_base + i ; i < ctx -> insns_count ;) {
3783+ if (IR_IS_FOLDABLE_OP (insn -> op )) {
3784+ if (insn -> op != IR_NOP && ctx -> use_lists [i ].count == 0 ) {
3785+ ir_iter_remove_insn (ctx , i , & iter_worklist );
3786+ }
3787+ } else if (insn -> op == IR_IF || insn -> op == IR_MERGE ) {
3788+ ir_bitqueue_add (& cfg_worklist , i );
3789+ }
3790+ n = insn -> inputs_count ;
3791+ n = ir_insn_inputs_to_len (n );
3792+ i += n ;
3793+ insn += n ;
3794+ }
3795+
3796+ while ((i = ir_bitqueue_pop (& iter_worklist )) >= 0 ) {
3797+ insn = & ctx -> ir_base [i ];
3798+ if (IR_IS_FOLDABLE_OP (insn -> op )) {
3799+ if (ctx -> use_lists [i ].count == 0 ) {
3800+ ir_iter_remove_insn (ctx , i , & iter_worklist );
3801+ }
3802+ }
3803+ }
3804+
3805+ /* Cleanup Control Flow */
3806+ ir_iter_opt (ctx , & cfg_worklist );
3807+
3808+ ir_bitqueue_free (& iter_worklist );
3809+ ir_bitqueue_free (& cfg_worklist );
3810+ }
3811+
37533812int ir_sccp (ir_ctx * ctx )
37543813{
37553814 ir_bitqueue sccp_worklist , iter_worklist ;
0 commit comments