summaryrefslogtreecommitdiff
path: root/sys/src/cmd/6c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-06-24 19:36:01 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-06-24 19:36:01 +0200
commit345714dd56f5da8dcb2193f9cdf041cfc005d82f (patch)
tree2e6e832c8f06d88edf309eb711bdf7c3559b7e01 /sys/src/cmd/6c
parent9f6967ed7e12ec3254bc1b3b7ad3e5a41c274e3a (diff)
8c, 6c: avoid allocating index registers when we don't have to
when a operation receives a chain of OINDEX nodes as its operands, each indexing step used to allocate a new index register. this is wastefull an can result in running out of fixed registers on 386 for code such as: x = a[a[a[a[i]]]]. instead we attempt to reuse the destination register of the operation as the index register if it is not otherwise referenced. this results in the index chain to use a single register for index and result and leaves registers free to be used for something usefull instead. for 6c, try to avoid R13 as well as BP index base register.
Diffstat (limited to 'sys/src/cmd/6c')
-rw-r--r--sys/src/cmd/6c/txt.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/sys/src/cmd/6c/txt.c b/sys/src/cmd/6c/txt.c
index 82045c168..1f4662b69 100644
--- a/sys/src/cmd/6c/txt.c
+++ b/sys/src/cmd/6c/txt.c
@@ -1117,8 +1117,18 @@ gmove(Node *f, Node *t)
gins(a, f, t);
}
+static int
+regused(Node *n, int r)
+{
+ if(n == nil)
+ return 0;
+ if(isreg(n, r))
+ return 1;
+ return regused(n->left, r) || regused(n->right, r);
+}
+
void
-doindex(Node *n)
+doindex(Node *n, Node *o)
{
Node nod, nod1;
long v;
@@ -1129,7 +1139,11 @@ prtree(n, "index");
if(n->left->complex >= FNX)
print("botch in doindex\n");
- regalloc(&nod, &qregnode, Z);
+ if(n->right->op == OREGISTER)
+ o = n->right;
+ else if(o == Z || o->op != OREGISTER || regused(n, o->reg))
+ o = Z;
+ regalloc(&nod, &qregnode, o);
v = constnode.vconst;
cgen(n->right, &nod);
idx.ptr = D_NONE;
@@ -1139,11 +1153,13 @@ print("botch in doindex\n");
idx.ptr = n->left->reg;
else if(n->left->op != OADDR) {
reg[D_BP]++; // cant be used as a base
+ reg[D_R13]++;
regalloc(&nod1, &qregnode, Z);
cgen(n->left, &nod1);
idx.ptr = nod1.reg;
regfree(&nod1);
reg[D_BP]--;
+ reg[D_R13]--;
}
idx.reg = nod.reg;
regfree(&nod);
@@ -1155,9 +1171,14 @@ gins(int a, Node *f, Node *t)
{
if(f != Z && f->op == OINDEX)
- doindex(f);
+ doindex(f, a == AMOVL || a == ALEAL
+ || a == AMOVQ || a == ALEAQ
+ || a == AMOVBLSX || a == AMOVBLZX
+ || a == AMOVBQSX || a == AMOVBQZX
+ || a == AMOVWLSX || a == AMOVWLZX
+ || a == AMOVWQSX || a == AMOVWQZX ? t : Z);
if(t != Z && t->op == OINDEX)
- doindex(t);
+ doindex(t, Z);
nextpc();
p->as = a;
if(f != Z)