aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-11-23 19:38:38 +0100
committerlemon <lsof@mailbox.org>2025-11-23 19:38:38 +0100
commit0b77ae0eda8d3abca659f816040021a82a456e81 (patch)
treede72d56c0d0f3efb88faba88129d7825973bace8 /ir
parenta86bbfc553433e377e48f9e26c90bcc5b4fe0263 (diff)
c: check actual reachability for non-void func may not return value
Diffstat (limited to 'ir')
-rw-r--r--ir/ir.c21
-rw-r--r--ir/ir.h1
2 files changed, 22 insertions, 0 deletions
diff --git a/ir/ir.c b/ir/ir.c
index 412d0f9..4a092b3 100644
--- a/ir/ir.c
+++ b/ir/ir.c
@@ -451,6 +451,27 @@ numberinstrs(struct function *fn)
} while ((blk = blk->lnext) != fn->entry);
}
+static bool
+reachablerec(struct function *fn, struct block *blk)
+{
+ if (blk == fn->entry) return 1;
+ markvisited(blk);
+ if (blk->npred == 1 && !wasvisited(blkpred(blk, 0)))
+ return reachablerec(fn, blkpred(blk, 0));
+ else for (int i = 0; i < blk->npred; ++i) {
+ struct block *p = blkpred(blk, i);
+ if (!wasvisited(p) && reachablerec(fn, p)) return 1;
+ }
+ return 0;
+}
+
+bool
+blkreachable(struct function *fn, struct block *blk)
+{
+ startbbvisit();
+ return reachablerec(fn, blk);
+}
+
/* require use */
void
replcuses(union ref from, union ref to)
diff --git a/ir/ir.h b/ir/ir.h
index 77f25d4..9047233 100644
--- a/ir/ir.h
+++ b/ir/ir.h
@@ -277,6 +277,7 @@ void fillblkids(struct function *);
#define wasvisited(blk) ((blk)->visit == visitmark)
#define markvisited(blk) ((blk)->visit = visitmark)
void numberinstrs(struct function *);
+bool blkreachable(struct function *fn, struct block *blk);
/** builder.c **/
union ref irbinop(struct function *, enum op, enum irclass, union ref lhs, union ref rhs);