aboutsummaryrefslogtreecommitdiff
path: root/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'cfg.c')
-rw-r--r--cfg.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/cfg.c b/cfg.c
index 8047c12..8d31f18 100644
--- a/cfg.c
+++ b/cfg.c
@@ -396,3 +396,48 @@ reachesnotvia(Fn *fn, Blk *b, Blk *to, Blk *excl)
excl->visit = 1;
return reaches(fn, b, to);
}
+
+int
+ifgraph(Blk *ifb, Blk **pthenb, Blk **pelseb, Blk **pjoinb)
+{
+ Blk *s1, *s2, **t;
+
+ if (ifb->jmp.type != Jjnz)
+ return 0;
+
+ s1 = ifb->s1;
+ s2 = ifb->s2;
+ if (s1->id > s2->id) {
+ s1 = ifb->s2;
+ s2 = ifb->s1;
+ t = pthenb;
+ pthenb = pelseb;
+ pelseb = t;
+ }
+ if (s1 == s2)
+ return 0;
+
+ if (s1->jmp.type != Jjmp || s1->npred != 1)
+ return 0;
+
+ if (s1->s1 == s2) {
+ /* if-then / if-else */
+ if (s2->npred != 2)
+ return 0;
+ *pthenb = s1;
+ *pelseb = ifb;
+ *pjoinb = s2;
+ return 1;
+ }
+
+ if (s2->jmp.type != Jjmp || s2->npred != 1)
+ return 0;
+ if (s1->s1 != s2->s1 || s1->s1->npred != 2)
+ return 0;
+
+ assert(s1->s1 != ifb);
+ *pthenb = s1;
+ *pelseb = s2;
+ *pjoinb = s1->s1;
+ return 1;
+}