From a6182dab47eadcd4f90ee8ef2c99e5e8fef2c89e Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Sun, 23 Nov 2008 17:26:49 -0800 Subject: [PATCH] indexing optimizations and bug fix R=r OCL=19886 CL=19886 --- src/cmd/6g/cgen.c | 129 +++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 58 deletions(-) diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c index d6f27a92960..74e945e6548 100644 --- a/src/cmd/6g/cgen.c +++ b/src/cmd/6g/cgen.c @@ -351,9 +351,12 @@ agen(Node *n, Node *res) 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 @@ agen(Node *n, Node *res) 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 @@ agen(Node *n, Node *res) 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 @@ agen(Node *n, Node *res) 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 @@ agen(Node *n, Node *res) 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: