diff options
| author | 2025-11-24 12:58:46 +0100 | |
|---|---|---|
| committer | 2025-11-24 12:58:46 +0100 | |
| commit | 5ba62d79923a48c1b1f6a8fc236650f5a8281844 (patch) | |
| tree | 7edc0d8828e1e5b71eb194b03672665e89ce754d | |
| parent | 31122c856c193085d427dc74459847a280728805 (diff) | |
ir: simplify some occurrences of single-argument phis
| -rw-r--r-- | ir/builder.c | 15 | ||||
| -rw-r--r-- | ir/ssa.c | 10 |
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]); } @@ -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]; |