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 /sys/src/cmd/8c | |
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.
Diffstat (limited to 'sys/src/cmd/8c')
-rw-r--r-- | sys/src/cmd/8c/txt.c | 25 |
1 files changed, 20 insertions, 5 deletions
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) |