aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--abi0.c8
-rw-r--r--ir.c4
-rw-r--r--ir.h5
-rw-r--r--irdump.c10
-rw-r--r--parse.c21
-rw-r--r--regalloc.c14
6 files changed, 33 insertions, 29 deletions
diff --git a/abi0.c b/abi0.c
index 3236e63..c3673e4 100644
--- a/abi0.c
+++ b/abi0.c
@@ -194,13 +194,13 @@ abi0(struct function *fn)
union ref arg = blk->jmp.arg[0];
if (blk->jmp.t != Jret) continue;
if (!arg.t) continue;
- if (arg.t != RTMP || !oisalloca(instrtab[arg.idx].op)) {
+ if (arg.t != RTMP || !oisalloca(instrtab[arg.i].op)) {
rvovar = -1;
break;
}
if (rvovar == -1) {
- rvovar = arg.idx;
- } else if (arg.idx != rvovar) {
+ rvovar = arg.i;
+ } else if (arg.i != rvovar) {
rvovar = -1;
break;
}
@@ -214,7 +214,7 @@ abi0(struct function *fn)
/* adjust calls */
for (int iinstr = 0; iinstr < blk->ins.n; ++iinstr) {
struct instr *ins = &instrtab[blk->ins.p[iinstr]];
- struct call *call = &calltab.p[ins->r.idx];
+ struct call *call = &calltab.p[ins->r.i];
static union ref newargsbuf[32];
static union irtype newtypsbuf[32];
vec_of(union ref) newargs = VINIT(newargsbuf, arraylength(newargsbuf));
diff --git a/ir.c b/ir.c
index 2f1c622..96877e2 100644
--- a/ir.c
+++ b/ir.c
@@ -349,7 +349,7 @@ replref(struct function *fn, struct block *blk, int i0, union ref from, union re
{
do {
if (!i0) for (int i = 0; i < blk->phi.n; ++i) {
- struct phi *phi = &phitab.p[instrtab[blk->phi.p[i]].l.idx];
+ struct phi *phi = &phitab.p[instrtab[blk->phi.p[i]].l.i];
for (int i = 0; i < phi->n; ++i)
if (phi->ref[i].bits == to.bits) phi->ref[i] = from;
}
@@ -360,7 +360,7 @@ replref(struct function *fn, struct block *blk, int i0, union ref from, union re
union ref *r = &(&ins->l)[i];
if (r->bits == from.bits) *r = to;
else if (r->t == RMORE) {
- struct call *call = &calltab.p[r->idx];
+ struct call *call = &calltab.p[r->i];
assert(ins->op == Ocall || ins->op == Ointrin);
for (int i = 0; i < call->narg; ++i)
if (call->args[i].bits == from.bits)
diff --git a/ir.h b/ir.h
index 4cce899..c871fa7 100644
--- a/ir.h
+++ b/ir.h
@@ -75,8 +75,7 @@ enum refkind {
};
union ref {
- struct { uint t : 3, idx : 29; };
- struct { signed _0: 3, i : 29; }; /* RICON */
+ struct { unsigned t : 3; signed i : 29; };
uint bits;
};
@@ -166,8 +165,8 @@ extern struct calltab {vec_of(struct call);} calltab;
extern struct phitab {vec_of(struct phi);} phitab;
extern struct dattab {vec_of(struct irdat);} dattab;
#define NOREF ((union ref) {0})
+#define ZEROREF ((union ref) {{ RICON, 0 }})
#define mkref(t, x) ((union ref) {{ (t), (x) }})
-#define mkzerocon() ((union ref) {{ RICON, 0 }})
#define mkinstr(O, C, ...) ((struct instr) { .op = (O), .cls = (C), .reg=0, __VA_ARGS__ })
void irinit(struct function *);
void irfini(struct function *);
diff --git a/irdump.c b/irdump.c
index 1e5302e..d437fc4 100644
--- a/irdump.c
+++ b/irdump.c
@@ -76,14 +76,14 @@ dumpref(enum op o, union ref ref)
{
struct xcon *con;
switch (ref.t) {
- case RTMP: efmt("%%%d", ref.idx); break;
- case RPARAM: efmt("%%param%d", ref.idx); break;
+ case RTMP: efmt("%%%d", ref.i); break;
+ case RPARAM: efmt("%%param%d", ref.i); break;
case RICON:
if (o == Ointrin) efmt("\"%s\"", intrinname[ref.i]);
else efmt("%d", ref.i);
break;
case RXCON:
- con = &conht[ref.idx];
+ con = &conht[ref.i];
if (con->issym) efmt("$%s", con->sym);
else switch (con->cls) {
case KI4: efmt("%d", con->i4); break;
@@ -99,7 +99,7 @@ dumpref(enum op o, union ref ref)
break;
case RMORE:
if (o == Ocall || o == Ointrin) {
- struct call *call = &calltab.p[ref.idx];
+ struct call *call = &calltab.p[ref.i];
if (call->sret) {
efmt("sret ");
prityp(call->typs[call->narg]);
@@ -117,7 +117,7 @@ dumpref(enum op o, union ref ref)
dumpref(0, call->args[i]);
}
} else if (o == Ophi) {
- struct phi *phi = &phitab.p[ref.idx];
+ struct phi *phi = &phitab.p[ref.i];
for (int i = 0; i < phi->n; ++i) {
if (i > 0) efmt(", ");
efmt("[@%d ", phi->blk[i]->id);
diff --git a/parse.c b/parse.c
index 0dd984d..4fb44ec 100644
--- a/parse.c
+++ b/parse.c
@@ -1118,9 +1118,9 @@ cvt(struct function *fn, enum typetag to, enum typetag from, union ref ref)
if (from == TYBOOL) return ref;
if (ref.t == RTMP)
/* these instrs already have output range of [0,1] */
- if (instrtab[ref.idx].op == Onot || oiscmp(instrtab[ref.idx].op))
+ if (instrtab[ref.i].op == Onot || oiscmp(instrtab[ref.i].op))
return ref;
- ins.op = Oneq, ins.r = mkzerocon();
+ ins.op = Oneq, ins.r = ZEROREF;
}
else if (kfrom == KI4 && issignedt(from)) ins.op = Oexts4;
else if (kfrom == KI4) ins.op = Oextu4;
@@ -1761,7 +1761,7 @@ block(struct parser *pr, struct function *fn)
goto Err;
}
EMITS {
- decl.id = addinstr(fn, mkalloca(typesize(decl.ty), typealign(decl.ty))).idx;
+ decl.id = addinstr(fn, mkalloca(typesize(decl.ty), typealign(decl.ty))).i;
}
if (st.varini) {
putdecl(pr, &decl);
@@ -1811,10 +1811,10 @@ function(struct parser *pr, struct function *fn, const char **pnames, const stru
.name = pnames[i], .scls = SCAUTO, .span = pspans[i] };
EMITS {
if (isscalar(arg.ty)) {
- arg.id = addinstr(fn, mkalloca(typesize(arg.ty), typealign(arg.ty))).idx;
+ arg.id = addinstr(fn, mkalloca(typesize(arg.ty), typealign(arg.ty))).i;
genstore(fn, arg.ty, mkref(RTMP, arg.id), mkref(RPARAM, i));
} else {
- arg.id = addinstr(fn, mkinstr(Ocopy, KPTR, mkref(RPARAM, i))).idx;
+ arg.id = addinstr(fn, mkinstr(Ocopy, KPTR, mkref(RPARAM, i))).i;
}
}
putdecl(pr, &arg);
@@ -1831,10 +1831,15 @@ function(struct parser *pr, struct function *fn, const char **pnames, const stru
block(pr, fn);
envup(pr);
if (fn->curblk) {
- if (fn->retty.t != TYVOID && !nerror) {
- warn(&pr->fnblkspan, "non-void function may not return a value");
+ if (!strcmp(fn->name, "main") && fn->retty.t == TYINT) {
+ /* implicit return 0 for main function */
+ putreturn(fn, ZEROREF, NOREF);
+ } else {
+ if (fn->retty.t != TYVOID && !nerror) {
+ warn(&pr->fnblkspan, "non-void function may not return a value");
+ }
+ putreturn(fn, NOREF, NOREF);
}
- putreturn(fn, NOREF, NOREF);
}
}
diff --git a/regalloc.c b/regalloc.c
index 5810079..d7fadf6 100644
--- a/regalloc.c
+++ b/regalloc.c
@@ -37,33 +37,33 @@ use(struct block *blk, enum op op, int hint, union ref *ref)
struct instr *ins;
if (ref->t == RMORE) {
if (op == Ocall || op == Ointrin) {
- struct call *call = &calltab.p[ref->idx];
+ struct call *call = &calltab.p[ref->i];
for (int i = 0; i < call->narg; ++i)
use(blk, 0, op == Ocall ? call->abiargregs[i] : -1, &call->args[i]);
} else if (op == Ophi) {
- struct phi *phi = &phitab.p[ref->idx];
+ struct phi *phi = &phitab.p[ref->i];
for (int i = 0; i < phi->n; ++i)
use(blk, 0, hint, &phi->ref[i]);
} else assert("ext?");
return;
} else if (ref->t != RTMP) return;
- ins = &instrtab[ref->idx];
+ ins = &instrtab[ref->i];
if (oisalloca(ins->op)) return;
if (!ins->cls) return;
if (!ins->reg) {
if (op == -1) /* cond branch */
- if (oiscmp(ins->op) && ref->idx == blk->ins.p[blk->ins.n-1])
+ if (oiscmp(ins->op) && ref->i == blk->ins.p[blk->ins.n-1])
/* result of comparison instr is only used to conditionally branch,
* doesn't usually need a reg (handled by isel) */
return;
/* TODO implement actual constraints and stuff */
if (ins->op == Ocall) {
- struct call *call = &calltab.p[ins->r.idx];
+ struct call *call = &calltab.p[ins->r.i];
hint = call->abiret[0].reg;
} else if (ins->op == Ocall2r) {
- struct instr *ins2 = &instrtab[ins->l.idx];
- struct call *call = &calltab.p[ins2->r.idx];
+ struct instr *ins2 = &instrtab[ins->l.i];
+ struct call *call = &calltab.p[ins2->r.i];
assert(ins->l.t == RTMP && ins2->op == Ocall);
hint = call->abiret[0].reg;
}