@@ -1283,9 +1283,11 @@ void ir_build_def_use_lists(ir_ctx *ctx)
12831283void ir_use_list_remove_all (ir_ctx * ctx , ir_ref from , ir_ref ref )
12841284{
12851285 ir_ref j , n , * p , * q , use ;
1286- ir_use_list * use_list = & ctx -> use_lists [ from ] ;
1286+ ir_use_list * use_list ;
12871287 ir_ref skip = 0 ;
12881288
1289+ IR_ASSERT (from > 0 );
1290+ use_list = & ctx -> use_lists [from ];
12891291 n = use_list -> count ;
12901292 for (j = 0 , p = q = & ctx -> use_edges [use_list -> refs ]; j < n ; j ++ , p ++ ) {
12911293 use = * p ;
@@ -1310,8 +1312,10 @@ void ir_use_list_remove_all(ir_ctx *ctx, ir_ref from, ir_ref ref)
13101312void ir_use_list_remove_one (ir_ctx * ctx , ir_ref from , ir_ref ref )
13111313{
13121314 ir_ref j , n , * p ;
1313- ir_use_list * use_list = & ctx -> use_lists [ from ] ;
1315+ ir_use_list * use_list ;
13141316
1317+ IR_ASSERT (from > 0 );
1318+ use_list = & ctx -> use_lists [from ];
13151319 n = use_list -> count ;
13161320 j = 0 ;
13171321 p = & ctx -> use_edges [use_list -> refs ];
@@ -1334,9 +1338,11 @@ void ir_use_list_remove_one(ir_ctx *ctx, ir_ref from, ir_ref ref)
13341338
13351339void ir_use_list_replace_one (ir_ctx * ctx , ir_ref ref , ir_ref use , ir_ref new_use )
13361340{
1337- ir_use_list * use_list = & ctx -> use_lists [ ref ] ;
1341+ ir_use_list * use_list ;
13381342 ir_ref i , n , * p ;
13391343
1344+ IR_ASSERT (ref > 0 );
1345+ use_list = & ctx -> use_lists [ref ];
13401346 n = use_list -> count ;
13411347 for (i = 0 , p = & ctx -> use_edges [use_list -> refs ]; i < n ; i ++ , p ++ ) {
13421348 if (* p == use ) {
@@ -1348,9 +1354,11 @@ void ir_use_list_replace_one(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use
13481354
13491355void ir_use_list_replace_all (ir_ctx * ctx , ir_ref ref , ir_ref use , ir_ref new_use )
13501356{
1351- ir_use_list * use_list = & ctx -> use_lists [ ref ] ;
1357+ ir_use_list * use_list ;
13521358 ir_ref i , n , * p ;
13531359
1360+ IR_ASSERT (ref > 0 );
1361+ use_list = & ctx -> use_lists [ref ];
13541362 n = use_list -> count ;
13551363 for (i = 0 , p = & ctx -> use_edges [use_list -> refs ]; i < n ; i ++ , p ++ ) {
13561364 if (* p == use ) {
@@ -1361,9 +1369,12 @@ void ir_use_list_replace_all(ir_ctx *ctx, ir_ref ref, ir_ref use, ir_ref new_use
13611369
13621370bool ir_use_list_add (ir_ctx * ctx , ir_ref to , ir_ref ref )
13631371{
1364- ir_use_list * use_list = & ctx -> use_lists [ to ] ;
1365- ir_ref n = use_list -> refs + use_list -> count ;
1372+ ir_use_list * use_list ;
1373+ ir_ref n ;
13661374
1375+ IR_ASSERT (to > 0 );
1376+ use_list = & ctx -> use_lists [to ];
1377+ n = use_list -> refs + use_list -> count ;
13671378 if (n < ctx -> use_edges_count && ctx -> use_edges [n ] == IR_UNUSED ) {
13681379 ctx -> use_edges [n ] = ref ;
13691380 use_list -> count ++ ;
@@ -1385,6 +1396,59 @@ bool ir_use_list_add(ir_ctx *ctx, ir_ref to, ir_ref ref)
13851396 }
13861397}
13871398
1399+ static int ir_ref_cmp (const void * p1 , const void * p2 )
1400+ {
1401+ return * (ir_ref * )p1 - * (ir_ref * )p2 ;
1402+ }
1403+
1404+ void ir_use_list_sort (ir_ctx * ctx , ir_ref ref )
1405+ {
1406+ ir_use_list * use_list ;
1407+ uint32_t n ;
1408+
1409+ IR_ASSERT (ref > 0 );
1410+ use_list = & ctx -> use_lists [ref ];
1411+ n = use_list -> count ;
1412+ if (n > 1 ) {
1413+ qsort (ctx -> use_edges + use_list -> refs , n , sizeof (ir_ref ), ir_ref_cmp );
1414+ }
1415+ }
1416+
1417+ void ir_replace (ir_ctx * ctx , ir_ref ref , ir_ref new_ref )
1418+ {
1419+ int i , j , n , use ;
1420+ ir_insn * insn ;
1421+
1422+ IR_ASSERT (ref != new_ref );
1423+ n = ctx -> use_lists [ref ].count ;
1424+ for (i = 0 ; i < n ; i ++ ) {
1425+ use = ctx -> use_edges [ctx -> use_lists [ref ].refs + i ];
1426+ IR_ASSERT (use != ref );
1427+ insn = & ctx -> ir_base [use ];
1428+ j = ir_insn_find_op (insn , ref );
1429+ IR_ASSERT (j > 0 );
1430+ ir_insn_set_op (insn , j , new_ref );
1431+ if (!IR_IS_CONST_REF (new_ref )) {
1432+ ir_use_list_add (ctx , new_ref , use );
1433+ }
1434+ }
1435+ }
1436+
1437+ void ir_update_op (ir_ctx * ctx , ir_ref ref , uint32_t idx , ir_ref new_val )
1438+ {
1439+ ir_insn * insn = & ctx -> ir_base [ref ];
1440+ ir_ref old_val = ir_insn_op (insn , idx );
1441+
1442+ IR_ASSERT (old_val != new_val );
1443+ if (new_val > 0 ) {
1444+ ir_use_list_add (ctx , new_val , ref );
1445+ }
1446+ ir_insn_set_op (insn , idx , new_val );
1447+ if (old_val > 0 ) {
1448+ ir_use_list_remove_one (ctx , old_val , ref );
1449+ }
1450+ }
1451+
13881452/* Helper Data Types */
13891453void ir_array_grow (ir_array * a , uint32_t size )
13901454{
@@ -1428,16 +1492,16 @@ void ir_list_remove(ir_list *l, uint32_t i)
14281492 l -> len -- ;
14291493}
14301494
1431- bool ir_list_contains (const ir_list * l , ir_ref val )
1495+ uint32_t ir_list_find (const ir_list * l , ir_ref val )
14321496{
14331497 uint32_t i ;
14341498
14351499 for (i = 0 ; i < l -> len ; i ++ ) {
14361500 if (ir_array_at (& l -> a , i ) == val ) {
1437- return 1 ;
1501+ return i ;
14381502 }
14391503 }
1440- return 0 ;
1504+ return ( uint32_t ) -1 ;
14411505}
14421506
14431507static uint32_t ir_hashtab_hash_size (uint32_t size )
@@ -2010,18 +2074,22 @@ ir_ref _ir_PHI_N(ir_ctx *ctx, ir_type type, ir_ref n, ir_ref *inputs)
20102074 return inputs [0 ];
20112075 } else {
20122076 ir_ref i ;
2013- ir_ref ref = inputs [0 ];
2014-
2015- IR_ASSERT (ctx -> ir_base [ctx -> control ].op == IR_MERGE || ctx -> ir_base [ctx -> control ].op == IR_LOOP_BEGIN );
2016- if (ref != IR_UNUSED ) {
2017- for (i = 1 ; i < n ; i ++ ) {
2018- if (inputs [i ] != ref ) {
2019- break ;
2077+ ir_ref ref ;
2078+
2079+ if (UNEXPECTED (!(ctx -> flags & IR_OPT_FOLDING ))) {
2080+ IR_ASSERT (ctx -> ir_base [ctx -> control ].op == IR_MERGE
2081+ || ctx -> ir_base [ctx -> control ].op == IR_LOOP_BEGIN );
2082+ ref = inputs [0 ];
2083+ if (ref != IR_UNUSED ) {
2084+ for (i = 1 ; i < n ; i ++ ) {
2085+ if (inputs [i ] != ref ) {
2086+ break ;
2087+ }
2088+ }
2089+ if (i == n ) {
2090+ /* all the same */
2091+ return ref ;
20202092 }
2021- }
2022- if (i == n ) {
2023- /* all the same */
2024- return ref ;
20252093 }
20262094 }
20272095
@@ -2066,7 +2134,8 @@ void _ir_ENTRY(ir_ctx *ctx, ir_ref src, ir_ref num)
20662134void _ir_BEGIN (ir_ctx * ctx , ir_ref src )
20672135{
20682136 IR_ASSERT (!ctx -> control );
2069- if (src
2137+ if (EXPECTED (ctx -> flags & IR_OPT_FOLDING )
2138+ && src
20702139 && src + 1 == ctx -> insns_count
20712140 && ctx -> ir_base [src ].op == IR_END ) {
20722141 /* merge with the last END */
@@ -2095,8 +2164,14 @@ ir_ref _ir_IF(ir_ctx *ctx, ir_ref condition)
20952164{
20962165 ir_ref if_ref ;
20972166
2098- condition = _ir_fold_condition (ctx , condition );
20992167 IR_ASSERT (ctx -> control );
2168+ if (UNEXPECTED (!(ctx -> flags & IR_OPT_FOLDING ))) {
2169+ if_ref = ir_emit2 (ctx , IR_IF , ctx -> control , condition );
2170+ ctx -> control = IR_UNUSED ;
2171+ return if_ref ;
2172+ }
2173+
2174+ condition = _ir_fold_condition (ctx , condition );
21002175 if (IR_IS_CONST_REF (condition )) {
21012176 condition = ir_ref_is_true (ctx , condition ) ? IR_TRUE : IR_FALSE ;
21022177 } else {
@@ -2649,7 +2724,7 @@ void _ir_GUARD(ir_ctx *ctx, ir_ref condition, ir_ref addr)
26492724 return ;
26502725 }
26512726 condition = IR_FALSE ;
2652- } else {
2727+ } else if ( EXPECTED ( ctx -> flags & IR_OPT_FOLDING )) {
26532728 ir_insn * prev = NULL ;
26542729 ir_ref ref = ctx -> control ;
26552730 ir_insn * insn ;
@@ -2695,7 +2770,7 @@ void _ir_GUARD_NOT(ir_ctx *ctx, ir_ref condition, ir_ref addr)
26952770 return ;
26962771 }
26972772 condition = IR_TRUE ;
2698- } else {
2773+ } else if ( EXPECTED ( ctx -> flags & IR_OPT_FOLDING )) {
26992774 ir_insn * prev = NULL ;
27002775 ir_ref ref = ctx -> control ;
27012776 ir_insn * insn ;
@@ -2779,6 +2854,10 @@ ir_ref _ir_VLOAD(ir_ctx *ctx, ir_type type, ir_ref var)
27792854 ir_ref ref = ctx -> control ;
27802855 ir_insn * insn ;
27812856
2857+ if (UNEXPECTED (!(ctx -> flags & IR_OPT_FOLDING ))) {
2858+ IR_ASSERT (ctx -> control );
2859+ return ctx -> control = ir_emit2 (ctx , IR_OPT (IR_VLOAD , type ), ctx -> control , var );
2860+ }
27822861 while (ref > var ) {
27832862 insn = & ctx -> ir_base [ref ];
27842863 if (insn -> op == IR_VLOAD ) {
@@ -2825,6 +2904,12 @@ void _ir_VSTORE(ir_ctx *ctx, ir_ref var, ir_ref val)
28252904 ir_insn * insn ;
28262905 bool guarded = 0 ;
28272906
2907+ if (UNEXPECTED (!(ctx -> flags & IR_OPT_FOLDING ))) {
2908+ IR_ASSERT (ctx -> control );
2909+ ctx -> control = ir_emit3 (ctx , IR_VSTORE , ctx -> control , var , val );
2910+ return ;
2911+ }
2912+
28282913 if (!IR_IS_CONST_REF (val )) {
28292914 insn = & ctx -> ir_base [val ];
28302915 if (insn -> op == IR_BITCAST
@@ -2893,9 +2978,12 @@ void _ir_RSTORE(ir_ctx *ctx, ir_ref reg, ir_ref val)
28932978
28942979ir_ref _ir_LOAD (ir_ctx * ctx , ir_type type , ir_ref addr )
28952980{
2896- ir_ref ref = ir_find_aliasing_load ( ctx , ctx -> control , type , addr ) ;
2981+ ir_ref ref = IR_UNUSED ;
28972982
28982983 IR_ASSERT (ctx -> control );
2984+ if (EXPECTED (ctx -> flags & IR_OPT_FOLDING )) {
2985+ ref = ir_find_aliasing_load (ctx , ctx -> control , type , addr );
2986+ }
28992987 if (!ref ) {
29002988 ctx -> control = ref = ir_emit2 (ctx , IR_OPT (IR_LOAD , type ), ctx -> control , addr );
29012989 }
@@ -2912,6 +3000,12 @@ void _ir_STORE(ir_ctx *ctx, ir_ref addr, ir_ref val)
29123000 ir_type type2 ;
29133001 bool guarded = 0 ;
29143002
3003+ IR_ASSERT (ctx -> control );
3004+ if (UNEXPECTED (!(ctx -> flags & IR_OPT_FOLDING ))) {
3005+ ctx -> control = ir_emit3 (ctx , IR_STORE , ctx -> control , addr , val );
3006+ return ;
3007+ }
3008+
29153009 if (!IR_IS_CONST_REF (val )) {
29163010 insn = & ctx -> ir_base [val ];
29173011 if (insn -> op == IR_BITCAST
@@ -2922,7 +3016,6 @@ void _ir_STORE(ir_ctx *ctx, ir_ref addr, ir_ref val)
29223016 }
29233017 }
29243018
2925- IR_ASSERT (ctx -> control );
29263019 while (ref > limit ) {
29273020 insn = & ctx -> ir_base [ref ];
29283021 if (insn -> op == IR_STORE ) {
0 commit comments