commit 32d9e33191a08e9162cebfac6e19cbd56eb1b3b6
parent 02b70c0cb1203a9a3cc9a0bda0f013188a2a4942
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Tue, 12 Apr 2016 18:29:10 -0400
harden memopt()
Diffstat:
| M | mem.c | | | 84 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------- |
1 file changed, 55 insertions(+), 29 deletions(-)
diff --git a/mem.c b/mem.c
@@ -1,12 +1,29 @@
#include "all.h"
-/* Memory optimization:
- *
- * - replace alloced slots used only in
- * load/store operations
- * Assumption: all the accesses have the
- * same size (this could be wrong...)
- */
+static int
+loadsz(Ins *l)
+{
+ switch (l->op) {
+ case OLoadsb: case OLoadub: return 1;
+ case OLoadsh: case OLoaduh: return 2;
+ case OLoadsw: case OLoaduw: return 4;
+ case OLoad: return KWIDE(l->cls) ? 8 : 4;
+ }
+ die("unreachable");
+}
+
+static int
+storesz(Ins *s)
+{
+ switch (s->op) {
+ case OStoreb: return 1;
+ case OStoreh: return 2;
+ case OStorew: case OStores: return 4;
+ case OStorel: case OStored: return 8;
+ }
+ die("unreachable");
+}
+
/* require use, maintains use counts */
void
@@ -16,8 +33,9 @@ memopt(Fn *fn)
Ins *i, *l;
Tmp *t;
Use *u, *ue;
- int a;
+ int s, k;
+ /* promote uniform stack slots to temporaries */
b = fn->start;
for (i=b->ins; i-b->ins < b->nins; i++) {
if (OAlloc > i->op || i->op > OAlloc1)
@@ -25,13 +43,26 @@ memopt(Fn *fn)
/* specific to NAlign == 3 */
assert(rtype(i->to) == RTmp);
t = &fn->tmp[i->to.val];
+ k = -1;
+ s = -1;
for (u=t->use; u != &t->use[t->nuse]; u++) {
if (u->type != UIns)
- goto NextIns;
+ goto Skip;
l = u->u.ins;
- if (!isload(l->op)
- && (!isstore(l->op) || req(i->to, l->arg[0])))
- goto NextIns;
+ if (isload(l->op))
+ if (s == -1 || s == loadsz(l)) {
+ s = loadsz(l);
+ continue;
+ }
+ if (isstore(l->op))
+ if (req(i->to, l->arg[1]) && !req(i->to, l->arg[0]))
+ if (s == -1 || s == storesz(l))
+ if (k == -1 || k == opdesc[l->op].argcls[0][0]) {
+ s = storesz(l);
+ k = opdesc[l->op].argcls[0][0];
+ continue;
+ }
+ goto Skip;
}
/* get rid of the alloc and replace uses */
*i = (Ins){.op = ONop};
@@ -40,39 +71,34 @@ memopt(Fn *fn)
for (u=t->use; u!=ue; u++) {
l = u->u.ins;
if (isstore(l->op)) {
- if (l->op == OStores)
- l->cls = Kd;
- else if (l->op == OStored)
- l->cls = Kd;
- else if (l->op == OStorel)
- l->cls = Kl;
- else
- l->cls = Kw;
+ l->cls = k;
l->op = OCopy;
l->to = l->arg[1];
l->arg[1] = R;
t->nuse--;
t->ndef++;
- } else
+ } else {
+ if (k == -1)
+ err("slot %%%s is read but never stored to",
+ fn->tmp[l->arg[0].val].name);
/* try to turn loads into copies so we
* can eliminate them later */
switch(l->op) {
case OLoad:
- l->op = OCopy;
- break;
case OLoadsw:
case OLoaduw:
- l->cls = Kw;
- l->op = OCopy;
+ if (KBASE(k) != KBASE(l->cls))
+ l->op = OCast;
+ else
+ l->op = OCopy;
break;
default:
- /* keep l->cls */
- a = l->op - OLoadsb;
- l->op = OExtsb + a;
+ l->op = OExtsb + (l->op - OLoadsb);
break;
}
+ }
}
- NextIns:;
+ Skip:;
}
if (debug['M']) {
fprintf(stderr, "\n> After memory optimization:\n");