diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-06-24 19:36:01 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-06-24 19:36:01 +0200 |
commit | 345714dd56f5da8dcb2193f9cdf041cfc005d82f (patch) | |
tree | 2e6e832c8f06d88edf309eb711bdf7c3559b7e01 | |
parent | 9f6967ed7e12ec3254bc1b3b7ad3e5a41c274e3a (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.
-rw-r--r-- | sys/src/cmd/6c/txt.c | 29 | ||||
-rw-r--r-- | sys/src/cmd/8c/txt.c | 25 |
2 files changed, 45 insertions, 9 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) diff --git a/sys/src/cmd/8c/txt.c b/sys/src/cmd/8c/txt.c index 9d64aa7e3..4feb0f7f4 100644 --- a/sys/src/cmd/8c/txt.c +++ b/sys/src/cmd/8c/txt.c @@ -928,8 +928,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; @@ -940,7 +950,11 @@ prtree(n, "index"); 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 @@ print("botch in doindex\n"); 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) |