]> Cypherpunks repositories - gostls13.git/commitdiff
5g, 6g, 8g: generate code for string index
authorRuss Cox <rsc@golang.org>
Wed, 27 Oct 2010 04:11:17 +0000 (21:11 -0700)
committerRuss Cox <rsc@golang.org>
Wed, 27 Oct 2010 04:11:17 +0000 (21:11 -0700)
instead of calling function.

R=ken2
CC=golang-dev
https://golang.org/cl/2762041

14 files changed:
src/cmd/5g/cgen.c
src/cmd/5g/gsubr.c
src/cmd/6g/cgen.c
src/cmd/6g/gsubr.c
src/cmd/8g/cgen.c
src/cmd/8g/reg.c
src/cmd/gc/builtin.c.boot
src/cmd/gc/gen.c
src/cmd/gc/go.h
src/cmd/gc/print.c
src/cmd/gc/runtime.go
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c
src/pkg/runtime/string.goc

index bbe5b9c0b76f755c8a970e6b35d518fe60786f3b..1328f4be644a0e057aac5ca77286703b8c27ed9b 100644 (file)
@@ -558,9 +558,11 @@ agen(Node *n, Node *res)
                p2 = nil;  // to be patched to panicindex.
                w = n->type->width;
                if(nr->addable) {
-                       agenr(nl, &n3, res);
-                       if(!isconst(nr, CTINT)) {
+                       if(!isconst(nr, CTINT))
                                tempname(&tmp, types[TINT32]);
+                       if(!isconst(nl, CTSTR))
+                               agenr(nl, &n3, res);
+                       if(!isconst(nr, CTINT)) {
                                p2 = cgenindex(nr, &tmp);
                                regalloc(&n1, tmp.type, N);
                                gmove(&tmp, &n1);
@@ -572,13 +574,16 @@ agen(Node *n, Node *res)
                                regalloc(&n1, tmp.type, N);
                                gmove(&tmp, &n1);
                        }
-                       regalloc(&n3, types[tptr], res);
-                       agen(nl, &n3);
+                       if(!isconst(nl, CTSTR)) {
+                               regalloc(&n3, types[tptr], res);
+                               agen(nl, &n3);
+                       }
                } else {
                        tempname(&tmp, types[TINT32]);
                        p2 = cgenindex(nr, &tmp);
                        nr = &tmp;
-                       agenr(nl, &n3, res);
+                       if(!isconst(nl, CTSTR))
+                               agenr(nl, &n3, res);
                        regalloc(&n1, tmp.type, N);
                        gins(optoas(OAS, tmp.type), &tmp, &n1);
                }
@@ -592,9 +597,10 @@ agen(Node *n, Node *res)
 
                // constant index
                if(isconst(nr, CTINT)) {
+                       if(isconst(nl, CTSTR))
+                               fatal("constant string constant index");
                        v = mpgetfix(nr->val.u.xval);
-                       if(isslice(nl->type)) {
-
+                       if(isslice(nl->type) || nl->type->etype == TSTRING) {
                                if(!debug['B'] && !n->etype) {
                                        n1 = n3;
                                        n1.op = OINDREG;
@@ -638,7 +644,10 @@ agen(Node *n, Node *res)
                if(!debug['B'] && !n->etype) {
                        // check bounds
                        regalloc(&n4, types[TUINT32], N);
-                       if(isslice(nl->type)) {
+                       if(isconst(nl, CTSTR)) {
+                               nodconst(&n1, types[TUINT32], nl->val.u.sval->len);
+                               gmove(&n1, &n4);
+                       } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
                                n1 = n3;
                                n1.op = OINDREG;
                                n1.type = types[tptr];
@@ -656,8 +665,13 @@ agen(Node *n, Node *res)
                        ginscall(panicindex, 0);
                        patch(p1, pc);
                }
-
-               if(isslice(nl->type)) {
+               
+               if(isconst(nl, CTSTR)) {
+                       regalloc(&n3, types[tptr], res);
+                       p1 = gins(AMOVW, N, &n3);
+                       datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
+                       p1->from.type = D_CONST;
+               } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
                        n1 = n3;
                        n1.op = OINDREG;
                        n1.type = types[tptr];
@@ -795,12 +809,8 @@ igen(Node *n, Node *a, Node *res)
 void
 agenr(Node *n, Node *a, Node *res)
 {
-       Node n1;
-
-       tempname(&n1, types[tptr]);
-       agen(n, &n1);
        regalloc(a, types[tptr], res);
-       gmove(&n1, a);
+       agen(n, a);
 }
 
 /*
index 7089b71850d2970fc86519d562a4b3f12d4784c1..260a9d3f6a05535d86ca7c301f470b92b4028812 100644 (file)
@@ -1678,6 +1678,8 @@ sudoaddable(int as, Node *n, Addr *a, int *w)
                goto odot;
 
        case OINDEX:
+               if(n->left->type->etype == TSTRING)
+                       return 0;
                cleani += 2;
                reg = &clean[cleani-1];
                reg1 = &clean[cleani-2];
index 1df6b25dd26f37ded629cd7985cae5281537e576..d4d22fd610c1c2528dcb861ab3aed925502ee0c2 100644 (file)
@@ -477,8 +477,10 @@ agen(Node *n, Node *res)
                                regalloc(&n1, nr->type, N);
                                cgen(nr, &n1);
                        }
-                       regalloc(&n3, types[tptr], res);
-                       agen(nl, &n3);
+                       if(!isconst(nl, CTSTR)) {
+                               regalloc(&n3, types[tptr], res);
+                               agen(nl, &n3);
+                       }
                        goto index;
                }
                tempname(&tmp, nr->type);
@@ -486,8 +488,10 @@ agen(Node *n, Node *res)
                nr = &tmp;
 
        irad:
-               regalloc(&n3, types[tptr], res);
-               agen(nl, &n3);
+               if(!isconst(nl, CTSTR)) {
+                       regalloc(&n3, types[tptr], res);
+                       agen(nl, &n3);
+               }
                if(!isconst(nr, CTINT)) {
                        regalloc(&n1, nr->type, N);
                        cgen(nr, &n1);
@@ -501,7 +505,7 @@ agen(Node *n, Node *res)
 
                // explicit check for nil if array is large enough
                // that we might derive too big a pointer.
-               if(!isslice(nl->type) && nl->type->width >= unmappedzero) {
+               if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
                        regalloc(&n4, types[tptr], &n3);
                        gmove(&n3, &n4);
                        n4.op = OINDREG;
@@ -516,8 +520,10 @@ agen(Node *n, Node *res)
 
                // constant index
                if(isconst(nr, CTINT)) {
+                       if(isconst(nl, CTSTR))
+                               fatal("constant string constant index");        // front end should handle
                        v = mpgetfix(nr->val.u.xval);
-                       if(isslice(nl->type)) {
+                       if(isslice(nl->type) || nl->type->etype == TSTRING) {
                                if(!debug['B'] && !n->etype) {
                                        n1 = n3;
                                        n1.op = OINDREG;
@@ -556,20 +562,21 @@ agen(Node *n, Node *res)
                        // check bounds
                        n5.op = OXXX;
                        t = types[TUINT32];
-                       if(isslice(nl->type)) {
+                       if(is64(nr->type))
+                               t = types[TUINT64];
+                       if(isconst(nl, CTSTR)) {
+                               nodconst(&n1, t, nl->val.u.sval->len);
+                       } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
                                n1 = n3;
                                n1.op = OINDREG;
                                n1.type = types[TUINT32];
                                n1.xoffset = Array_nel;
                                if(is64(nr->type)) {
-                                       t = types[TUINT64];
                                        regalloc(&n5, t, N);
                                        gmove(&n1, &n5);
                                        n1 = n5;
                                }
                        } else {
-                               if(is64(nr->type))
-                                       t = types[TUINT64];
                                nodconst(&n1, t, nl->type->bound);
                        }
                        gins(optoas(OCMP, t), &n2, &n1);
@@ -580,7 +587,16 @@ agen(Node *n, Node *res)
                        patch(p1, pc);
                }
 
-               if(isslice(nl->type)) {
+               if(isconst(nl, CTSTR)) {
+                       regalloc(&n3, types[tptr], res);
+                       p1 = gins(ALEAQ, N, &n3);
+                       datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
+                       p1->from.scale = 1;
+                       p1->from.index = n2.val.u.reg;
+                       goto indexdone;
+               }
+
+               if(isslice(nl->type) || nl->type->etype == TSTRING) {
                        n1 = n3;
                        n1.op = OINDREG;
                        n1.type = types[tptr];
@@ -599,6 +615,7 @@ agen(Node *n, Node *res)
                        gmove(&n3, res);
                }
 
+       indexdone:
                gmove(&n3, res);
                regfree(&n2);
                regfree(&n3);
index 1cd5c650bd4555c23fc620e3aa47b3b4a4382d33..ebb61ea9459bb2f83af5137f763719c3b0cc5ba1 100644 (file)
@@ -1784,6 +1784,8 @@ sudoaddable(int as, Node *n, Addr *a)
                goto odot;
 
        case OINDEX:
+               if(n->left->type->etype == TSTRING)
+                       return 0;
                goto oindex;
        }
        return 0;
index 810ad4da64c6e941ca0eb022c4d92ee447a22beb..875d434fa79b336d108a2398efd3abfe07027336 100644 (file)
@@ -230,8 +230,8 @@ cgen(Node *n, Node *res)
                        cgen(nl, res);
                        break;
                }
-               mgen(nl, &n1, res);
                tempname(&n2, n->type);
+               mgen(nl, &n1, res);
                gmove(&n1, &n2);
                gmove(&n2, res);
                mfree(&n1);
@@ -518,9 +518,11 @@ agen(Node *n, Node *res)
                p2 = nil;  // to be patched to panicindex.
                w = n->type->width;
                if(nr->addable) {
-                       agenr(nl, &n3, res);
-                       if(!isconst(nr, CTINT)) {
+                       if(!isconst(nr, CTINT))
                                tempname(&tmp, types[TINT32]);
+                       if(!isconst(nl, CTSTR))
+                               agenr(nl, &n3, res);
+                       if(!isconst(nr, CTINT)) {
                                p2 = cgenindex(nr, &tmp);
                                regalloc(&n1, tmp.type, N);
                                gmove(&tmp, &n1);
@@ -532,13 +534,16 @@ agen(Node *n, Node *res)
                                regalloc(&n1, tmp.type, N);
                                gmove(&tmp, &n1);
                        }
-                       regalloc(&n3, types[tptr], res);
-                       agen(nl, &n3);
+                       if(!isconst(nl, CTSTR)) {
+                               regalloc(&n3, types[tptr], res);
+                               agen(nl, &n3);
+                       }
                } else {
                        tempname(&tmp, types[TINT32]);
                        p2 = cgenindex(nr, &tmp);
                        nr = &tmp;
-                       agenr(nl, &n3, res);
+                       if(!isconst(nl, CTSTR))
+                               agenr(nl, &n3, res);
                        regalloc(&n1, tmp.type, N);
                        gins(optoas(OAS, tmp.type), &tmp, &n1);
                }
@@ -549,7 +554,7 @@ agen(Node *n, Node *res)
 
                // explicit check for nil if array is large enough
                // that we might derive too big a pointer.
-               if(!isslice(nl->type) && nl->type->width >= unmappedzero) {
+               if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
                        regalloc(&n4, types[tptr], &n3);
                        gmove(&n3, &n4);
                        n4.op = OINDREG;
@@ -564,9 +569,10 @@ agen(Node *n, Node *res)
 
                // constant index
                if(isconst(nr, CTINT)) {
+                       if(isconst(nl, CTSTR))
+                               fatal("constant string constant index");
                        v = mpgetfix(nr->val.u.xval);
-                       if(isslice(nl->type)) {
-
+                       if(isslice(nl->type) || nl->type->etype == TSTRING) {
                                if(!debug['B'] && !n->etype) {
                                        n1 = n3;
                                        n1.op = OINDREG;
@@ -600,7 +606,9 @@ agen(Node *n, Node *res)
 
                if(!debug['B'] && !n->etype) {
                        // check bounds
-                       if(isslice(nl->type)) {
+                       if(isconst(nl, CTSTR))
+                               nodconst(&n1, types[TUINT32], nl->val.u.sval->len);
+                       else if(isslice(nl->type) || nl->type->etype == TSTRING) {
                                n1 = n3;
                                n1.op = OINDREG;
                                n1.type = types[tptr];
@@ -614,8 +622,17 @@ agen(Node *n, Node *res)
                        ginscall(panicindex, 0);
                        patch(p1, pc);
                }
+               
+               if(isconst(nl, CTSTR)) {
+                       regalloc(&n3, types[tptr], res);
+                       p1 = gins(ALEAL, N, &n3);
+                       datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
+                       p1->from.scale = 1;
+                       p1->from.index = n2.val.u.reg;
+                       goto indexdone;
+               }
 
-               if(isslice(nl->type)) {
+               if(isslice(nl->type) || nl->type->etype == TSTRING) {
                        n1 = n3;
                        n1.op = OINDREG;
                        n1.type = types[tptr];
@@ -635,6 +652,7 @@ agen(Node *n, Node *res)
                        gmove(&n3, res);
                }
 
+       indexdone:
                gmove(&n3, res);
                regfree(&n2);
                regfree(&n3);
@@ -710,8 +728,14 @@ igen(Node *n, Node *a, Node *res)
 {
        Node n1;
 
+       // release register for now, to avoid
+       // confusing tempname.
+       if(res != N && res->op == OREGISTER)
+               reg[res->val.u.reg]--;
        tempname(&n1, types[tptr]);
        agen(n, &n1);
+       if(res != N && res->op == OREGISTER)
+               reg[res->val.u.reg]++;
        regalloc(a, types[tptr], res);
        gmove(&n1, a);
        a->op = OINDREG;
index ae9a5f2eafa0a4aed27af7081278da0d337bbbbf..e1dacf55ad96ee47e3bd26d142a619407656904d 100644 (file)
@@ -789,6 +789,8 @@ mkvar(Reg *r, Adr *a)
 
                        // if they overlaps, disable both
                        if(overlap(v->offset, v->width, o, w)) {
+                               if(debug['R'])
+                                       print("disable %s\n", v->sym->name);
                                v->addr = 1;
                                flag = 1;
                        }
@@ -821,7 +823,7 @@ mkvar(Reg *r, Adr *a)
        v->addr = flag;         // funny punning
 
        if(debug['R'])
-               print("bit=%2d et=%2d w=%d %S %D\n", i, et, w, s, a);
+               print("bit=%2d et=%2d w=%d %S %D flag=%d\n", i, et, w, s, a, v->addr);
        ostats.nvar++;
 
        bit = blsh(i);
index bb1a5f5fa62167d4ca1d3a9b7d254fd264fa05c4..10559a900f1f4ca3178657c4577a4e9c92cdaefc 100644 (file)
@@ -24,7 +24,6 @@ char *runtimeimport =
        "func \"\".cmpstring (? string, ? string) int\n"
        "func \"\".slicestring (? string, ? int, ? int) string\n"
        "func \"\".slicestring1 (? string, ? int) string\n"
-       "func \"\".indexstring (? string, ? int) uint8\n"
        "func \"\".intstring (? int64) string\n"
        "func \"\".slicebytetostring (? []uint8) string\n"
        "func \"\".sliceinttostring (? []int) string\n"
index d2396aa09f0aa70732c71dbc390cd48f8ffd4b14..65861c7635bfbf4d4a07169a31718e75f97797c4 100644 (file)
@@ -652,7 +652,6 @@ tempname(Node *n, Type *t)
        snprint(namebuf, sizeof(namebuf), "autotmp_%.4d", statuniqgen);
        statuniqgen++;
        s = lookup(namebuf);
-
        memset(n, 0, sizeof(*n));
        n->op = ONAME;
        n->sym = s;
index 78472d22eb7dd9b70ac24e6d6de93355adb087a5..91a1562f7591ab380fe43a59bb118043e550b013 100644 (file)
@@ -369,7 +369,7 @@ enum
        ODOTTYPE2,
        OEQ, ONE, OLT, OLE, OGE, OGT,
        OIND,
-       OINDEX, OINDEXSTR, OINDEXMAP,
+       OINDEX, OINDEXMAP,
        OKEY, OPARAM,
        OLEN,
        OMAKE, OMAKECHAN, OMAKEMAP, OMAKESLICE,
index 32e8b7de55251d6ea1eee712c65adc4d215b580c..478aa84e3b58114eef453944961b62395467920f 100644 (file)
@@ -59,6 +59,9 @@ exprfmt(Fmt *f, Node *n, int prec)
        case OPRINT:
        case OPRINTN:
        case OCALL:
+       case OCALLMETH:
+       case OCALLINTER:
+       case OCALLFUNC:
        case OCONV:
        case OCONVNOP:
        case OMAKESLICE:
@@ -72,6 +75,8 @@ exprfmt(Fmt *f, Node *n, int prec)
        case ORECV:
        case OCONVIFACE:
        case OTPAREN:
+       case OINDEX:
+       case OINDEXMAP:
                nprec = 7;
                break;
 
@@ -328,7 +333,6 @@ exprfmt(Fmt *f, Node *n, int prec)
 
        case OINDEX:
        case OINDEXMAP:
-       case OINDEXSTR:
                exprfmt(f, n->left, 7);
                fmtprint(f, "[");
                exprfmt(f, n->right, 0);
index 2279384473f81697f9725165649803803a6cf950..1be706fa2f97c7882cbecf51b89ce0ff671e8597 100644 (file)
@@ -39,7 +39,6 @@ func concatstring()
 func cmpstring(string, string) int
 func slicestring(string, int, int) string
 func slicestring1(string, int) string
-func indexstring(string, int) byte
 func intstring(int64) string
 func slicebytetostring([]byte) string
 func sliceinttostring([]int) string
index 614833740a06097e4ef6a12d550e9639af9067a7..c4f082612c9c5592a72e6035a733413d9d3953c2 100644 (file)
@@ -614,7 +614,6 @@ reswitch:
                        if(n->right->type != T && !isint[n->right->type->etype])
                                yyerror("non-integer string index %#N", n->right);
                        n->type = types[TUINT8];
-                       n->op = OINDEXSTR;
                        break;
                }
                goto ret;
@@ -2052,6 +2051,8 @@ islvalue(Node *n)
        case OINDEX:
                if(isfixedarray(n->left->type))
                        return islvalue(n->left);
+               if(n->left->type != T && n->left->type->etype == TSTRING)
+                       return 0;
                // fall through
        case OIND:
        case ODOTPTR:
index bf20102c7da87e4fdc4f348dd2ada01db0b8b18d..757b6d93d69297314c6cc452258f85ce846c00d9 100644 (file)
@@ -1033,22 +1033,35 @@ walkexpr(Node **np, NodeList **init)
 
                // if range of type cannot exceed static array bound,
                // disable bounds check
-               if(!isslice(n->left->type))
+               if(isfixedarray(n->left->type))
                if(n->right->type->width < 4)
                if((1<<(8*n->right->type->width)) <= n->left->type->bound)
                        n->etype = 1;
 
+               if(isconst(n->left, CTSTR))
+               if(n->right->type->width < 4)
+               if((1<<(8*n->right->type->width)) <= n->left->val.u.sval->len)
+                       n->etype = 1;
+
                // check for static out of bounds
                if(isconst(n->right, CTINT) && !n->etype) {
                        v = mpgetfix(n->right->val.u.xval);
                        len = 1LL<<60;
                        t = n->left->type;
+                       if(isconst(n->left, CTSTR))
+                               len = n->left->val.u.sval->len;
                        if(t != T && isptr[t->etype])
                                t = t->type;
                        if(isfixedarray(t))
                                len = t->bound;
                        if(v < 0 || v >= (1LL<<31) || v >= len)
                                yyerror("index out of bounds");
+                       else if(isconst(n->left, CTSTR)) {
+                               // replace "abc"[2] with 'b'.
+                               // delayed until now because "abc"[2] is not
+                               // an ideal constant.
+                               nodconst(n, n->type, n->left->val.u.sval->s[v]);
+                       }
                }
                goto ret;
 
@@ -1252,14 +1265,6 @@ walkexpr(Node **np, NodeList **init)
                }
                goto ret;
 
-       case OINDEXSTR:
-               // TODO(rsc): should be done in back end
-               // sys_indexstring(s, i)
-               n = mkcall("indexstring", n->type, init,
-                       conv(n->left, types[TSTRING]),
-                       conv(n->right, types[TINT]));
-               goto ret;
-
        case OCOPY:
                if(n->right->type->etype == TSTRING)
                        fn = syslook("slicestringcopy", 1);
index 7bf8f8b37c7880ce81abe2efe954c42d7eb945f2..1db1c2c2cb023d8f8d2b2a940af15308f3dce286 100644 (file)
@@ -200,10 +200,6 @@ func slicestring(si String, lindex int32, hindex int32) (so String) {
        l = hindex-lindex;
        so.str = si.str + lindex;
        so.len = l;
-
-//     alternate to create a new string
-//     so = gostringsize(l);
-//     mcpy(so.str, si.str+lindex, l);
 }
 
 func slicestring1(si String, lindex int32) (so String) {
@@ -216,18 +212,6 @@ func slicestring1(si String, lindex int32) (so String) {
        l = si.len-lindex;
        so.str = si.str + lindex;
        so.len = l;
-
-//     alternate to create a new string
-//     so = gostringsize(l);
-//     mcpy(so.str, si.str+lindex, l);
-}
-
-func indexstring(s String, i int32) (b byte) {
-       if(i < 0 || i >= s.len) {
-               ·panicindex();
-       }
-
-       b = s.str[i];
 }
 
 func intstring(v int64) (s String) {