changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: 8c, 6c: avoid allocating index registers when we don't have to

changeset 7297: 3b23784f9e2f
parent 7296: 50dd2dc496ff
child 7298: 1d4da8ed4cb1
author: cinap_lenrek@felloff.net
date: Mon, 24 Jun 2019 19:36:01 +0200
files: sys/src/cmd/6c/txt.c sys/src/cmd/8c/txt.c
description: 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.
     1.1--- a/sys/src/cmd/6c/txt.c
     1.2+++ b/sys/src/cmd/6c/txt.c
     1.3@@ -1117,8 +1117,18 @@ gmove(Node *f, Node *t)
     1.4 	gins(a, f, t);
     1.5 }
     1.6 
     1.7+static int
     1.8+regused(Node *n, int r)
     1.9+{
    1.10+	if(n == nil)
    1.11+		return 0;
    1.12+	if(isreg(n, r))
    1.13+		return 1;
    1.14+	return regused(n->left, r) || regused(n->right, r);
    1.15+}
    1.16+
    1.17 void
    1.18-doindex(Node *n)
    1.19+doindex(Node *n, Node *o)
    1.20 {
    1.21 	Node nod, nod1;
    1.22 	long v;
    1.23@@ -1129,7 +1139,11 @@ prtree(n, "index");
    1.24 if(n->left->complex >= FNX)
    1.25 print("botch in doindex\n");
    1.26 
    1.27-	regalloc(&nod, &qregnode, Z);
    1.28+	if(n->right->op == OREGISTER)
    1.29+		o = n->right;
    1.30+	else if(o == Z || o->op != OREGISTER || regused(n, o->reg))
    1.31+		o = Z;
    1.32+	regalloc(&nod, &qregnode, o);
    1.33 	v = constnode.vconst;
    1.34 	cgen(n->right, &nod);
    1.35 	idx.ptr = D_NONE;
    1.36@@ -1139,11 +1153,13 @@ print("botch in doindex\n");
    1.37 		idx.ptr = n->left->reg;
    1.38 	else if(n->left->op != OADDR) {
    1.39 		reg[D_BP]++;	// cant be used as a base
    1.40+		reg[D_R13]++;
    1.41 		regalloc(&nod1, &qregnode, Z);
    1.42 		cgen(n->left, &nod1);
    1.43 		idx.ptr = nod1.reg;
    1.44 		regfree(&nod1);
    1.45 		reg[D_BP]--;
    1.46+		reg[D_R13]--;
    1.47 	}
    1.48 	idx.reg = nod.reg;
    1.49 	regfree(&nod);
    1.50@@ -1155,9 +1171,14 @@ gins(int a, Node *f, Node *t)
    1.51 {
    1.52 
    1.53 	if(f != Z && f->op == OINDEX)
    1.54-		doindex(f);
    1.55+		doindex(f, a == AMOVL || a == ALEAL
    1.56+			|| a == AMOVQ || a == ALEAQ
    1.57+			|| a == AMOVBLSX || a == AMOVBLZX
    1.58+			|| a == AMOVBQSX || a == AMOVBQZX
    1.59+			|| a == AMOVWLSX || a == AMOVWLZX
    1.60+			|| a == AMOVWQSX || a == AMOVWQZX ? t : Z);
    1.61 	if(t != Z && t->op == OINDEX)
    1.62-		doindex(t);
    1.63+		doindex(t, Z);
    1.64 	nextpc();
    1.65 	p->as = a;
    1.66 	if(f != Z)
     2.1--- a/sys/src/cmd/8c/txt.c
     2.2+++ b/sys/src/cmd/8c/txt.c
     2.3@@ -928,8 +928,18 @@ gmove(Node *f, Node *t)
     2.4 	gins(a, f, t);
     2.5 }
     2.6 
     2.7+static int
     2.8+regused(Node *n, int r)
     2.9+{
    2.10+	if(n == nil)
    2.11+		return 0;
    2.12+	if(isreg(n, r))
    2.13+		return 1;
    2.14+	return regused(n->left, r) || regused(n->right, r);
    2.15+}
    2.16+
    2.17 void
    2.18-doindex(Node *n)
    2.19+doindex(Node *n, Node *o)
    2.20 {
    2.21 	Node nod, nod1;
    2.22 	long v;
    2.23@@ -940,7 +950,11 @@ prtree(n, "index");
    2.24 if(n->left->complex >= FNX)
    2.25 print("botch in doindex\n");
    2.26 
    2.27-	regalloc(&nod, &regnode, Z);
    2.28+	if(n->right->op == OREGISTER)
    2.29+		o = n->right;
    2.30+	else if(o == Z || o->op != OREGISTER || regused(n, o->reg))
    2.31+		o = Z;
    2.32+	regalloc(&nod, &regnode, o);
    2.33 	v = constnode.vconst;
    2.34 	cgen(n->right, &nod);
    2.35 	idx.ptr = D_NONE;
    2.36@@ -965,11 +979,12 @@ print("botch in doindex\n");
    2.37 void
    2.38 gins(int a, Node *f, Node *t)
    2.39 {
    2.40-
    2.41 	if(f != Z && f->op == OINDEX)
    2.42-		doindex(f);
    2.43+		doindex(f, a == AMOVL || a == ALEAL
    2.44+			|| a == AMOVBLSX || a == AMOVBLZX
    2.45+			|| a == AMOVWLSX || a == AMOVWLZX ? t : Z);
    2.46 	if(t != Z && t->op == OINDEX)
    2.47-		doindex(t);
    2.48+		doindex(t, Z);
    2.49 	nextpc();
    2.50 	p->as = a;
    2.51 	if(f != Z)