aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2023-06-22 21:54:08 +0200
committerlemon <lsof@mailbox.org>2023-06-22 21:54:08 +0200
commitd313c6e49bfb32ae24745e90eebe833da20efa1a (patch)
tree73f950f515b4442a800ecc4e35c346b0cc263a89
parent836f91535f421be4cba2840aed55aba3c5f72f1b (diff)
change RMORE -> RADDR; use RXXX (RNONE) for special args,also undef
-rw-r--r--abi0.c6
-rw-r--r--amd64/emit.c28
-rw-r--r--amd64/isel.c24
-rw-r--r--ir.c10
-rw-r--r--ir.h29
-rw-r--r--irdump.c12
-rw-r--r--optmem.c6
-rw-r--r--regalloc.c30
-rw-r--r--ssa.c2
9 files changed, 73 insertions, 74 deletions
diff --git a/abi0.c b/abi0.c
index 2024424..a798735 100644
--- a/abi0.c
+++ b/abi0.c
@@ -316,7 +316,7 @@ abi0(struct function *fn)
do {
union ref arg = blk->jmp.arg[0];
if (blk->jmp.t != Jret) continue;
- if (!arg.t) continue;
+ if (!arg.bits) continue;
if (arg.t != RTMP || !oisalloca(instrtab[arg.i].op)) {
rvovar = -1;
break;
@@ -342,8 +342,8 @@ abi0(struct function *fn)
}
/* adjust returns */
- if (isagg(fn->retty) && blk->jmp.t == Jret && blk->jmp.arg[0].t) {
- assert(!blk->jmp.arg[1].t);
+ if (isagg(fn->retty) && blk->jmp.t == Jret && blk->jmp.arg[0].bits) {
+ assert(!blk->jmp.arg[1].bits);
if (fn->nabiret) { /* aggregate return in register(s) */
union ref src = blk->jmp.arg[0];
for (int i = 0; i < fn->nabiret; ++i) {
diff --git a/amd64/emit.c b/amd64/emit.c
index d3dad9c..f354262 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -38,7 +38,7 @@ ref2oper(union ref r)
else if (!conht[r.i].cls)
return mkoper(OCONR, .con = r.i);
assert(0);
- case RMORE: return mkmemoper(r);
+ case RADDR: return mkmemoper(r);
default: assert(0);
}
}
@@ -108,19 +108,19 @@ mkmemoper(union ref r)
if (wop.t == OMEM) return wop;
assert(wop.t == OREG);
return mkoper(OMEM, .base = wop.reg, .index = NOINDEX);
- } else if (r.t == RMORE) {
+ } else if (r.t == RADDR) {
const struct addr *addr = &addrht[r.i];
struct oper mem;
if (addr->base.t == RTMP && ioper[addr->base.i].t == OMEM) {
mem = ioper[addr->base.i];
- if (addr->index.t) addmemoper(&mem, mkregoper(addr->index));
+ if (addr->index.bits) addmemoper(&mem, mkregoper(addr->index));
assert(!mem.shift);
mem.shift = addr->shift;
addmemoper(&mem, mkoper(OIMM, .imm = addr->disp));
return mem;
}
- return mkoper(OMEM, .base = addr->base.t ? mkregoper(addr->base).reg : NOBASE,
- .index = addr->index.t ? mkregoper(addr->index).reg : NOINDEX,
+ return mkoper(OMEM, .base = addr->base.bits ? mkregoper(addr->base).reg : NOBASE,
+ .index = addr->index.bits ? mkregoper(addr->index).reg : NOINDEX,
.disp = addr->disp,
.shift = addr->shift);
} else if (r.t == RXCON) {
@@ -565,7 +565,7 @@ flagslivep(struct block *blk, int curi)
{
int cmpi;
/* conditional branch that references a previous comparison instruction? */
- if (blk->jmp.t != Jb || !blk->jmp.arg[0].t)
+ if (blk->jmp.t != Jb || !blk->jmp.arg[0].bits)
return 0;
assert(blk->jmp.arg[0].t == RTMP);
cmpi = blk->jmp.arg[1].i;
@@ -583,29 +583,29 @@ static void
gencopy(uchar **pcode, enum irclass cls, struct block *blk, int curi, struct oper dst, union ref val)
{
assert(dst.t == OREG);
- if (val.t == RMORE) {
+ if (val.t == RADDR) {
/* this is a LEA, but maybe it can be lowered to a 2-address instruction,
* which may clobber flags */
const struct addr *addr = &addrht[val.i];
if (flagslivep(blk, curi)) goto Lea;
- if (addr->base.t && dst.reg == mkregoper(addr->base).reg) { /* base = dst */
- if (addr->index.t && !addr->disp && !addr->shift){
+ if (addr->base.bits && dst.reg == mkregoper(addr->base).reg) { /* base = dst */
+ if (addr->index.bits && !addr->disp && !addr->shift){
/* lea Rx, [Rx + Ry] -> add Rx, Ry */
Xadd(pcode, cls, dst, mkregoper(addr->index));
return;
- } else if (!addr->index.t) {
+ } else if (!addr->index.bits) {
if (!addr->disp) /* lea Rx, [Rx] -> mov Rx, Rx */
Xmov(pcode, cls, dst, dst);
else /* lea Rx, [Rx + Imm] -> add Rx, Imm */
Xadd(pcode, cls, dst, mkoper(OIMM, .imm = addr->disp));
return;
}
- } else if (addr->index.t && dst.reg == mkregoper(addr->index).reg) { /* index = dst */
- if (addr->base.t && !addr->disp && !addr->shift) {
+ } else if (addr->index.bits && dst.reg == mkregoper(addr->index).reg) { /* index = dst */
+ if (addr->base.bits && !addr->disp && !addr->shift) {
/* lea Rx, [Ry + Rx] -> add Rx, Ry */
Xadd(pcode, cls, dst, mkregoper(addr->base));
return;
- } else if (!addr->base.t) {
+ } else if (!addr->base.bits) {
if (!addr->disp && !addr->shift) /* lea Rx, [Rx] -> mov Rx, Rx */
Xmov(pcode, cls, dst, dst);
else if (!addr->shift) /* lea Rx, [Rx + Imm] -> add Rx, Imm */
@@ -789,7 +789,7 @@ emitbranch(uchar **pcode, struct block *blk)
/* conditional branch.. */
union ref arg = blk->jmp.arg[0];
- if (!arg.t) /* implicit by ZF */
+ if (!arg.bits) /* implicit by ZF */
cc = CCNZ;
else {
struct instr *ins;
diff --git a/amd64/isel.c b/amd64/isel.c
index 3f83312..cb87b7d 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -146,7 +146,7 @@ static bool
ascale(struct addr *addr, union ref a, union ref b)
{
if (b.t != RICON) return 0;
- if (addr->index.t) return 0;
+ if (addr->index.bits) return 0;
if (a.t != RTMP && a.t != RREG) return 0;
if ((unsigned)b.i > 3) return 0;
addr->shift = b.i;
@@ -167,11 +167,11 @@ aadd(struct addr *addr, union ref r)
} else if (ins->op == Oshl) {
if (!ascale(addr, ins->l, ins->r)) goto Ref;
ins->skip = 1;
- } else if (ins->op == Ocopy && ins->l.t == RMORE) {
+ } else if (ins->op == Ocopy && ins->l.t == RADDR) {
struct addr save = *addr, *addr2 = &addrht[ins->l.i];
- if ((!addr2->base.t || aadd(addr, addr2->base))
+ if ((!addr2->base.bits || aadd(addr, addr2->base))
&& acon(addr, mkintcon(KI4, addr2->disp))
- && (!addr2->index.t || ascale(addr, addr2->index, mkref(RICON, addr2->shift))))
+ && (!addr2->index.bits || ascale(addr, addr2->index, mkref(RICON, addr2->shift))))
{
ins->skip = 1;
} else {
@@ -189,8 +189,8 @@ aadd(struct addr *addr, union ref r)
* safely hoisted into an address value, unless they have global lifetime */
if (!bstest(mctarg->rglob, r.i)) return 0;
Ref:
- if (!addr->base.t) addr->base = r;
- else if (!addr->index.t) addr->index = r;
+ if (!addr->base.bits) addr->base = r;
+ else if (!addr->index.bits) addr->index = r;
else return 0;
} else return 0;
return 1;
@@ -201,7 +201,7 @@ fuseaddr(union ref *r)
{
struct addr addr = { 0 };
- if (r->t == RMORE) return 1;
+ if (r->t == RADDR) return 1;
if (r->t == RXCON && (!conht[r->i].cls && !conht[r->i].deref)) return 1;
if (r->t != RTMP) return 0;
if (!aadd(&addr, *r)) return 0;
@@ -216,7 +216,7 @@ addarg4addrp(union ref r)
{
struct instr *ins = &instrtab[r.i];
if (r.t != RTMP) return 0;
- return ins->op == Oshl || (ins->op == Ocopy && ins->l.t == RMORE) || ins->op == Oadd;
+ return ins->op == Oshl || (ins->op == Ocopy && ins->l.t == RADDR) || ins->op == Oadd;
}
static void
@@ -344,7 +344,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
ins->inplace = 1;
if (ins->l.t != RTMP && ins->l.t != RREG)
ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, ins->l));
- if (ins->r.t)
+ if (ins->r.bits)
case Omove:
fixarg(&ins->r, ins, blk, curi);
break;
@@ -367,7 +367,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
static void
seljmp(struct function *fn, struct block *blk)
{
- if (blk->jmp.t == Jb && blk->jmp.arg[0].t) {
+ if (blk->jmp.t == Jb && blk->jmp.arg[0].bits) {
union ref c = blk->jmp.arg[0];
if (c.t != RTMP) {
enum irclass cls = c.t == RICON ? KI4 : c.t == RXCON && conht[c.i].cls ? conht[c.i].cls : KPTR;
@@ -385,14 +385,14 @@ seljmp(struct function *fn, struct block *blk)
}
}
} else if (blk->jmp.t == Jret) {
- if (blk->jmp.arg[0].t) {
+ if (blk->jmp.arg[0].bits) {
int curi;
union ref r = mkref(RREG, fn->abiret[0].reg);
struct instr *ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr(Omove, fn->abiret[0].ty.cls, r , blk->jmp.arg[0])).i];
curi = blk->ins.n;
fixarg(&ins->r, ins, blk, &curi);
blk->jmp.arg[0] = r;
- if (blk->jmp.arg[1].t) {
+ if (blk->jmp.arg[1].bits) {
r = mkref(RREG, fn->abiret[1].reg);
ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr(Omove, fn->abiret[1].ty.cls, r, blk->jmp.arg[1])).i];
curi = blk->ins.n;
diff --git a/ir.c b/ir.c
index a42bf55..8fb6fed 100644
--- a/ir.c
+++ b/ir.c
@@ -69,7 +69,7 @@ addaddr(const struct addr *addr)
uint i = h, n = arraylength(addrht);
for (;; ++i) {
i &= arraylength(addrht) - 1;
- if (!addrht[i].base.t && !addrht[i].index.t) {
+ if (!addrht[i].base.bits && !addrht[i].index.bits) {
addrht[i] = *addr;
++naddrht;
return i;
@@ -213,13 +213,13 @@ mkcallarg(union irtype ret, uint narg, int vararg)
struct call call = { .ret=ret, .narg=narg, .vararg=vararg };
assert((long) vararg <= narg);
vpush(&calltab, call);
- return mkref(RMORE, calltab.n-1);
+ return mkref(RXXX, calltab.n-1);
}
union ref
mkaddr(struct addr addr)
{
- return mkref(RMORE, addaddr(&addr));
+ return mkref(RADDR, addaddr(&addr));
}
static inline void
@@ -327,7 +327,7 @@ insertphi(struct block *blk, enum irclass cls)
xbgrow(&refs, blk->npred);
memset(refs, 0, blk->npred * sizeof *refs);
vpush(&phitab, refs);
- instrtab[new] = mkinstr(Ophi, cls, mkref(RMORE, phitab.n - 1));
+ instrtab[new] = mkinstr(Ophi, cls, mkref(RXXX, phitab.n - 1));
vpush(&blk->phi, new);
return mkref(RTMP, new);
}
@@ -449,7 +449,7 @@ addphi(struct function *fn, enum irclass cls, union ref *r)
xbgrow(&refs, fn->curblk->npred);
memcpy(refs, r, fn->curblk->npred * sizeof *r);
vpush(&phitab, refs);
- ins.l = mkref(RMORE, phitab.n-1);
+ ins.l = mkref(RXXX, phitab.n-1);
assert(fn->curblk != NULL);
assert(fn->curblk->ins.n == 0);
diff --git a/ir.h b/ir.h
index a8b3356..0ebe68b 100644
--- a/ir.h
+++ b/ir.h
@@ -59,13 +59,13 @@ struct call {
};
enum refkind {
- RNONE,
- RTMP, /* reference to another instruction's result */
- RREG, /* machine register */
- RICON, /* small integer constants */
- RXCON, /* other constants (incl. external symbols) */
- RMORE, /* Ocall -> calltab idx, Ophi -> phitab idx, else -> addrtab idx */
- RTYPE, /* irtype */
+ RXXX, /* used for empty ref (zeros), undef, and the special args of call,phi,etc */
+ RTMP, /* reference to another instruction's result */
+ RREG, /* machine register */
+ RICON, /* small integer constants */
+ RXCON, /* other constants (incl. external symbols) */
+ RADDR, /* target-specific addressing mode */
+ RTYPE, /* irtype */
};
union ref {
@@ -78,6 +78,14 @@ struct addr {
int shift, disp;
};
+#define insrescls(ins) (oiscmp((ins).op) ? KI4 : (ins).cls)
+#define NOREF ((union ref) {0})
+#define UNDREF ((union ref) {{ 0, -1 }})
+#define ZEROREF ((union ref) {{ RICON, 0 }})
+#define mkref(t, x) ((union ref) {{ (t), (x) }})
+#define mktyperef(t) ((union ref) {{ RTYPE, (t).bits }})
+#define ref2type(r) ((union irtype) {.bits = (r).i})
+
enum op {
Oxxx,
#define _(o,...) O##o,
@@ -195,13 +203,6 @@ extern struct calltab {vec_of(struct call);} calltab;
extern struct phitab {vec_of(union ref *);} phitab;
extern struct dattab {vec_of(struct irdat);} dattab;
extern struct addr addrht[];
-#define insrescls(ins) (oiscmp((ins).op) ? KI4 : (ins).cls)
-#define NOREF ((union ref) {0})
-#define UNDREF ((union ref) {{ 0, -1 }})
-#define ZEROREF ((union ref) {{ RICON, 0 }})
-#define mkref(t, x) ((union ref) {{ (t), (x) }})
-#define mktyperef(t) ((union ref) {{ RTYPE, (t).bits }})
-#define ref2type(r) ((union irtype) {.bits = (r).i})
#define mkinstr(O, C, ...) ((struct instr) { .op = (O), .cls = (C), .reg=0, __VA_ARGS__ })
#define mkarginstr(ty, x) mkinstr(Oarg, 0, mktyperef(ty), (x))
void irinit(struct function *);
diff --git a/irdump.c b/irdump.c
index 5835c81..9eda415 100644
--- a/irdump.c
+++ b/irdump.c
@@ -73,7 +73,7 @@ dumpref(enum op o, union ref ref)
{
struct xcon *con;
switch (ref.t) {
- case RNONE:
+ case RXXX:
if (ref.bits == UNDREF.bits)
efmt("undef");
else
@@ -109,13 +109,13 @@ dumpref(enum op o, union ref ref)
case RTYPE:
prityp(ref2type(ref));
break;
- case RMORE:
+ case RADDR:
{
const struct addr *addr = &addrht[ref.i];
bool k = 0;
efmt("addr [");
- if ((k = addr->base.t)) dumpref(0, addr->base);
- if (addr->index.t) {
+ if ((k = addr->base.bits)) dumpref(0, addr->base);
+ if (addr->index.bits) {
if (k) efmt(" + ");
dumpref(0, addr->index);
if (addr->shift)
@@ -210,13 +210,13 @@ dumpblk(struct function *fn, struct block *blk)
dumpinst(&instrtab[blk->ins.p[i]]);
}
efmt(" %s ", jnames[blk->jmp.t]);
- if (blk->jmp.arg[0].t && !fn->nabiret && isagg(fn->retty)) {
+ if (blk->jmp.arg[0].bits && !fn->nabiret && isagg(fn->retty)) {
/* un-lowered struct return */
dumpref(0, mktyperef(mkirtype(fn->retty)));
efmt(" ");
}
for (i = 0; i < 2; ++i) {
- if (!blk->jmp.arg[i].t) break;
+ if (!blk->jmp.arg[i].bits) break;
if (i > 0) efmt(", ");
dumpref(0, blk->jmp.arg[i]);
}
diff --git a/optmem.c b/optmem.c
index b5eaae4..39719bb 100644
--- a/optmem.c
+++ b/optmem.c
@@ -114,10 +114,10 @@ static union ref
readvar(struct ssabuilder *sb, int var, enum irclass cls, struct block *blk)
{
union ref **pcurdefs;
- if ((pcurdefs = imap_get(&sb->curdefs, var)) && (*pcurdefs)[blk->id].t)
+ if ((pcurdefs = imap_get(&sb->curdefs, var)) && (*pcurdefs)[blk->id].bits)
return (*pcurdefs)[blk->id];
if (blk->npred == 0) /* entry block, var is read before being written to */
- return NOREF;
+ return UNDREF;
return readvarrec(sb, var, cls, blk);
}
@@ -172,7 +172,7 @@ mem2reg(struct function *fn)
*m = mkinstr(Onop,0,);
} else if (oisload(m->op)) {
union ref val = readvar(&sb, var, k, use->blk);
- if (!val.t) { /* var is used uninitialized */
+ if (!val.bits) { /* var is used uninitialized */
/* TODO emit diagnostic */
/* load some garbage */
*m = mkinstr(kisflt(k) ? Oloadf4 + (k==KF8) : Oloads1+ilog2(sz)*2,
diff --git a/regalloc.c b/regalloc.c
index 19df61c..7202e68 100644
--- a/regalloc.c
+++ b/regalloc.c
@@ -69,7 +69,7 @@ def(struct rega *ra, struct instr *ins, struct block *blk, int curi)
if ((ins->op == Ocopy || ins->inplace) && ins->l.t == RREG) {
int hint = ins->l.i;
- if (!ra->regs[hint].t) {
+ if (!ra->regs[hint].bits) {
take(ra, reg = hint, mkref(RTMP, var));
assert(ra->regs[reg].bits == mkref(RTMP, var).bits);
}
@@ -104,7 +104,7 @@ def(struct rega *ra, struct instr *ins, struct block *blk, int curi)
static void
take(struct rega *ra, int reg, union ref ref) {
DBG("-- take %s for %c%d\n", mctarg->rnames[reg], "R%"[ref.t==RTMP], ref.i);
- assert(!ra->regs[reg].t && "taken");
+ assert(!ra->regs[reg].bits && "taken");
if (ref.t == RTMP)
ra->allocs[ref.i] = areg(reg);
ra->regs[reg] = ref;
@@ -129,7 +129,7 @@ allocreg(struct rega *ra, enum irclass cls, union ref ref, uvlong excl)
} else assert(0);
for (reg = r0; reg < rend; ++reg) {
if (bstest(mctarg->rglob, reg)) continue;
- if (!(excl >> reg & 1) && !ra->regs[reg].t) {
+ if (!(excl >> reg & 1) && !ra->regs[reg].bits) {
take(ra, reg, ref);
return reg;
}
@@ -158,9 +158,9 @@ spill(struct rega *ra, int reg, struct block *blk, int curi) {
int var, s;
struct instr load;
- if (!ra->regs[reg].t) return;
+ if (!ra->regs[reg].bits) return;
var = ra->regs[reg].i;
- assert(ra->regs[reg].t == RTMP && *(ushort *)&ra->allocs[var] == *(ushort *)&areg(reg));
+ assert(ra->regs[reg].bits == RTMP && *(ushort *)&ra->allocs[var] == *(ushort *)&areg(reg));
s = allocstk(ra, var);
DBG("-- spill %%%d %s -> s%d\n", var, mctarg->rnames[reg], s);
instrtab[var].reg = 0;
@@ -179,11 +179,11 @@ forcetake(struct rega *ra, int reg, union ref ref, struct block *blk, int curi)
struct alloc *alloc;
if (ra->regs[reg].bits == ref.bits) return;
- if (!ra->regs[reg].t) {
+ if (!ra->regs[reg].bits) {
take(ra, reg, ref);
return;
}
- assert(ra->regs[reg].t == RTMP);
+ assert(ra->regs[reg].bits == RTMP);
var = ra->regs[reg].i;
alloc = &ra->allocs[var];
assert(alloc->a == reg);
@@ -217,10 +217,10 @@ use(struct rega *ra, struct block *blk, int curi, enum op op, int hint, union re
struct instr *ins;
uvlong excl = other.t == RREG ? 1ull<<other.i : 0;
- if (ref->t == RMORE) {
+ if (ref->t == RADDR) {
struct addr addr = addrht[ref->i];
- if (addr.base.t) use(ra, blk, curi, 0, hint, &addr.base, addr.index);
- if (addr.index.t) use(ra, blk, curi, 0, hint, &addr.index, NOREF);
+ if (addr.base.bits) use(ra, blk, curi, 0, hint, &addr.base, addr.index);
+ if (addr.index.bits) use(ra, blk, curi, 0, hint, &addr.index, NOREF);
*ref = mkaddr(addr);
return;
} else if (ref->t == RREG) {
@@ -238,10 +238,10 @@ use(struct rega *ra, struct block *blk, int curi, enum op op, int hint, union re
assert(ins->op != Ocall);
if (ins->r.t == RREG && ins->inplace) excl |= 1ull<<ins->r.i;
- if ((hint == -1 || ra->regs[hint].t) && ins->op == Ocopy && ins->l.t == RREG)
+ if ((hint == -1 || ra->regs[hint].bits) && ins->op == Ocopy && ins->l.t == RREG)
/* for '%x = copy Rx', hint %x to use Rx */
hint = ins->l.i;
- if (hint != -1 && !(excl >> hint & 1) && !ra->regs[hint].t) {
+ if (hint != -1 && !(excl >> hint & 1) && !ra->regs[hint].bits) {
take(ra, hint, *ref);
ins->reg = hint + 1;
} else {
@@ -294,7 +294,7 @@ regalloc(struct function *fn)
blk = last;
do {
for (int i = 0; i < 2; ++i) {
- if (!blk->jmp.arg[i].t) break;
+ if (!blk->jmp.arg[i].bits) break;
/* do not allocate a reg for a cmp op used a branch argument, since it's a pseudo op */
if (blk->jmp.t == Jb && blk->jmp.arg[i].t == RTMP && oiscmp(instrtab[blk->jmp.arg[i].i].op))
break;
@@ -324,8 +324,8 @@ regalloc(struct function *fn)
use(&ra, blk, i, ins->op, hint0, &ins->r, NOREF);
use(&ra, blk, i, ins->op, hint0, &ins->l, ins->r);
} else {
- if (ins->l.t) use(&ra, blk, i, ins->op, hint0, &ins->l, ins->r);
- if (ins->r.t) use(&ra, blk, i, ins->op, hint1, &ins->r, NOREF);
+ if (ins->l.bits) use(&ra, blk, i, ins->op, hint0, &ins->l, ins->r);
+ if (ins->r.bits) use(&ra, blk, i, ins->op, hint1, &ins->r, NOREF);
}
}
} else {
diff --git a/ssa.c b/ssa.c
index a2abf7b..4ce8774 100644
--- a/ssa.c
+++ b/ssa.c
@@ -19,8 +19,6 @@ filluses(struct function *fn)
}
for (int i = 0; i < blk->ins.n; ++i) {
int ins = blk->ins.p[i];
- assert(instrtab[ins].l.t != RMORE);
- if (instrtab[ins].op != Ocall) assert(instrtab[ins].l.t != RMORE);
adduse(blk, ins, instrtab[ins].l);
adduse(blk, ins, instrtab[ins].r);
}