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.
This commit is contained in:
parent
9f6967ed7e
commit
345714dd56
2 changed files with 45 additions and 9 deletions
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue