aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2023-06-22 20:17:21 +0200
committerlemon <lsof@mailbox.org>2023-06-22 20:17:21 +0200
commit8245dfa2d5c6e074d577d756f40243cd2c0363c7 (patch)
treec1901de6cc85a9ecec8cc9f86df647779c1a1b14
parent3f2221dfb9ab33b7ac44bbf822a78753a0357d25 (diff)
misc fix
-rw-r--r--ir.c47
-rw-r--r--ir.h3
-rw-r--r--optmem.c23
3 files changed, 55 insertions, 18 deletions
diff --git a/ir.c b/ir.c
index d1f3ec9..a42bf55 100644
--- a/ir.c
+++ b/ir.c
@@ -250,7 +250,7 @@ newinstr(void)
assert(ninstr < arraylength(instrtab));
t = ninstr++;
}
- if (instrnuse[t] > 2)
+ if (instrnuse[t] > arraylength(*instrusebuf))
xbfree(instruse[t]);
instruse[t] = instrusebuf[t];
instrnuse[t] = 0;
@@ -261,12 +261,12 @@ void
adduse(struct block *ublk, int ui, union ref r) {
struct use user = { ublk, ui };
if (r.t != RTMP) return;
- if (instrnuse[r.i] < 2) {
+ if (instrnuse[r.i] < arraylength(*instrusebuf)) {
instruse[r.i][instrnuse[r.i]++] = user;
} else if (instrnuse[r.i] == arraylength(*instrusebuf)) {
struct use *use = NULL;
xbgrow(&use, arraylength(*instrusebuf) + 2);
- memcpy(use, instruse[r.i], arraylength(*instrusebuf) * sizeof *use);
+ memcpy(use, instruse[r.i], sizeof(*instrusebuf));
use[instrnuse[r.i]++] = user;
instruse[r.i] = use;
} else {
@@ -274,6 +274,30 @@ adduse(struct block *ublk, int ui, union ref r) {
}
}
+bool
+deluse(struct block *ublk, int ui, union ref r) {
+ if (r.t != RTMP) return 0;
+
+ for (int i = 0; i < instrnuse[r.i]; ++i) {
+ if (instruse[r.i][i].blk == ublk && instruse[r.i][i].u == ui) {
+ for (int k = i; k < instrnuse[r.i] - 1; ++k) {
+ instruse[r.i][k] = instruse[r.i][k+1];
+ }
+ goto Shrink;
+ }
+ }
+ return 0;
+
+Shrink:
+ if (instrnuse[r.i] == arraylength(*instrusebuf) + 1) {
+ struct use *use = instruse[r.i];
+ instruse[r.i] = instrusebuf[r.i];
+ memcpy(instruse[r.i], use, sizeof *instrusebuf);
+ }
+ --instrnuse[r.i];
+ return 1;
+}
+
union ref
insertinstr(struct block *blk, int idx, struct instr ins)
{
@@ -310,7 +334,7 @@ insertphi(struct block *blk, enum irclass cls)
/* require use */
void
-replcins(union ref from, union ref to)
+replcuses(union ref from, union ref to)
{
struct use *use, *uend;
@@ -333,7 +357,9 @@ replcins(union ref from, union ref to)
for (i = 0; i < n; ++i) {
if (u[i].bits == from.bits) {
+ deluse(use->blk, use->u, u[i]);
u[i].bits = to.bits;
+ adduse(use->blk, use->u, u[i]);
break;
}
}
@@ -361,6 +387,19 @@ delinstr(struct block *blk, int idx)
--blk->ins.n;
}
+void
+delphi(struct block *blk, int idx)
+{
+ int t = blk->phi.p[idx];
+ assert(idx >= 0 && idx < blk->phi.n);
+ memcpy(&instrtab[t], &instrfreelist, sizeof(int));
+ instrfreelist = t;
+ deluses(t);
+ for (int i = idx; i < blk->phi.n; ++i)
+ blk->phi.p[i] = blk->phi.p[i + 1];
+ --blk->phi.n;
+}
+
/** IR builders **/
struct block *
diff --git a/ir.h b/ir.h
index 45a64a2..a8b3356 100644
--- a/ir.h
+++ b/ir.h
@@ -228,9 +228,10 @@ union ref mkaddr(struct addr);
void adduse(struct block *ublk, int ui, union ref r);
union ref insertinstr(struct block *, int idx, struct instr);
union ref insertphi(struct block *, enum irclass cls);
-void replcins(union ref from, union ref to);
+void replcuses(union ref from, union ref to);
void deluses(int ins);
void delinstr(struct block *, int idx);
+void delphi(struct block *, int idx);
#define blkpred(blk, i) 0[(blk)->npred < 2 ? &(blk)->_pred0 : &(blk)->_pred[i]]
/* IR builder functions */
diff --git a/optmem.c b/optmem.c
index c9b4536..b5eaae4 100644
--- a/optmem.c
+++ b/optmem.c
@@ -49,25 +49,22 @@ deltrivialphis(struct block *blk, union ref phiref)
same = UNDREF; /* the phi is unreachable or in the start block */
/* replace uses */
- replcins(phiref, same);
+ replcuses(phiref, same);
- /* remove phi */
- for (int i = 0; i < blk->phi.n; ++i) {
- if (blk->phi.p[i] == phiref.i) {
- for (int k = i; k < blk->phi.n - 1; ++k)
- blk->phi.p[k] = blk->phi.p[k + 1];
- --blk->phi.n;
- break;
- }
- }
instrtab[phiref.i].op = Onop;
/* recursively try to remove all phi users as they might have become trivial */
for (use = instruse[phiref.i], uend = use + instrnuse[phiref.i]; use < uend; ++use)
- if (use->u != USERJUMP && instrtab[use->u].op == Ophi && use->u != phiref.i)
+ if (use->u != USERJUMP && instrtab[use->u].op == Ophi)
deltrivialphis(use->blk, mkref(RTMP, use->u));
- deluses(phiref.i);
+ /* remove phi */
+ for (int i = 0; i < blk->phi.n; ++i) {
+ if (blk->phi.p[i] == phiref.i) {
+ delphi(blk, i);
+ break;
+ }
+ }
return same;
}
@@ -187,7 +184,7 @@ mem2reg(struct function *fn)
}
}
/* remove alloca */
- delinstr(blk, i);
+ delinstr(blk, i--);
Next:;
}