diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-27 10:34:22 -0500 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2017-02-27 10:34:29 -0500 |
commit | e80252a52bf25f762bc986ce6e4e0d17fbb130d0 (patch) | |
tree | 06b476558944a83d6c3e11ecc322a568caf1fe94 /cfg.c | |
parent | 3aecf460f5ab60c96ba90042ffd1cd7df41eeca5 (diff) | |
download | roux-e80252a52bf25f762bc986ce6e4e0d17fbb130d0.tar.gz |
scrub assembly output
Notably, this adds a new pass to get rid of jumps on jumps.
Diffstat (limited to 'cfg.c')
-rw-r--r-- | cfg.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/cfg.c b/cfg.c index e210589..e695f39 100644 --- a/cfg.c +++ b/cfg.c @@ -278,3 +278,47 @@ fillloop(Fn *fn) b->loop = 1; loopiter(fn, multloop); } + +static void +uffind(Blk **pb, Blk **uf, Fn *fn) +{ + Blk **pb1; + + pb1 = &uf[(*pb)->id]; + if (*pb1 != *pb) + uffind(pb1, uf, fn); + *pb = *pb1; +} + +/* requires rpo and no phis, breaks cfg */ +void +simpljmp(Fn *fn) +{ + + Blk **uf; /* union-find */ + Blk *b; + uint n; + int c; + + uf = alloc(fn->nblk * sizeof uf[0]); + for (n=0; n<fn->nblk; n++) + uf[n] = fn->rpo[n]; + for (b=fn->start; b; b=b->link) { + assert(!b->phi); + if (b->nins == 0) + if (b->jmp.type == Jjmp) + uf[b->id] = b->s1; + } + for (b=fn->start; b; b=b->link) { + if (b->s1) + uffind(&b->s1, uf, fn); + if (b->s2) + uffind(&b->s2, uf, fn); + c = b->jmp.type - Jxjc; + if (0 <= c && c <= NXICmp) + if (b->s1 == b->s2) { + b->jmp.type = Jjmp; + b->s2 = 0; + } + } +} |