aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/ir_ssa.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-03-17 13:22:00 +0100
committerlemon <lsof@mailbox.org>2026-03-17 13:22:00 +0100
commita8d6f8bf30c07edb775e56889f568ca20240bedf (patch)
treeb5a452b2675b2400f15013617291fe6061180bbf /src/ir_ssa.c
parent24f14b7ad1af08d872971d72ce089a529911f657 (diff)
REFACTOR: move sources to src/
Diffstat (limited to 'src/ir_ssa.c')
-rw-r--r--src/ir_ssa.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/ir_ssa.c b/src/ir_ssa.c
new file mode 100644
index 0000000..6598fba
--- /dev/null
+++ b/src/ir_ssa.c
@@ -0,0 +1,46 @@
+#include "ir.h"
+
+void
+copyopt(struct function *fn)
+{
+ struct block *blk = fn->entry;
+
+ FREQUIRE(FNUSE);
+ do {
+ for (int i = 0; i < blk->phi.n; ++i) {
+ /* simplify same-arg phi */
+ int phi = blk->phi.p[i];
+ union ref *arg = phitab.p[instrtab[phi].l.i];
+ for (int j = 1; j < blk->npred; ++j) {
+ if (arg[j].bits != arg->bits) goto Next;
+ }
+ /* 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--);
+ }
+ Next:;
+ }
+ for (int i = 0; i < blk->ins.n; ++i) {
+ union ref var = mkref(RTMP, blk->ins.p[i]);
+ struct instr *ins = &instrtab[var.i];
+ enum irclass k;
+
+ if (ins->op == Ocopy) {
+ union ref arg = ins->l;
+ if (arg.t == RTMP) k = insrescls(instrtab[arg.i]);
+ else if (arg.t == RICON) k = cls2siz[ins->cls] == 4 ? KI32 : KI64;
+ else if (arg.t == RXCON) k = isnumcon(arg) ? concls(arg) : KPTR;
+ else continue;
+ if (ins->cls != k) continue;
+
+ replcuses(var, arg);
+ *ins = mkinstr(Onop,0,);
+ deluses(var.i);
+ }
+ }
+ delnops(blk);
+ } while ((blk = blk->lnext) != fn->entry);
+}
+
+/* vim:set ts=3 sw=3 expandtab: */