aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-11-21 17:07:28 +0100
committerlemon <lsof@mailbox.org>2025-11-21 17:35:55 +0100
commit87f9753fb776a1fa6e59baef759e4687fb9a1ac7 (patch)
tree192e36f06ac1bda63c3dceced36cb9c8562ca713 /ir
parent821adf9e5c962c97e46f3a215c876bc10916e302 (diff)
ir: barebones IR passes checked contracts
Diffstat (limited to 'ir')
-rw-r--r--ir/abi0.c5
-rw-r--r--ir/cfg.c3
-rw-r--r--ir/ir.c3
-rw-r--r--ir/ir.h8
-rw-r--r--ir/optmem.c3
-rw-r--r--ir/regalloc.c2
-rw-r--r--ir/ssa.c4
7 files changed, 26 insertions, 2 deletions
diff --git a/ir/abi0.c b/ir/abi0.c
index 895277c..fe1a7e3 100644
--- a/ir/abi0.c
+++ b/ir/abi0.c
@@ -348,6 +348,8 @@ abi0(struct function *fn)
struct block *blk;
union ref sret = {0};
+ FREQUIRE(FNUSE);
+
if (fn->retty.t == TYVOID) {
fn->nabiret = 0;
} else {
@@ -435,6 +437,9 @@ abi0(struct function *fn)
blk->id = id++;
} while ((blk = blk->lnext) != fn->entry);
+ /* vaargs might break */
+ fn->prop &= ~(FNBLKID | FNRPO);
+
if (ccopt.dbg.a) {
bfmt(ccopt.dbgout, "<< After abi0 >>\n");
irdump(fn);
diff --git a/ir/cfg.c b/ir/cfg.c
index e79dc63..758fa4e 100644
--- a/ir/cfg.c
+++ b/ir/cfg.c
@@ -10,6 +10,7 @@ porec(struct block ***rpo, struct block *b)
*--*rpo = b;
}
+/* also blkid */
void
sortrpo(struct function *fn)
{
@@ -47,6 +48,8 @@ sortrpo(struct function *fn)
}
fn->entry->lprev = rpo[-1];
rpo[-1]->lnext = fn->entry;
+
+ fn->prop |= FNBLKID | FNRPO;
}
/* vim:set ts=3 sw=3 expandtab: */
diff --git a/ir/ir.c b/ir/ir.c
index 6a40991..30da628 100644
--- a/ir/ir.c
+++ b/ir/ir.c
@@ -68,6 +68,7 @@ irinit(struct function *fn)
fn->entry = fn->curblk = allocz(fn->arena, sizeof(struct block), 0);
fn->nblk = 1;
fn->entry->lprev = fn->entry->lnext = fn->entry;
+ fn->prop = FNUSE; /* builder keeps this */
}
static int
@@ -552,6 +553,8 @@ fillblkids(struct function *fn)
int i = 0;
struct block *blk = fn->entry;
do blk->id = i++; while ((blk = blk->lnext) != fn->entry);
+
+ fn->prop |= FNBLKID;
}
/** Misc **/
diff --git a/ir/ir.h b/ir/ir.h
index 0879b86..1c7c02e 100644
--- a/ir/ir.h
+++ b/ir/ir.h
@@ -153,6 +153,12 @@ rsiter(int *i, uvlong rs)
return 1;
}
+enum {
+ FNBLKID = 1<<0,
+ FNUSE = 1<<1,
+ FNRPO = 1<<2,
+ FNDOM = 1<<3,
+};
struct function {
struct arena **arena;
const char *name;
@@ -161,6 +167,7 @@ struct function {
short *nuse;
union type fnty, retty;
struct abiarg *abiarg, abiret[2];
+ uint prop;
uint nblk;
int stksiz;
ushort nabiarg, nabiret;
@@ -168,6 +175,7 @@ struct function {
bool isleaf;
regset regusage;
};
+#define FREQUIRE(_prop) assert((fn->prop & (_prop)) && "preconditions not met")
enum objkind { OBJELF };
enum mcisa { ISamd64 };
diff --git a/ir/optmem.c b/ir/optmem.c
index d28ea53..3f5852b 100644
--- a/ir/optmem.c
+++ b/ir/optmem.c
@@ -225,7 +225,6 @@ cmpuse(const void *a, const void *b)
return blkfindins(blk, ua->u) - blkfindins(blk, ub->u);
}
-/* require use, blkid; keeps use */
void
mem2reg(struct function *fn)
{
@@ -233,6 +232,8 @@ mem2reg(struct function *fn)
struct ssabuilder sb = { .nblk = fn->nblk };
struct block *blk;
+ FREQUIRE(FNUSE);
+
if (fn->nblk <= 64 * arraylength(bsbuf[0])) {
sb.sealed = bsbuf[0];
sb.marked = bsbuf[1];
diff --git a/ir/regalloc.c b/ir/regalloc.c
index 8c8b39c..e9909ae 100644
--- a/ir/regalloc.c
+++ b/ir/regalloc.c
@@ -411,6 +411,8 @@ fixcssa(struct function *fn)
}
}
} while ((blk = blk->lnext) != fn->entry);
+
+ fn->prop &= ~FNBLKID;
}
static inline bool
diff --git a/ir/ssa.c b/ir/ssa.c
index 5a3db2f..f6c9d6f 100644
--- a/ir/ssa.c
+++ b/ir/ssa.c
@@ -1,11 +1,11 @@
#include "ir.h"
-/* require use, keeps use */
void
copyopt(struct function *fn)
{
struct block *blk = fn->entry;
+ FREQUIRE(FNUSE);
do {
for (int i = 0; i < blk->ins.n; ++i) {
union ref var = mkref(RTMP, blk->ins.p[i]);
@@ -53,6 +53,8 @@ filluses(struct function *fn)
adduse(blk, USERJUMP, blk->jmp.arg[0]);
adduse(blk, USERJUMP, blk->jmp.arg[1]);
} while ((blk = blk->lnext) != fn->entry);
+
+ fn->prop |= FNUSE;
}
/* vim:set ts=3 sw=3 expandtab: */