@@ -2003,16 +2003,50 @@ void compute_live_in(basic_block_t *bb)
2003
2003
2004
2004
int merge_live_in (var_t * live_out [], int live_out_idx , basic_block_t * bb )
2005
2005
{
2006
- for (int i = 0 ; i < bb -> live_in_idx ; i ++ ) {
2007
- int found = 0 ;
2008
- for (int j = 0 ; j < live_out_idx ; j ++ ) {
2009
- if (live_out [j ] == bb -> live_in [i ]) {
2010
- found = 1 ;
2011
- break ;
2006
+ /* Early exit for empty live_in */
2007
+ if (bb -> live_in_idx == 0 )
2008
+ return live_out_idx ;
2009
+
2010
+ /* Optimize for common case of small sets */
2011
+ if (live_out_idx < 16 ) {
2012
+ /* For small sets, simple linear search is fast enough */
2013
+ for (int i = 0 ; i < bb -> live_in_idx ; i ++ ) {
2014
+ int found = 0 ;
2015
+ for (int j = 0 ; j < live_out_idx ; j ++ ) {
2016
+ if (live_out [j ] == bb -> live_in [i ]) {
2017
+ found = 1 ;
2018
+ break ;
2019
+ }
2020
+ }
2021
+ if (!found && live_out_idx < MAX_ANALYSIS_STACK_SIZE )
2022
+ live_out [live_out_idx ++ ] = bb -> live_in [i ];
2023
+ }
2024
+ } else {
2025
+ /* For larger sets, check bounds and use optimized loop */
2026
+ for (int i = 0 ; i < bb -> live_in_idx ; i ++ ) {
2027
+ int found = 0 ;
2028
+ var_t * var = bb -> live_in [i ];
2029
+ /* Unroll inner loop for better performance */
2030
+ int j ;
2031
+ for (j = 0 ; j + 3 < live_out_idx ; j += 4 ) {
2032
+ if (live_out [j ] == var || live_out [j + 1 ] == var ||
2033
+ live_out [j + 2 ] == var || live_out [j + 3 ] == var ) {
2034
+ found = 1 ;
2035
+ break ;
2036
+ }
2037
+ }
2038
+ /* Handle remaining elements */
2039
+ if (!found ) {
2040
+ for (; j < live_out_idx ; j ++ ) {
2041
+ if (live_out [j ] == var ) {
2042
+ found = 1 ;
2043
+ break ;
2044
+ }
2045
+ }
2012
2046
}
2047
+ if (!found && live_out_idx < MAX_ANALYSIS_STACK_SIZE )
2048
+ live_out [live_out_idx ++ ] = var ;
2013
2049
}
2014
- if (!found )
2015
- live_out [live_out_idx ++ ] = bb -> live_in [i ];
2016
2050
}
2017
2051
return live_out_idx ;
2018
2052
}
@@ -2022,6 +2056,7 @@ bool recompute_live_out(basic_block_t *bb)
2022
2056
var_t * live_out [MAX_ANALYSIS_STACK_SIZE ];
2023
2057
int live_out_idx = 0 ;
2024
2058
2059
+ /* Compute union of successor live_in sets */
2025
2060
if (bb -> next ) {
2026
2061
compute_live_in (bb -> next );
2027
2062
live_out_idx = merge_live_in (live_out , live_out_idx , bb -> next );
@@ -2035,12 +2070,32 @@ bool recompute_live_out(basic_block_t *bb)
2035
2070
live_out_idx = merge_live_in (live_out , live_out_idx , bb -> else_ );
2036
2071
}
2037
2072
2073
+ /* Quick check: if sizes differ, sets must be different */
2038
2074
if (bb -> live_out_idx != live_out_idx ) {
2039
2075
memcpy (bb -> live_out , live_out , HOST_PTR_SIZE * live_out_idx );
2040
2076
bb -> live_out_idx = live_out_idx ;
2041
2077
return true;
2042
2078
}
2043
2079
2080
+ /* Size is same, need to check if contents are identical */
2081
+ /* Optimize by checking if first few elements match (common case) */
2082
+ if (live_out_idx > 0 ) {
2083
+ /* Quick check first element */
2084
+ bool first_found = false;
2085
+ for (int j = 0 ; j < bb -> live_out_idx ; j ++ ) {
2086
+ if (live_out [0 ] == bb -> live_out [j ]) {
2087
+ first_found = true;
2088
+ break ;
2089
+ }
2090
+ }
2091
+ if (!first_found ) {
2092
+ memcpy (bb -> live_out , live_out , HOST_PTR_SIZE * live_out_idx );
2093
+ bb -> live_out_idx = live_out_idx ;
2094
+ return true;
2095
+ }
2096
+ }
2097
+
2098
+ /* Full comparison */
2044
2099
for (int i = 0 ; i < live_out_idx ; i ++ ) {
2045
2100
int same = 0 ;
2046
2101
for (int j = 0 ; j < bb -> live_out_idx ; j ++ ) {
0 commit comments