shithub: riscv

Download patch

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, &regnode, Z);
+	if(n->right->op == OREGISTER)
+		o = n->right;
+	else if(o == Z || o->op != OREGISTER || regused(n, o->reg))
+		o = Z;
+	regalloc(&nod, &regnode, 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)