indexing optimizations and bug fix
R=r
OCL=19886
CL=19886
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index d6f27a9..74e945e 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -351,9 +351,12 @@
if(nr->addable)
goto iprad;
if(nl->addable) {
- regalloc(&n1, nr->type, N);
- cgen(nr, &n1);
- cgen(nl, res);
+ if(whatis(nr) != Wlitint) {
+ regalloc(&n1, nr->type, N);
+ cgen(nr, &n1);
+ }
+ regalloc(&n3, types[tptr], res);
+ cgen(nl, &n3);
goto index;
}
cgen(nr, res);
@@ -361,9 +364,12 @@
gmove(res, &tmp);
iprad:
- cgen(nl, res);
- regalloc(&n1, nr->type, N);
- cgen(nr, &n1);
+ regalloc(&n3, types[tptr], res);
+ cgen(nl, &n3);
+ if(whatis(nr) != Wlitint) {
+ regalloc(&n1, nr->type, N);
+ cgen(nr, &n1);
+ }
goto index;
case OINDEX:
@@ -371,9 +377,12 @@
if(nr->addable)
goto irad;
if(nl->addable) {
- regalloc(&n1, nr->type, N);
- cgen(nr, &n1);
- agen(nl, res);
+ if(whatis(nr) != Wlitint) {
+ regalloc(&n1, nr->type, N);
+ cgen(nr, &n1);
+ }
+ regalloc(&n3, types[tptr], res);
+ agen(nl, &n3);
goto index;
}
cgen(nr, res);
@@ -381,66 +390,39 @@
gmove(res, &tmp);
irad:
- agen(nl, res);
- regalloc(&n1, nr->type, N);
- cgen(nr, &n1);
+ regalloc(&n3, types[tptr], res);
+ agen(nl, &n3);
+ if(whatis(nr) != Wlitint) {
+ regalloc(&n1, nr->type, N);
+ cgen(nr, &n1);
+ }
goto index;
index:
- // &a is in res
- // i is in &n1
+ // &a is in &n3 (allocated in res)
+ // i is in &n1 (if not constant)
// w is width
if(w == 0)
fatal("index is zero width");
- if(isptrdarray(nl->type)) {
- regalloc(&n2, types[tptr], res);
- gmove(res, &n2);
-
- if(!debug['B']) {
- // check bounds
- 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);
+ if(isptrdarray(nl->type)) {
+ n1 = n3;
+ n1.op = OINDREG;
+ n1.type = types[tptr];
+ n1.xoffset = offsetof(Array, array);
+ gmove(&n1, &n3);
+ }
v = mpgetfix(nr->val.u.xval);
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;
}
+ // type of the index
t = types[TUINT64];
if(issigned[n1.type->etype])
t = types[TINT64];
@@ -449,10 +431,41 @@
gmove(&n1, &n2);
regfree(&n1);
- nodconst(&n3, t, w); // w
- gins(optoas(OMUL, t), &n3, &n2);
- gins(optoas(OADD, types[tptr]), &n2, res);
+ if(!debug['B']) {
+ // check bounds
+ 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(&n3);
break;
case OIND: