diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | all.h | 11 | ||||
-rw-r--r-- | copy.c | 48 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | simpl.c | 46 | ||||
-rw-r--r-- | ssa.c | 14 |
6 files changed, 66 insertions, 56 deletions
diff --git a/Makefile b/Makefile index 4040923..fc649f8 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ABI = sysv V = @ OBJDIR = obj -SRC = main.c util.c parse.c cfg.c mem.c ssa.c alias.c load.c simpl.c copy.c fold.c live.c $(ABI).c isel.c spill.c rega.c emit.c +SRC = main.c util.c parse.c cfg.c mem.c ssa.c alias.c load.c copy.c fold.c live.c $(ABI).c isel.c spill.c rega.c emit.c OBJ = $(SRC:%.c=$(OBJDIR)/%.o) CFLAGS += -Wall -Wextra -std=c99 -g -pedantic diff --git a/all.h b/all.h index f518a36..e70bffb 100644 --- a/all.h +++ b/all.h @@ -228,7 +228,7 @@ enum Op { Ostores, Ostored, #define isstore(o) (Ostoreb <= o && o <= Ostored) - Oloadsb, /* needs to match OExt (mem.c) */ + Oloadsb, /* must match Oext and Tmp.width */ Oloadub, Oloadsh, Oloaduh, @@ -407,6 +407,15 @@ struct Tmp { } hint; int phi; Alias alias; + enum { + WFull, + Wsb, /* must match Oload/Oext order */ + Wub, + Wsh, + Wuh, + Wsw, + Wuw + } width; int visit; }; diff --git a/copy.c b/copy.c index bcb7b4d..7442306 100644 --- a/copy.c +++ b/copy.c @@ -51,13 +51,51 @@ visitphi(Phi *p, Ref *cp, RList ***pw) update(p->to, r, cp, pw); } +static int +iscopy(Ins *i, Ref r, Fn *fn) +{ + static bits extcpy[] = { + [WFull] = 0, + [Wsb] = BIT(Wsb) | BIT(Wsh) | BIT(Wsw), + [Wub] = BIT(Wub) | BIT(Wuh) | BIT(Wuw), + [Wsh] = BIT(Wsh) | BIT(Wsw), + [Wuh] = BIT(Wuh) | BIT(Wuw), + [Wsw] = BIT(Wsw), + [Wuw] = BIT(Wuw), + }; + int k, w; + Tmp *t; + + if (i->op == Ocopy) + return 1; + if (!isext(i->op)) + return 0; + if (i->op == Oextsw || i->op == Oextuw) + if (i->cls == Kw) + return 1; + if (rtype(r) == RTmp) { + t = &fn->tmp[r.val]; + w = t->width; + k = t->cls; + assert(k == Kw || k == Kl); + } else { + assert(rtype(r) == RCon); + w = WFull; + k = Kl; + } + if (i->cls == Kl && k == Kw) + /* not enough bits in r */ + return 0; + return (BIT(Wsb + (i->op - Oextsb)) & extcpy[w]) != 0; +} + static void -visitins(Ins *i, Ref *cp, RList ***pw) +visitins(Ins *i, Ref *cp, RList ***pw, Fn *fn) { Ref r; - if (i->op == Ocopy) { - r = copyof(i->arg[0], cp); + r = copyof(i->arg[0], cp); + if (iscopy(i, r, fn)) { update(i->to, r, cp, pw); } else if (!req(i->to, R)) { assert(rtype(i->to) == RTmp); @@ -91,7 +129,7 @@ copy(Fn *fn) for (p=b->phi; p; p=p->link) visitphi(p, cp, &pw); for (i=b->ins; i-b->ins < b->nins; i++) - visitins(i, cp, &pw); + visitins(i, cp, &pw, fn); } while ((w1=w)) { t = w->t; @@ -103,7 +141,7 @@ copy(Fn *fn) visitphi(u->u.phi, cp, &pw); break; case UIns: - visitins(u->u.ins, cp, &pw); + visitins(u->u.ins, cp, &pw, fn); break; case UJmp: break; diff --git a/main.c b/main.c index 1a8973f..fe68ae0 100644 --- a/main.c +++ b/main.c @@ -59,7 +59,6 @@ func(Fn *fn) loadopt(fn); filluse(fn); ssacheck(fn); - simpl(fn); copy(fn); filluse(fn); fold(fn); diff --git a/simpl.c b/simpl.c deleted file mode 100644 index 384a8da..0000000 --- a/simpl.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "all.h" - -static void -elimext(Ins *i, int ext, Fn *fn) -{ - Tmp *t; - Use *u; - - assert(rtype(i->to) == RTmp); - t = &fn->tmp[i->to.val]; - for (u=t->use; u<&t->use[t->nuse]; u++) - if (u->type == UIns - && u->u.ins->op == ext - && (u->u.ins->cls == i->cls || i->cls == Kl)) { - u->u.ins->op = Ocopy; - elimext(u->u.ins, ext, fn); - } -} - -/* requires & preserves uses */ -void -simpl(Fn *fn) -{ - Blk *b; - Ins *i; - int ext; - - for (b=fn->start; b; b=b->link) - for (i=b->ins; i<&b->ins[b->nins]; i++) - switch (i->op) { - case Oloadsb: - case Oloadub: - case Oloadsh: - case Oloaduh: - ext = Oextsb + (i->op - Oloadsb); - goto Elimext; - case Oextsb: - case Oextub: - case Oextsh: - case Oextuh: - ext = i->op; - Elimext: - elimext(i, ext, fn); - break; - } -} diff --git a/ssa.c b/ssa.c index 8a28eeb..632ebbe 100644 --- a/ssa.c +++ b/ssa.c @@ -31,7 +31,7 @@ adduse(Tmp *tmp, int ty, Blk *b, ...) va_end(ap); } -/* fill usage, phi, and class information +/* fill usage, width, phi, and class information * must not change .visit fields */ void @@ -40,7 +40,7 @@ filluse(Fn *fn) Blk *b; Phi *p; Ins *i; - int m, t; + int m, t, w; uint a; Tmp *tmp; @@ -51,6 +51,7 @@ filluse(Fn *fn) tmp[t].nuse = 0; tmp[t].phi = 0; tmp[t].cls = 0; + tmp[t].width = WFull; if (tmp[t].use == 0) tmp[t].use = vnew(0, sizeof(Use), Pfn); } @@ -72,7 +73,16 @@ filluse(Fn *fn) for (i=b->ins; i-b->ins < b->nins; i++) { if (!req(i->to, R)) { assert(rtype(i->to) == RTmp); + w = WFull; + if (isload(i->op) && i->op != Oload) + w = Wsb + (i->op - Oloadsb); + if (isext(i->op)) + w = Wsb + (i->op - Oextsb); + if (w == Wsw || w == Wuw) + if (i->cls == Kw) + w = WFull; t = i->to.val; + tmp[t].width = w; tmp[t].ndef++; tmp[t].cls = i->cls; } |