aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir/ir.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-11-14 18:49:04 +0100
committerlemon <lsof@mailbox.org>2025-11-14 19:04:51 +0100
commita287fe5aeb6b681ab405c0297841dce64ab4b946 (patch)
tree5ae81f3b60cc910cd356059a77e89dd50ca83b42 /ir/ir.c
parentfc91a4ce139fd0236ad9e8c4fe1e7dad42f0b178 (diff)
preeliminary va_list support
Diffstat (limited to 'ir/ir.c')
-rw-r--r--ir/ir.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/ir/ir.c b/ir/ir.c
index f3e6e89..0f716f9 100644
--- a/ir/ir.c
+++ b/ir/ir.c
@@ -234,8 +234,7 @@ delpred(struct block *blk, struct block *p)
struct block *
newblk(struct function *fn)
{
- struct block *blk = alloc(fn->arena, sizeof(struct block), 0);
- memset(blk, 0, sizeof *blk);
+ struct block *blk = allocz(fn->arena, sizeof(struct block), 0);
blk->id = -1;
return blk;
}
@@ -297,8 +296,36 @@ insertblk(struct function *fn, struct block *pred, struct block *subst)
assert(0);
}
+struct block *
+blksplitafter(struct function *fn, struct block *blk, int idx)
+{
+ struct block *new = newblk(fn);
+ ++fn->nblk;
+ new->lprev = blk;
+ new->lnext = blk->lnext;
+ blk->lnext = new;
+ new->lnext->lprev = new;
+ if (idx < blk->ins.n-1)
+ vpushn(&new->ins, &blk->ins.p[idx+1], blk->ins.n-idx-1);
+ blk->ins.n -= new->ins.n;
+ new->jmp = blk->jmp;
+ blk->jmp.t = Jb;
+ memset(blk->jmp.arg, 0, sizeof blk->jmp.arg);
+ for (int i = 0; i < 2; ++i) {
+ struct block *s = (&blk->s1)[i];
+ for (int i = 0; i < s->npred; ++i) {
+ if (blkpred(s, i) == blk)
+ blkpred(s, i) = new;
+ }
+ }
+ new->s1 = blk->s1, new->s2 = blk->s2;
+ blk->s1 = new, blk->s2 = NULL;
+ addpred(new, blk);
+ return new;
+}
+
int
-newinstr(void)
+allocinstr(void)
{
int t;
if (instrfreelist != -1) {
@@ -358,12 +385,22 @@ Shrink:
return 1;
}
+int
+newinstr(struct block *at, struct instr ins)
+{
+ int new = allocinstr();
+ instrtab[new] = ins;
+ if (at) {
+ adduse(at, new, ins.l);
+ adduse(at, new, ins.r);
+ }
+ return new;
+}
+
union ref
insertinstr(struct block *blk, int idx, struct instr ins)
{
- int new = newinstr();
-
- instrtab[new] = ins;
+ int new = newinstr(blk, ins);
if (idx == blk->ins.n) vpush(&blk->ins, new);
else {
assert(idx >= 0 && idx < blk->ins.n);
@@ -373,15 +410,13 @@ insertinstr(struct block *blk, int idx, struct instr ins)
blk->ins.p[i] = blk->ins.p[i - 1];
blk->ins.p[idx] = new;
}
- adduse(blk, new, ins.l);
- adduse(blk, new, ins.r);
return mkref(RTMP, new);
}
union ref
insertphi(struct block *blk, enum irclass cls)
{
- int new = newinstr();
+ int new = allocinstr();
union ref *refs = NULL;
assert(blk->npred > 0);
xbgrowz(&refs, blk->npred);