Skip to content

Commit a3fe403

Browse files
committed
Add SSA memoization via duplicate detection
Implement memoization in SSA analysis without modifying data structures. Uses duplicate detection in dominance frontier arrays to prevent O(n²) duplicate scenarios in dominance frontier computation.
1 parent 8b807b6 commit a3fe403

File tree

1 file changed

+53
-24
lines changed

1 file changed

+53
-24
lines changed

src/ssa.c

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ bool dom_connect(basic_block_t *pred, basic_block_t *succ)
190190
int i;
191191
for (i = 0; i < MAX_BB_DOM_SUCC; i++) {
192192
if (pred->dom_next[i] == succ)
193-
return false;
193+
return false; /* Already connected - memoization */
194194
if (!pred->dom_next[i])
195195
break;
196196
}
@@ -226,6 +226,27 @@ void build_dom(void)
226226
}
227227
}
228228

229+
/* Add bb to dominance frontier with memoization */
230+
void add_to_df(basic_block_t *bb, basic_block_t *predecessor)
231+
{
232+
if (!predecessor)
233+
return;
234+
235+
for (basic_block_t *curr = predecessor; curr != bb->idom;
236+
curr = curr->idom) {
237+
/* Check if bb is already in curr's dominance frontier */
238+
bool already_added = false;
239+
for (int j = 0; j < curr->df_idx; j++) {
240+
if (curr->DF[j] == bb) {
241+
already_added = true;
242+
break;
243+
}
244+
}
245+
if (!already_added)
246+
curr->DF[curr->df_idx++] = bb;
247+
}
248+
}
249+
229250
void bb_build_df(func_t *func, basic_block_t *bb)
230251
{
231252
UNUSED(func);
@@ -239,12 +260,8 @@ void bb_build_df(func_t *func, basic_block_t *bb)
239260
return;
240261

241262
for (int i = 0; i < MAX_BB_PRED; i++) {
242-
if (!bb->prev[i].bb)
243-
continue;
244-
245-
for (basic_block_t *curr = bb->prev[i].bb; curr != bb->idom;
246-
curr = curr->idom)
247-
curr->DF[curr->df_idx++] = bb;
263+
if (bb->prev[i].bb)
264+
add_to_df(bb, bb->prev[i].bb);
248265
}
249266
}
250267

@@ -317,7 +334,7 @@ bool rdom_connect(basic_block_t *pred, basic_block_t *succ)
317334
int i;
318335
for (i = 0; i < MAX_BB_RDOM_SUCC; i++) {
319336
if (pred->rdom_next[i] == succ)
320-
return false;
337+
return false; /* Already connected - memoization */
321338
if (!pred->rdom_next[i])
322339
break;
323340
}
@@ -353,6 +370,27 @@ void build_rdom(void)
353370
}
354371
}
355372

373+
/* Add bb to reverse dominance frontier with memoization */
374+
void add_to_rdf(basic_block_t *bb, basic_block_t *successor)
375+
{
376+
if (!successor)
377+
return;
378+
379+
for (basic_block_t *curr = successor; curr != bb->r_idom;
380+
curr = curr->r_idom) {
381+
/* Check if bb is already in curr's reverse dominance frontier */
382+
bool already_added = false;
383+
for (int j = 0; j < curr->rdf_idx; j++) {
384+
if (curr->RDF[j] == bb) {
385+
already_added = true;
386+
break;
387+
}
388+
}
389+
if (!already_added)
390+
curr->RDF[curr->rdf_idx++] = bb;
391+
}
392+
}
393+
356394
void bb_build_rdf(func_t *func, basic_block_t *bb)
357395
{
358396
UNUSED(func);
@@ -367,21 +405,10 @@ void bb_build_rdf(func_t *func, basic_block_t *bb)
367405
if (cnt <= 0)
368406
return;
369407

370-
if (bb->next) {
371-
for (basic_block_t *curr = bb->next; curr != bb->r_idom;
372-
curr = curr->r_idom)
373-
curr->RDF[curr->rdf_idx++] = bb;
374-
}
375-
if (bb->else_) {
376-
for (basic_block_t *curr = bb->else_; curr != bb->r_idom;
377-
curr = curr->r_idom)
378-
curr->RDF[curr->rdf_idx++] = bb;
379-
}
380-
if (bb->then_) {
381-
for (basic_block_t *curr = bb->then_; curr != bb->r_idom;
382-
curr = curr->r_idom)
383-
curr->RDF[curr->rdf_idx++] = bb;
384-
}
408+
/* Process all possible successors */
409+
add_to_rdf(bb, bb->next);
410+
add_to_rdf(bb, bb->else_);
411+
add_to_rdf(bb, bb->then_);
385412
}
386413

387414
void build_rdf(void)
@@ -2051,12 +2078,14 @@ bool recompute_live_out(basic_block_t *bb)
20512078
live_out_idx = merge_live_in(live_out, live_out_idx, bb->else_);
20522079
}
20532080

2081+
/* Early exit if size differs - memoization optimization */
20542082
if (bb->live_out_idx != live_out_idx) {
20552083
memcpy(bb->live_out, live_out, HOST_PTR_SIZE * live_out_idx);
20562084
bb->live_out_idx = live_out_idx;
20572085
return true;
20582086
}
20592087

2088+
/* Check if content is the same - memoization optimization */
20602089
for (int i = 0; i < live_out_idx; i++) {
20612090
bool same = false;
20622091
for (int j = 0; j < bb->live_out_idx; j++) {
@@ -2071,7 +2100,7 @@ bool recompute_live_out(basic_block_t *bb)
20712100
return true;
20722101
}
20732102
}
2074-
return false;
2103+
return false; /* No change - memoized result */
20752104
}
20762105

20772106
void liveness_analysis(void)

0 commit comments

Comments
 (0)