summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorotto <otto@openbsd.org>2007-09-22 14:42:26 +0000
committerotto <otto@openbsd.org>2007-09-22 14:42:26 +0000
commitc2ebdcbf80b786aaec9f705a25c0d50e6b7a08a0 (patch)
tree3e7a6cec9d3f0675c12d044f08fe26e97875d406
parentPull form ragge's repo: (diff)
downloadwireguard-openbsd-c2ebdcbf80b786aaec9f705a25c0d50e6b7a08a0.tar.xz
wireguard-openbsd-c2ebdcbf80b786aaec9f705a25c0d50e6b7a08a0.zip
Pull form ragge's repo:
Fix a problem that occurred when: 1) wrong register were spilled (no effect of colorability) 2) short-life-range register were spilled (no effect of colorability)
-rw-r--r--usr.bin/pcc/mip/regs.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/usr.bin/pcc/mip/regs.c b/usr.bin/pcc/mip/regs.c
index 170d737f9cf..e31b1671cfb 100644
--- a/usr.bin/pcc/mip/regs.c
+++ b/usr.bin/pcc/mip/regs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: regs.c,v 1.5 2007/09/21 07:48:13 otto Exp $ */
+/* $OpenBSD: regs.c,v 1.6 2007/09/22 14:42:26 otto Exp $ */
/*
* Copyright (c) 2005 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -290,6 +290,7 @@ nsucomp(NODE *p)
w->r_class = TCLASS(p->n_su);
if (w->r_class == 0)
w->r_class = gclass(p->n_type);
+ w->r_nclass[0] = o == LTYPE; /* XXX store leaf info here */
SETNUM(w);
if (w->r_class)
DLIST_INSERT_BEFORE(&initial, w, link);
@@ -1679,6 +1680,16 @@ SelectSpill(void)
if (w == &spillWorklist) {
/* no heuristics, just fetch first element */
+ /* but not if leaf */
+ DLIST_FOREACH(w, &spillWorklist, link) {
+ if (w->r_nclass[0] == 0)
+ break;
+ }
+ }
+
+ if (w == &spillWorklist) {
+ /* Eh, only leaves :-/ Try anyway */
+ /* May not be useable */
w = DLIST_NEXT(&spillWorklist, link);
}
@@ -1848,6 +1859,7 @@ static void
shorttemp(NODE *p)
{
struct interpass *nip;
+ struct optab *q;
REGW *w;
NODE *l, *r;
int off;
@@ -1863,12 +1875,35 @@ shorttemp(NODE *p)
break;
}
RDEBUG(("rewriting node %d\n", ASGNUM(w)));
+
off = BITOOR(freetemp(szty(p->n_type)));
l = mklnode(OREG, off, FPREG, p->n_type);
r = talloc();
- *r = *p;
- nip = ipnode(mkbinode(ASSIGN, l, r, p->n_type));
- *p = *l;
+ /*
+ * If this is a binode which reclaim a leg, and it had
+ * to walk down the other leg first, then it must be
+ * split below this node instead.
+ */
+ q = &table[TBLIDX(p->n_su)];
+ if (optype(p->n_op) == BITYPE &&
+ (q->rewrite & RLEFT && (p->n_su & DORIGHT) == 0) &&
+ (TBLIDX(p->n_right->n_su) != 0)) {
+ *r = *l;
+ nip = ipnode(mkbinode(ASSIGN, l,
+ p->n_left, p->n_type));
+ p->n_left = r;
+ } else if (optype(p->n_op) == BITYPE &&
+ (q->rewrite & RRIGHT && (p->n_su & DORIGHT) != 0) &&
+ (TBLIDX(p->n_left->n_su) != 0)) {
+ *r = *l;
+ nip = ipnode(mkbinode(ASSIGN, l,
+ p->n_right, p->n_type));
+ p->n_right = r;
+ } else {
+ *r = *p;
+ nip = ipnode(mkbinode(ASSIGN, l, r, p->n_type));
+ *p = *l;
+ }
DLIST_INSERT_BEFORE(cip, nip, qelem);
DLIST_REMOVE(w, link);
break;