Commit a6182dab authored by Ken Thompson's avatar Ken Thompson

indexing optimizations and bug fix

R=r
OCL=19886
CL=19886
parent 3aa063d7
...@@ -351,9 +351,12 @@ agen(Node *n, Node *res) ...@@ -351,9 +351,12 @@ agen(Node *n, Node *res)
if(nr->addable) if(nr->addable)
goto iprad; goto iprad;
if(nl->addable) { if(nl->addable) {
if(whatis(nr) != Wlitint) {
regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
cgen(nr, &n1); cgen(nr, &n1);
cgen(nl, res); }
regalloc(&n3, types[tptr], res);
cgen(nl, &n3);
goto index; goto index;
} }
cgen(nr, res); cgen(nr, res);
...@@ -361,9 +364,12 @@ agen(Node *n, Node *res) ...@@ -361,9 +364,12 @@ agen(Node *n, Node *res)
gmove(res, &tmp); gmove(res, &tmp);
iprad: iprad:
cgen(nl, res); regalloc(&n3, types[tptr], res);
cgen(nl, &n3);
if(whatis(nr) != Wlitint) {
regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
cgen(nr, &n1); cgen(nr, &n1);
}
goto index; goto index;
case OINDEX: case OINDEX:
...@@ -371,9 +377,12 @@ agen(Node *n, Node *res) ...@@ -371,9 +377,12 @@ agen(Node *n, Node *res)
if(nr->addable) if(nr->addable)
goto irad; goto irad;
if(nl->addable) { if(nl->addable) {
if(whatis(nr) != Wlitint) {
regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
cgen(nr, &n1); cgen(nr, &n1);
agen(nl, res); }
regalloc(&n3, types[tptr], res);
agen(nl, &n3);
goto index; goto index;
} }
cgen(nr, res); cgen(nr, res);
...@@ -381,66 +390,39 @@ agen(Node *n, Node *res) ...@@ -381,66 +390,39 @@ agen(Node *n, Node *res)
gmove(res, &tmp); gmove(res, &tmp);
irad: irad:
agen(nl, res); regalloc(&n3, types[tptr], res);
agen(nl, &n3);
if(whatis(nr) != Wlitint) {
regalloc(&n1, nr->type, N); regalloc(&n1, nr->type, N);
cgen(nr, &n1); cgen(nr, &n1);
}
goto index; goto index;
index: index:
// &a is in res // &a is in &n3 (allocated in res)
// i is in &n1 // i is in &n1 (if not constant)
// w is width // w is width
if(w == 0) if(w == 0)
fatal("index is zero width"); fatal("index is zero width");
if(whatis(nr) == Wlitint) {
if(isptrdarray(nl->type)) { if(isptrdarray(nl->type)) {
regalloc(&n2, types[tptr], res); n1 = n3;
gmove(res, &n2); n1.op = OINDREG;
n1.type = types[tptr];
if(!debug['B']) { n1.xoffset = offsetof(Array, array);
// check bounds gmove(&n1, &n3);
n3 = n2;
n3.op = OINDREG;
n3.type = types[tptr];
n3.xoffset = offsetof(Array, nel);
gins(optoas(OCMP, types[TUINT32]), &n1, &n3);
p1 = gbranch(optoas(OLT, types[TUINT32]), T);
gins(ACALL, N, throwindex);
patch(p1, pc);
}
// fetch array base from dope
n3 = n2;
n3.op = OINDREG;
n3.type = types[tptr];
n3.xoffset = offsetof(Array, array);
gins(AMOVQ, &n3, &n2);
gmove(&n2, res);
regfree(&n2);
} else
if(!debug['B']) {
// check bounds
nodconst(&n3, types[TUINT32], nl->type->bound);
if(isptrarray(nl->type))
nodconst(&n3, types[TUINT32], nl->type->type->bound);
gins(optoas(OCMP, types[TUINT32]), &n1, &n3);
p1 = gbranch(optoas(OLT, types[TUINT32]), T);
gins(ACALL, N, throwindex);
patch(p1, pc);
} }
if(whatis(nr) == Wlitint) {
regfree(&n1);
v = mpgetfix(nr->val.u.xval); v = mpgetfix(nr->val.u.xval);
nodconst(&n2, types[tptr], v*w); nodconst(&n2, types[tptr], v*w);
gins(optoas(OADD, types[tptr]), &n2, res); gins(optoas(OADD, types[tptr]), &n2, &n3);
gmove(&n3, res);
regfree(&n3);
break; break;
} }
// type of the index
t = types[TUINT64]; t = types[TUINT64];
if(issigned[n1.type->etype]) if(issigned[n1.type->etype])
t = types[TINT64]; t = types[TINT64];
...@@ -449,10 +431,41 @@ agen(Node *n, Node *res) ...@@ -449,10 +431,41 @@ agen(Node *n, Node *res)
gmove(&n1, &n2); gmove(&n1, &n2);
regfree(&n1); regfree(&n1);
nodconst(&n3, t, w); // w if(!debug['B']) {
gins(optoas(OMUL, t), &n3, &n2); // check bounds
gins(optoas(OADD, types[tptr]), &n2, res); if(isptrdarray(nl->type)) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
n1.xoffset = offsetof(Array, nel);
} else {
nodconst(&n1, types[TUINT64], nl->type->bound);
if(isptrarray(nl->type))
nodconst(&n1, types[TUINT64], nl->type->type->bound);
}
gins(optoas(OCMP, types[TUINT64]), &n2, &n1);
p1 = gbranch(optoas(OLT, types[TUINT64]), T);
gins(ACALL, N, throwindex);
patch(p1, pc);
}
if(w != 1) {
nodconst(&n1, t, w); // w
gins(optoas(OMUL, t), &n1, &n2);
}
if(isptrdarray(nl->type)) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
n1.xoffset = offsetof(Array, array);
gmove(&n1, &n3);
}
gins(optoas(OADD, types[tptr]), &n2, &n3);
gmove(&n3, res);
regfree(&n2); regfree(&n2);
regfree(&n3);
break; break;
case OIND: case OIND:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment