aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir/cfg.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-03-16 12:15:13 +0100
committerlemon <lsof@mailbox.org>2026-03-16 12:15:13 +0100
commit3e83c4280f0b1d72774c522a7e0d135913151b56 (patch)
treebd80eeae4386e269d09aeaf18590d306c83c646d /ir/cfg.c
parent5e6f97a1cadb1a1f8a1ed7cb4bd44bd1c79c150a (diff)
ir: blk loop index for spill cost
Diffstat (limited to 'ir/cfg.c')
-rw-r--r--ir/cfg.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/ir/cfg.c b/ir/cfg.c
index 984b6a9..86af3f3 100644
--- a/ir/cfg.c
+++ b/ir/cfg.c
@@ -95,4 +95,36 @@ filldom(struct function *fn)
fn->prop |= FNBLKID | FNDOM;
}
+static void
+loopmark(struct block *head, struct block *blk)
+{
+ if (blk->id < head->id || blk->visit == head->id) return;
+ blk->visit = head->id;
+ ++blk->loop;
+ for (int i = 0; i < blk->npred; ++i)
+ loopmark(head, blkpred(blk, i));
+}
+
+void
+fillloop(struct function *fn)
+{
+ struct block *b = fn->entry;
+ int id = 0;
+ FREQUIRE(FNRPO);
+ do {
+ b->id = id++;
+ b->visit = -1u;
+ b->loop = 0;
+ } while ((b = b->lnext) != fn->entry);
+ do {
+ for (int i = 0; i < b->npred; ++i) {
+ struct block *p = blkpred(b, i);
+ if (p->id > b->id) { /* b is loop header */
+ loopmark(b, p);
+ }
+ }
+ } while ((b = b->lnext) != fn->entry);
+ fn->prop |= FNBLKID;
+}
+
/* vim:set ts=3 sw=3 expandtab: */