diff options
| author | 2023-06-22 21:54:08 +0200 | |
|---|---|---|
| committer | 2023-06-22 21:54:08 +0200 | |
| commit | d313c6e49bfb32ae24745e90eebe833da20efa1a (patch) | |
| tree | 73f950f515b4442a800ecc4e35c346b0cc263a89 | |
| parent | 836f91535f421be4cba2840aed55aba3c5f72f1b (diff) | |
change RMORE -> RADDR; use RXXX (RNONE) for special args,also undef
| -rw-r--r-- | abi0.c | 6 | ||||
| -rw-r--r-- | amd64/emit.c | 28 | ||||
| -rw-r--r-- | amd64/isel.c | 24 | ||||
| -rw-r--r-- | ir.c | 10 | ||||
| -rw-r--r-- | ir.h | 29 | ||||
| -rw-r--r-- | irdump.c | 12 | ||||
| -rw-r--r-- | optmem.c | 6 | ||||
| -rw-r--r-- | regalloc.c | 30 | ||||
| -rw-r--r-- | ssa.c | 2 |
9 files changed, 73 insertions, 74 deletions
@@ -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; @@ -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); @@ -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 *); @@ -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]); } @@ -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, @@ -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 { @@ -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); } |