Skip to content

Commit 73bfbf4

Browse files
authored
Merge pull request #264 from sysprog21/improve-ssa
Speed up SSA liveness analysis
2 parents 3ce9b6d + 0bcb5b4 commit 73bfbf4

File tree

1 file changed

+63
-8
lines changed

1 file changed

+63
-8
lines changed

src/ssa.c

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,16 +2003,50 @@ void compute_live_in(basic_block_t *bb)
20032003

20042004
int merge_live_in(var_t *live_out[], int live_out_idx, basic_block_t *bb)
20052005
{
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+
}
20122046
}
2047+
if (!found && live_out_idx < MAX_ANALYSIS_STACK_SIZE)
2048+
live_out[live_out_idx++] = var;
20132049
}
2014-
if (!found)
2015-
live_out[live_out_idx++] = bb->live_in[i];
20162050
}
20172051
return live_out_idx;
20182052
}
@@ -2022,6 +2056,7 @@ bool recompute_live_out(basic_block_t *bb)
20222056
var_t *live_out[MAX_ANALYSIS_STACK_SIZE];
20232057
int live_out_idx = 0;
20242058

2059+
/* Compute union of successor live_in sets */
20252060
if (bb->next) {
20262061
compute_live_in(bb->next);
20272062
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)
20352070
live_out_idx = merge_live_in(live_out, live_out_idx, bb->else_);
20362071
}
20372072

2073+
/* Quick check: if sizes differ, sets must be different */
20382074
if (bb->live_out_idx != live_out_idx) {
20392075
memcpy(bb->live_out, live_out, HOST_PTR_SIZE * live_out_idx);
20402076
bb->live_out_idx = live_out_idx;
20412077
return true;
20422078
}
20432079

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 */
20442099
for (int i = 0; i < live_out_idx; i++) {
20452100
int same = 0;
20462101
for (int j = 0; j < bb->live_out_idx; j++) {

0 commit comments

Comments
 (0)