aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ir/builder.c15
-rw-r--r--ir/ssa.c10
2 files changed, 17 insertions, 8 deletions
diff --git a/ir/builder.c b/ir/builder.c
index c793f80..4b25329 100644
--- a/ir/builder.c
+++ b/ir/builder.c
@@ -228,19 +228,18 @@ useblk(struct function *fn, struct block *blk)
union ref
addphi(struct function *fn, enum irclass cls, union ref *r)
{
- int new;
- struct instr ins = { Ophi, cls };
- union ref *refs = NULL;
+ assert(fn->curblk);
+ if (fn->curblk->npred == 0) return UNDREF;
+ if (fn->curblk->npred == 1) /* 1-argument phi is identity */
+ return *r;
+ union ref *refs = NULL;
xbgrow(&refs, fn->curblk->npred);
memcpy(refs, r, fn->curblk->npred * sizeof *r);
vpush(&phitab, refs);
- ins.l = mkref(RXXX, phitab.n-1);
-
- assert(fn->curblk != NULL);
/*assert(fn->curblk->ins.n == 0);*/
- new = allocinstr();
- instrtab[new] = ins;
+ int new = allocinstr();
+ instrtab[new] = mkinstr(Ophi, cls, .l.i = phitab.n-1);
for (int i = 0; i < fn->curblk->npred; ++i) {
adduse(fn->curblk, new, r[i]);
}
diff --git a/ir/ssa.c b/ir/ssa.c
index f6c9d6f..5c9c8f3 100644
--- a/ir/ssa.c
+++ b/ir/ssa.c
@@ -7,6 +7,16 @@ copyopt(struct function *fn)
FREQUIRE(FNUSE);
do {
+ if (blk->npred == 1) for (int i = 0; i < blk->phi.n; ++i) {
+ /* simplify 1-arg phi */
+ int phi = blk->phi.p[i];
+ union ref *arg = phitab.p[instrtab[phi].l.i];
+ /* being conservative here because phis could have circular dependencies? */
+ if (arg->t != RTMP || instrtab[arg->i].op != Ophi) {
+ replcuses(mkref(RTMP, phi), *arg);
+ delphi(blk, i--);
+ }
+ }
for (int i = 0; i < blk->ins.n; ++i) {
union ref var = mkref(RTMP, blk->ins.p[i]);
struct instr *ins = &instrtab[var.i];