cleanup error handling

This commit is contained in:
Quentin Carbonneaux 2016-03-30 12:04:43 -04:00
parent beec05cd3b
commit 729aa97b79
10 changed files with 86 additions and 92 deletions

5
all.h
View file

@ -6,6 +6,7 @@
#include <string.h>
#define MAKESURE(what, x) typedef char make_sure_##what[(x)?1:-1]
#define die(...) die_(__FILE__, __VA_ARGS__)
typedef unsigned int uint;
typedef unsigned short ushort;
@ -481,7 +482,7 @@ extern char debug['Z'+1];
/* util.c */
extern Typ typ[NTyp];
extern Ins insb[NIns], *curi;
void diag(char *) __attribute__((noreturn));
void die_(char *, char *, ...) __attribute__((noreturn));
void *emalloc(size_t);
void *alloc(size_t);
void freeall(void);
@ -522,7 +523,7 @@ extern OpDesc opdesc[NOp];
void parse(FILE *, char *, void (Dat *), void (Fn *));
void printfn(Fn *, FILE *);
void printref(Ref, Fn *, FILE *);
void err(char *, ...);
void err(char *, ...) __attribute__((noreturn));
/* mem.c */
void memopt(Fn *);

34
copy.c
View file

@ -47,7 +47,6 @@ visitphi(Phi *p, Ref *cp, RList **w)
break;
}
}
assert(!req(r, R));
update(p->to, r, cp, w);
}
@ -65,6 +64,15 @@ visitins(Ins *i, Ref *cp, RList **w)
}
}
static void
subst(Ref *r, Ref *cp, Fn *fn)
{
if (rtype(*r) == RTmp && req(copyof(*r, cp), R))
err("temporary %%%s is used undefined",
fn->tmp[r->val].name);
*r = copyof(*r, cp);
}
void
copy(Fn *fn)
{
@ -93,8 +101,6 @@ copy(Fn *fn)
u1 = u + fn->tmp[t].nuse;
for (; u<u1; u++)
switch (u->type) {
default:
diag("copy: invalid use");
case UPhi:
visitphi(u->u.phi, cp, &w);
break;
@ -103,6 +109,8 @@ copy(Fn *fn)
break;
case UJmp:
break;
default:
die("invalid use %d", u->type);
}
}
for (b=fn->start; b; b=b->link) {
@ -113,31 +121,19 @@ copy(Fn *fn)
continue;
}
for (a=0; a<p->narg; a++)
if (rtype(p->arg[a]) == RTmp) {
r = cp[p->arg[a].val];
assert(!req(r, R));
p->arg[a] = r;
}
subst(&p->arg[a], cp, fn);
pp=&p->link;
}
for (i=b->ins; i-b->ins < b->nins; i++) {
r = cp[i->to.val];
r = copyof(i->to, cp);
if (!req(r, i->to)) {
*i = (Ins){.op = ONop};
continue;
}
for (a=0; a<2; a++)
if (rtype(i->arg[a]) == RTmp) {
r = cp[i->arg[a].val];
assert(!req(r, R));
i->arg[a] = r;
}
}
if (rtype(b->jmp.arg) == RTmp) {
r = cp[b->jmp.arg.val];
assert(!req(r, R));
b->jmp.arg = r;
subst(&i->arg[a], cp, fn);
}
subst(&b->jmp.arg, cp, fn);
}
if (debug['C']) {
fprintf(stderr, "\n> Copy information:");

40
emit.c
View file

@ -133,7 +133,7 @@ slot(int s, Fn *fn)
/* sign extend s using a bitfield */
x.i = s;
assert(NAlign == 3);
/* specific to NAlign == 3 */
if (x.i < 0)
return -4 * x.i;
else {
@ -146,8 +146,6 @@ static void
emitcon(Con *con, FILE *f)
{
switch (con->type) {
default:
diag("emit: invalid constant");
case CAddr:
if (con->local)
fprintf(f, "%s%s", locprefix, con->label);
@ -159,6 +157,8 @@ emitcon(Con *con, FILE *f)
case CBits:
fprintf(f, "%"PRId64, con->bits.i);
break;
default:
die("unreachable");
}
}
@ -178,14 +178,14 @@ static Ref
getarg(char c, Ins *i)
{
switch (c) {
default:
diag("emit: 0, 1, = expected in format");
case '0':
return i->arg[0];
case '1':
return i->arg[1];
case '=':
return i->to;
default:
die("invalid arg letter %c", c);
}
}
@ -222,8 +222,8 @@ emitf(char *s, Ins *i, Fn *fn, FILE *f)
}
/* fall through */
case '-':
if (req(i->arg[1], i->to) && !req(i->arg[0], i->to))
diag("emit: cannot convert to 2-address");
assert((!req(i->arg[1], i->to) || req(i->arg[0], i->to)) &&
"cannot convert to 2-address");
emitcopy(i->to, i->arg[0], i->cls, fn, f);
s++;
break;
@ -238,8 +238,6 @@ Next:
} else
fputc(c, f);
switch ((c = *s++)) {
default:
diag("emit: invalid escape");
case '%':
fputc('%', f);
break;
@ -258,8 +256,6 @@ Next:
c = *s++;
ref = getarg(c, i);
switch (rtype(ref)) {
default:
diag("emit: invalid reference");
case RTmp:
assert(isreg(ref));
fprintf(f, "%%%s", regtoa(ref.val, sz));
@ -294,6 +290,8 @@ Next:
fputc('$', f);
emitcon(&fn->con[ref.val], f);
break;
default:
die("unreachable");
}
break;
case 'L':
@ -312,8 +310,6 @@ Next:
c = *s++;
ref = getarg(c, i);
switch (rtype(ref)) {
default:
diag("emit: invalid memory reference");
case RAMem:
goto Mem;
case RSlot:
@ -327,8 +323,12 @@ Next:
assert(isreg(ref));
fprintf(f, "(%%%s)", regtoa(ref.val, SLong));
break;
default:
die("unreachable");
}
break;
default:
die("invalid format specifier %%%c", c);
}
goto Next;
}
@ -350,7 +350,7 @@ emitins(Ins i, Fn *fn, FILE *f)
/* this linear search should really be a binary
* search */
if (omap[o].op == NOp)
diag("emit: no entry found for instruction");
die("not match for %d(%d)", i.op, i.cls);
if (omap[o].op == i.op)
if (omap[o].cls == i.cls
|| (omap[o].cls == Ki && KBASE(i.cls) == 0)
@ -412,8 +412,6 @@ emitins(Ins i, Fn *fn, FILE *f)
/* calls simply have a weird syntax in AT&T
* assembly... */
switch (rtype(i.arg[0])) {
default:
diag("emit: invalid call instruction");
case RCon:
fprintf(f, "\tcallq ");
emitcon(&fn->con[i.arg[0].val], f);
@ -422,6 +420,8 @@ emitins(Ins i, Fn *fn, FILE *f)
case RTmp:
emitf("callq *%L0", &i, fn, f);
break;
default:
die("invalid call argument");
}
break;
case OSAlloc:
@ -450,7 +450,7 @@ static int
cneg(int cmp)
{
switch (cmp) {
default: diag("emit: cneg() unhandled comparison");
default: die("invalid int comparison %d", cmp);
case ICule: return ICugt;
case ICult: return ICuge;
case ICsle: return ICsgt;
@ -471,7 +471,7 @@ framesz(Fn *fn)
{
int i, o, f;
assert(NAlign == 3);
/* specific to NAlign == 3 */
for (i=0, o=0; i<NRClob; i++)
o ^= 1 & (fn->reg >> rclob[i]);
f = fn->slot;
@ -549,12 +549,12 @@ emitfn(Fn *fn, FILE *f)
c = cneg(c);
s = b->s2;
} else
diag("emit: unhandled jump (1)");
die("unhandled jump");
fprintf(f, "\tj%s %sbb%d /* %s */\n",
ctoa[c], locprefix, id0+s->id, s->name);
break;
}
diag("emit: unhandled jump (2)");
die("unhandled jump %d", b->jmp.type);
}
}
id0 += fn->nblk;

48
isel.c
View file

@ -35,7 +35,7 @@ static int
fcmptoi(int fc)
{
switch (fc) {
default: diag("isel: fcmptoi defaulted");
default: die("invalid fp comparison %d", fc);
case FCle: return ICule;
case FClt: return ICult;
case FCgt: return ICugt;
@ -85,8 +85,6 @@ noimm(Ref r, Fn *fn)
if (rtype(r) != RCon)
return 0;
switch (fn->con[r.val].type) {
default:
diag("isel: invalid constant");
case CAddr:
/* we only support the 'small'
* code model of the ABI, this
@ -97,6 +95,8 @@ noimm(Ref r, Fn *fn)
case CBits:
val = fn->con[r.val].bits.i;
return (val < INT32_MIN || val > INT32_MAX);
default:
die("invalid constant");
}
}
@ -208,7 +208,7 @@ sel(Ins i, ANum *an, Fn *fn)
{
Ref r0, r1;
int x, k, kc;
int64_t val;
int64_t sz;
Ins *i0;
if (rtype(i.to) == RTmp)
@ -308,12 +308,11 @@ Emit:
* (rsp = 0) mod 16
*/
if (rtype(i.arg[0]) == RCon) {
assert(fn->con[i.arg[0].val].type == CBits);
val = fn->con[i.arg[0].val].bits.i;
val = (val + 15) & ~INT64_C(15);
if (val < 0 || val > INT32_MAX)
diag("isel: alloc too large");
emit(OSAlloc, Kl, i.to, getcon(val, fn), R);
sz = fn->con[i.arg[0].val].bits.i;
if (sz < 0 || sz >= INT_MAX-15)
err("invalid alloc size %"PRId64, sz);
sz = (sz + 15) & -16;
emit(OSAlloc, Kl, i.to, getcon(sz, fn), R);
} else {
/* r0 = (i.arg[0] + 15) & -16 */
r0 = newtmp("isel", Kl, fn);
@ -335,13 +334,13 @@ Emit:
selcmp(i.arg, kc, fn);
break;
}
diag("isel: non-exhaustive implementation");
die("unknown instruction");
}
while (i0 > curi && --i0)
if (rslot(i0->arg[0], fn) != -1
|| rslot(i0->arg[1], fn) != -1)
diag("isel: usupported address argument");
while (i0 > curi && --i0) {
assert(rslot(i0->arg[0], fn) == -1);
assert(rslot(i0->arg[1], fn) == -1);
}
}
static Ins *
@ -733,7 +732,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
}
/* allocate return pad */
ra = alloc(sizeof *ra);
assert(NAlign == 3);
/* specific to NAlign == 3 */
aret.align -= 2;
if (aret.align < 0)
aret.align = 0;
@ -822,7 +821,7 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
} else
classify(i0, i1, ac, OPar, 0);
assert(NAlign == 3);
/* specific to NAlign == 3 */
s = 4;
for (i=i0, a=ac; i<i1; i++, a++) {
@ -856,7 +855,6 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
for (i=i0, a=ac; i<i1; i++, a++) {
if (i->op != OParc || a->inmem)
continue;
assert(NAlign == 3);
for (al=0; a->align >> (al+2); al++)
;
r = TMP(a->cls[0]);
@ -876,12 +874,12 @@ static int
aref(Ref r, ANum *ai)
{
switch (rtype(r)) {
default:
diag("isel: aref defaulted");
case RCon:
return 2;
case RTmp:
return ai[r.val].n;
default:
die("constant or temporary expected");
}
}
@ -986,8 +984,6 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
}
}
switch (ai[r.val].n) {
default:
diag("isel: amatch defaulted");
case 3: /* s * i */
if (!top) {
a->index = al;
@ -1023,6 +1019,8 @@ amatch(Addr *a, Ref r, ANum *ai, Fn *fn, int top)
amatch(a, ar, ai, fn, 0);
amatch(a, al, ai, fn, 0);
break;
default:
die("unreachable");
}
}
@ -1092,15 +1090,15 @@ isel(Fn *fn)
/* assign slots to fast allocs */
b = fn->start;
assert(NAlign == 3 && "change n=4 and sz /= 4 below");
/* specific to NAlign == 3 */ /* or change n=4 and sz /= 4 below */
for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
for (i=b->ins; i-b->ins < b->nins; i++)
if (i->op == al) {
if (rtype(i->arg[0]) != RCon)
break;
sz = fn->con[i->arg[0].val].bits.i;
if (sz < 0 || sz >= INT_MAX-3)
diag("isel: invalid alloc size");
if (sz < 0 || sz >= INT_MAX-15)
err("invalid alloc size %"PRId64, sz);
sz = (sz + n-1) & -n;
sz /= 4;
fn->tmp[i->to.val].slot = fn->slot;

2
mem.c
View file

@ -22,7 +22,7 @@ memopt(Fn *fn)
for (i=b->ins; i-b->ins < b->nins; i++) {
if (OAlloc > i->op || i->op > OAlloc1)
continue;
assert(NAlign == 3);
/* specific to NAlign == 3 */
assert(rtype(i->to) == RTmp);
t = &fn->tmp[i->to.val];
for (u=t->use; u != &t->use[t->nuse]; u++) {

12
parse.c
View file

@ -159,18 +159,14 @@ static int ntyp;
void
err(char *s, ...)
{
char buf[100], *p, *end;
va_list ap;
p = buf;
end = buf + sizeof(buf);
va_start(ap, s);
p += snprintf(p, end - p, "%s:%d: ", inpath, lnum);
p += vsnprintf(p, end - p, s, ap);
fprintf(stderr, "%s:%d: ", inpath, lnum);
vfprintf(stderr, s, ap);
fprintf(stderr, "\n");
va_end(ap);
diag(buf);
exit(1);
}
static int

4
rega.c
View file

@ -125,7 +125,7 @@ ralloc(RMap *m, int t)
for (r=r0; r<r1; r++)
if (!bshas(m->b, r))
goto Found;
diag("rega: no more regs");
die("no more regs");
}
Found:
radd(m, t, r);
@ -170,7 +170,7 @@ pmadd(Ref src, Ref dst, int k)
cpm = cpm * 2 + 16;
pm = realloc(pm, cpm * sizeof pm[0]);
if (!pm)
diag("pmadd: out of memory");
die("pmadd, out of memory");
}
pm[npm].src = src;
pm[npm].dst = dst;

10
spill.c
View file

@ -94,8 +94,7 @@ fillcost(Fn *fn)
tmpuse(p->to, 0, 0, fn);
for (a=0; a<p->narg; a++) {
n = p->blk[a]->loop;
assert(b->npred==p->narg &&
"wrong cfg");
assert(b->npred==p->narg && "wrong cfg");
n /= b->npred;
tmpuse(p->arg[a], 1, n, fn);
}
@ -146,11 +145,10 @@ slot(int t)
{
int s;
if (t < Tmp0)
diag("spill: cannot spill register");
assert(t >= Tmp0 && "cannot spill register");
s = tmp[t].slot;
if (s == -1) {
assert(NAlign == 3);
/* specific to NAlign == 3 */
/* nice logic to pack stack slots
* on demand, there can be only
* one hole and slot4 points to it
@ -491,7 +489,7 @@ spill(Fn *fn)
}
/* align the locals to a 16 byte boundary */
assert(NAlign == 3);
/* specific to NAlign == 3 */
slot8 += slot8 & 3;
fn->slot += slot8;

6
ssa.c
View file

@ -15,8 +15,6 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
u->type = ty;
u->bid = b->id;
switch (ty) {
default:
diag("ssa: adduse defaulted");
case UPhi:
u->u.phi = va_arg(ap, Phi *);
break;
@ -25,6 +23,8 @@ adduse(Tmp *tmp, int ty, Blk *b, ...)
break;
case UJmp:
break;
default:
die("unreachable");
}
va_end(ap);
}
@ -465,7 +465,7 @@ renblk(Blk *b, Name **stk, Fn *fn)
if ((t=fn->tmp[t].visit)) {
m = p->narg++;
if (m == NPred)
diag("ssa: too many phi arguments");
die("renblk, too many phi args");
p->arg[m] = getstk(t, b, stk);
p->blk[m] = b;
}

17
util.c
View file

@ -1,4 +1,5 @@
#include "all.h"
#include <stdarg.h>
typedef struct Bitset Bitset;
typedef struct Vec Vec;
@ -28,9 +29,14 @@ static void **pool = ptr;
static int nptr = 1;
void
diag(char *s)
die_(char *file, char *s, ...)
{
fputs(s, stderr);
va_list ap;
fprintf(stderr, "%s: dying: ", file);
va_start(ap, s);
vfprintf(stderr, s, ap);
va_end(ap);
fputc('\n', stderr);
abort();
}
@ -42,7 +48,7 @@ emalloc(size_t n)
p = calloc(1, n);
if (!p)
diag("emalloc: out of memory");
die("emalloc, out of memory");
return p;
}
@ -95,7 +101,7 @@ void
emit(int op, int k, Ref to, Ref arg0, Ref arg1)
{
if (curi == insb)
diag("emit: too many instructions");
die("emit, too many instructions");
*--curi = (Ins){
.op = op, .cls = k,
.to = to, .arg = {arg0, arg1}
@ -210,8 +216,7 @@ addcon(Con *c0, Con *c1)
*c0 = *c1;
else {
if (c1->type == CAddr) {
if (c0->type == CAddr)
diag("addcon: adding two addresses");
assert(c0->type != CAddr && "adding two addresses");
c0->type = CAddr;
strcpy(c0->label, c1->label);
}