commit 2c2db15995ce6c0f362d65e174d5a1b933057b80
parent e46b4e31e83f2f9d638ddffc5575795565f15e88
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Sat, 25 Feb 2017 14:48:15 -0500
do sign/zero extensions removal in copy.c
Diffstat:
M | Makefile | | | 2 | +- |
M | all.h | | | 11 | ++++++++++- |
M | copy.c | | | 48 | +++++++++++++++++++++++++++++++++++++++++++----- |
M | main.c | | | 1 | - |
D | simpl.c | | | 46 | ---------------------------------------------- |
M | ssa.c | | | 14 | ++++++++++++-- |
6 files changed, 66 insertions(+), 56 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
}