ref: 345714dd56f5da8dcb2193f9cdf041cfc005d82f
parent: 9f6967ed7e12ec3254bc1b3b7ad3e5a41c274e3a
author: cinap_lenrek <[email protected]>
date: Mon Jun 24 15:36:01 EDT 2019
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.
--- a/sys/src/cmd/6c/txt.c
+++ b/sys/src/cmd/6c/txt.c
@@ -1117,8 +1117,18 @@
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 @@
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 @@
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 @@
{
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)
--- a/sys/src/cmd/8c/txt.c
+++ b/sys/src/cmd/8c/txt.c
@@ -928,8 +928,18 @@
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;
@@ -940,7 +950,11 @@
if(n->left->complex >= FNX)
print("botch in doindex\n");
- regalloc(&nod, ®node, Z);
+ if(n->right->op == OREGISTER)
+ o = n->right;
+ else if(o == Z || o->op != OREGISTER || regused(n, o->reg))
+ o = Z;
+ regalloc(&nod, ®node, o);
v = constnode.vconst;
cgen(n->right, &nod);
idx.ptr = D_NONE;
@@ -965,11 +979,12 @@
void
gins(int a, Node *f, Node *t)
{
-
if(f != Z && f->op == OINDEX)
- doindex(f);
+ doindex(f, a == AMOVL || a == ALEAL
+ || a == AMOVBLSX || a == AMOVBLZX
+ || a == AMOVWLSX || a == AMOVWLZX ? t : Z);
if(t != Z && t->op == OINDEX)
- doindex(t);
+ doindex(t, Z);
nextpc();
p->as = a;
if(f != Z)