aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir/ssa.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-10-19 08:09:09 +0200
committerlemon <lsof@mailbox.org>2025-10-19 08:09:09 +0200
commitdea8fd171acb54b6d9685422d5e391fb55074008 (patch)
tree2c149892f35c5183c9b2a1da4ab437228dc432ef /ir/ssa.c
parent3437945692f2b87883a4f066473c9deed50f25f5 (diff)
Organize source files into directories
Diffstat (limited to 'ir/ssa.c')
-rw-r--r--ir/ssa.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/ir/ssa.c b/ir/ssa.c
new file mode 100644
index 0000000..9b89878
--- /dev/null
+++ b/ir/ssa.c
@@ -0,0 +1,58 @@
+#include "ir.h"
+
+/* require use, keeps use */
+void
+copyopt(struct function *fn)
+{
+ struct block *blk = fn->entry;
+
+ do {
+ 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 ? KI4 : KI8;
+ else if (arg.t == RXCON) k = isnumcon(arg) ? conht[arg.i].cls : 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);
+}
+
+void
+filluses(struct function *fn)
+{
+ extern int ninstr;
+ struct block *blk = fn->entry;
+
+ for (int i = 0; i < ninstr; ++i)
+ deluses(i);
+
+ do {
+ for (int i = 0; i < blk->phi.n; ++i) {
+ int ins = blk->phi.p[i];
+ union ref *phi = phitab.p[instrtab[ins].l.i];
+ for (int i = 0; i < blk->npred; ++i)
+ adduse(blk, ins, phi[i]);
+ }
+ for (int i = 0; i < blk->ins.n; ++i) {
+ int ins = blk->ins.p[i];
+ adduse(blk, ins, instrtab[ins].l);
+ adduse(blk, ins, instrtab[ins].r);
+ }
+ adduse(blk, USERJUMP, blk->jmp.arg[0]);
+ adduse(blk, USERJUMP, blk->jmp.arg[1]);
+ } while ((blk = blk->lnext) != fn->entry);
+}
+
+/* vim:set ts=3 sw=3 expandtab: */