]> Cypherpunks repositories - gostls13.git/commitdiff
arraytoslice and some cleanup
authorKen Thompson <ken@golang.org>
Fri, 28 Aug 2009 22:44:24 +0000 (15:44 -0700)
committerKen Thompson <ken@golang.org>
Fri, 28 Aug 2009 22:44:24 +0000 (15:44 -0700)
R=rsc
OCL=34058
CL=34058

src/cmd/6g/ggen.c
test/ken/slicearray.go

index acbb3032104316df564aa9b607d44c54848412c3..788e6daa55b7352045960ac9ed29f5b030504fbd 100644 (file)
@@ -1180,12 +1180,16 @@ regcmp(Node *ra, Node *rb)
        return ra->local - rb->local;
 }
 
+static Prog*   throwpc;
+
 void
 getargs(NodeList *nn, Node *reg, int n)
 {
        NodeList *l;
        int i;
 
+       throwpc = nil;
+
        l = nn;
        for(i=0; i<n; i++) {
                if(!smallintconst(l->n->right) && !isslice(l->n->right->type)) {
@@ -1218,8 +1222,13 @@ cmpandthrow(Node *nl, Node *nr)
                        return;
                if(smallintconst(nr)) {
                        cr = mpgetfix(nr->val.u.xval);
-                       if(cl > cr)
-                               ginscall(throwslice, 0);
+                       if(cl > cr) {
+                               if(throwpc == nil) {
+                                       throwpc = pc;
+                                       ginscall(throwslice, 0);
+                               } else
+                                       patch(gbranch(AJMP, T), throwpc);
+                       }
                        return;
                }
 
@@ -1231,9 +1240,16 @@ cmpandthrow(Node *nl, Node *nr)
        }
 
        gins(optoas(OCMP, types[TUINT32]), nl, nr);
-       p1 = gbranch(optoas(op, types[TUINT32]), T);
-       ginscall(throwslice, 0);
-       patch(p1, pc);
+       if(throwpc == nil) {
+               p1 = gbranch(optoas(op, types[TUINT32]), T);
+               throwpc = pc;
+               ginscall(throwslice, 0);
+               patch(p1, pc);
+       } else {
+               op = brcom(op);
+               p1 = gbranch(optoas(op, types[TUINT32]), T);
+               patch(p1, throwpc);
+       }
 }
 
 int
@@ -1253,7 +1269,7 @@ sleasy(Node *n)
 int
 cgen_inline(Node *n, Node *res)
 {
-       Node nodes[10];
+       Node nodes[5];
        Node n1, n2;
        vlong v;
        int i;
@@ -1278,25 +1294,25 @@ slicearray:
        getargs(n->list, nodes, 5);
 
        // if(hb[3] > nel[1]) goto throw
-       cmpandthrow(nodes+3, nodes+1);
+       cmpandthrow(&nodes[3], &nodes[1]);
 
        // if(lb[2] > hb[3]) goto throw
-       cmpandthrow(nodes+2, nodes+3);
+       cmpandthrow(&nodes[2], &nodes[3]);
 
        // len = hb[3] - lb[2] (destroys hb)
        n2 = *res;
        n2.xoffset += Array_nel;
 
-       if(smallintconst(nodes+3) && smallintconst(nodes+2)) {
-               v = mpgetfix((nodes+3)->val.u.xval) -
-                       mpgetfix((nodes+2)->val.u.xval);
+       if(smallintconst(&nodes[3]) && smallintconst(&nodes[2])) {
+               v = mpgetfix(nodes[3].val.u.xval) -
+                       mpgetfix(nodes[2].val.u.xval);
                nodconst(&n1, types[TUINT32], v);
                gins(optoas(OAS, types[TUINT32]), &n1, &n2);
        } else {
-               regalloc(&n1, types[TUINT32], nodes+3);
-               gmove(nodes+3, &n1);
-               if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0)
-                       gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
+               regalloc(&n1, types[TUINT32], &nodes[3]);
+               gmove(&nodes[3], &n1);
+               if(!smallintconst(&nodes[2]) || mpgetfix(nodes[2].val.u.xval) != 0)
+                       gins(optoas(OSUB, types[TUINT32]), &nodes[2], &n1);
                gins(optoas(OAS, types[TUINT32]), &n1, &n2);
                regfree(&n1);
        }
@@ -1305,16 +1321,16 @@ slicearray:
        n2 = *res;
        n2.xoffset += Array_cap;
 
-       if(smallintconst(nodes+1) && smallintconst(nodes+2)) {
-               v = mpgetfix((nodes+1)->val.u.xval) -
-                       mpgetfix((nodes+2)->val.u.xval);
+       if(smallintconst(&nodes[1]) && smallintconst(&nodes[2])) {
+               v = mpgetfix(nodes[1].val.u.xval) -
+                       mpgetfix(nodes[2].val.u.xval);
                nodconst(&n1, types[TUINT32], v);
                gins(optoas(OAS, types[TUINT32]), &n1, &n2);
        } else {
-               regalloc(&n1, types[TUINT32], nodes+1);
-               gmove(nodes+1, &n1);
-               if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0)
-                       gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
+               regalloc(&n1, types[TUINT32], &nodes[1]);
+               gmove(&nodes[1], &n1);
+               if(!smallintconst(&nodes[2]) || mpgetfix(nodes[2].val.u.xval) != 0)
+                       gins(optoas(OSUB, types[TUINT32]), &nodes[2], &n1);
                gins(optoas(OAS, types[TUINT32]), &n1, &n2);
                regfree(&n1);
        }
@@ -1323,73 +1339,97 @@ slicearray:
        n2 = *res;
        n2.xoffset += Array_array;
 
-       if(smallintconst(nodes+2) && smallintconst(nodes+4)) {
-               v = mpgetfix((nodes+2)->val.u.xval) *
-                       mpgetfix((nodes+4)->val.u.xval);
+       if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) {
+               v = mpgetfix(nodes[2].val.u.xval) *
+                       mpgetfix(nodes[4].val.u.xval);
                if(v != 0) {
                        nodconst(&n1, types[tptr], v);
-                       gins(optoas(OADD, types[tptr]), &n1, nodes+0);
+                       gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
                }
        } else {
-               regalloc(&n1, types[tptr], nodes+2);
-               gmove(nodes+2, &n1);
-               if(!smallintconst(nodes+4) || mpgetfix((nodes+4)->val.u.xval) != 1)
-                       gins(optoas(OMUL, types[tptr]), nodes+4, &n1);
-               gins(optoas(OADD, types[tptr]), &n1, nodes+0);
+               regalloc(&n1, types[tptr], &nodes[2]);
+               gmove(&nodes[2], &n1);
+               if(!smallintconst(&nodes[4]) || mpgetfix(nodes[4].val.u.xval) != 1)
+                       gins(optoas(OMUL, types[tptr]), &nodes[4], &n1);
+               gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
                regfree(&n1);
        }
-       gins(optoas(OAS, types[tptr]), nodes+0, &n2);
+       gins(optoas(OAS, types[tptr]), &nodes[0], &n2);
 
        for(i=0; i<5; i++) {
-               if((nodes+i)->op == OREGISTER)
-                       regfree(nodes+i);
+               if(nodes[i].op == OREGISTER)
+                       regfree(&nodes[i]);
+       }
+       return 1;
+
+arraytoslice:
+       getargs(n->list, nodes, 2);
+
+       // ret.len = nel[1];
+       n2 = *res;
+       n2.xoffset += Array_nel;
+       gins(optoas(OAS, types[TUINT32]), &nodes[1], &n2);
+
+       // ret.cap = nel[1];
+       n2 = *res;
+       n2.xoffset += Array_cap;
+       gins(optoas(OAS, types[TUINT32]), &nodes[1], &n2);
+
+       // ret.array = old[0];
+       n2 = *res;
+       n2.xoffset += Array_array;
+       gins(optoas(OAS, types[tptr]), &nodes[0], &n2);
+
+       for(i=0; i<2; i++) {
+               if(nodes[i].op == OREGISTER)
+                       regfree(&nodes[i]);
        }
        return 1;
 
 sliceslice:
        getargs(n->list, nodes, 4);
-       if(!sleasy(nodes+0)) {
+       if(!sleasy(&nodes[0])) {
                for(i=0; i<4; i++) {
-                       if((nodes+i)->op == OREGISTER)
-                               regfree(nodes+i);
+                       if(nodes[i].op == OREGISTER)
+                               regfree(&nodes[i]);
                }
                goto no;
        }
 
        // if(hb[2] > old.cap[0]) goto throw;
-       n2 = *(nodes+0);
+       n2 = nodes[0];
        n2.xoffset += Array_cap;
-       cmpandthrow(nodes+2, &n2);
+       cmpandthrow(&nodes[2], &n2);
 
        // if(lb[1] > hb[2]) goto throw;
-       cmpandthrow(nodes+1, nodes+2);
+       cmpandthrow(&nodes[1], &nodes[2]);
 
        // ret.len = hb[2]-lb[1]; (destroys hb[2])
        n2 = *res;
        n2.xoffset += Array_nel;
 
-       if(smallintconst(nodes+2) && smallintconst(nodes+1)) {
-               v = mpgetfix((nodes+2)->val.u.xval) -
-                       mpgetfix((nodes+1)->val.u.xval);
+       if(smallintconst(&nodes[2]) && smallintconst(&nodes[1])) {
+               v = mpgetfix(nodes[2].val.u.xval) -
+                       mpgetfix(nodes[1].val.u.xval);
                nodconst(&n1, types[TUINT32], v);
                gins(optoas(OAS, types[TUINT32]), &n1, &n2);
        } else {
-               regalloc(&n1, types[TUINT32], nodes+2);
-               gmove(nodes+2, &n1);
-               if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0)
-                       gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1);
+               regalloc(&n1, types[TUINT32], &nodes[2]);
+               gmove(&nodes[2], &n1);
+               if(!smallintconst(&nodes[1]) || mpgetfix(nodes[1].val.u.xval) != 0)
+                       gins(optoas(OSUB, types[TUINT32]), &nodes[1], &n1);
                gins(optoas(OAS, types[TUINT32]), &n1, &n2);
                regfree(&n1);
        }
 
        // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
-       n2 = *(nodes+0);
+       n2 = nodes[0];
        n2.xoffset += Array_cap;
 
-       regalloc(&n1, types[TUINT32], nodes+2);
+       regalloc(&n1, types[TUINT32], &nodes[2]);
        gins(optoas(OAS, types[TUINT32]), &n2, &n1);
-       if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0)
-               gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1);
+       if(!smallintconst(&nodes[1]) || mpgetfix(nodes[1].val.u.xval) != 0)
+               gins(optoas(OSUB, types[TUINT32]), &nodes[1], &n1);
 
        n2 = *res;
        n2.xoffset += Array_cap;
@@ -1397,22 +1437,22 @@ sliceslice:
        regfree(&n1);
 
        // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
-       n2 = *(nodes+0);
+       n2 = nodes[0];
        n2.xoffset += Array_array;
 
-       regalloc(&n1, types[tptr], nodes+1);
-       if(smallintconst(nodes+1) && smallintconst(nodes+3)) {
+       regalloc(&n1, types[tptr], &nodes[1]);
+       if(smallintconst(&nodes[1]) && smallintconst(&nodes[3])) {
                gins(optoas(OAS, types[tptr]), &n2, &n1);
-               v = mpgetfix((nodes+1)->val.u.xval) *
-                       mpgetfix((nodes+3)->val.u.xval);
+               v = mpgetfix(nodes[1].val.u.xval) *
+                       mpgetfix(nodes[3].val.u.xval);
                if(v != 0) {
                        nodconst(&n2, types[tptr], v);
                        gins(optoas(OADD, types[tptr]), &n2, &n1);
                }
        } else {
-               gmove(nodes+1, &n1);
-               if(!smallintconst(nodes+3) || mpgetfix((nodes+3)->val.u.xval) != 1)
-                       gins(optoas(OMUL, types[tptr]), nodes+3, &n1);
+               gmove(&nodes[1], &n1);
+               if(!smallintconst(&nodes[3]) || mpgetfix(nodes[3].val.u.xval) != 1)
+                       gins(optoas(OMUL, types[tptr]), &nodes[3], &n1);
                gins(optoas(OADD, types[tptr]), &n2, &n1);
        }
 
@@ -1422,17 +1462,11 @@ sliceslice:
        regfree(&n1);
 
        for(i=0; i<4; i++) {
-               if((nodes+i)->op == OREGISTER)
-                       regfree(nodes+i);
+               if(nodes[i].op == OREGISTER)
+                       regfree(&nodes[i]);
        }
        return 1;
 
-arraytoslice:
-       // ret.len = nel;
-       // ret.cap = nel;
-       // ret.array = old;
-       goto no;
-
 no:
        return 0;
 }
index 31faa9c783e63b093704b1f9b2de7651a25094b8..8e03cb3f40b79472a0253cf123d5a7c38829bd5e 100644 (file)
@@ -4,7 +4,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-
 package main
 
 var    bx      [10]byte
@@ -17,6 +16,12 @@ var  t       int
 func
 main()
 {
+       lb = 0; hb = 10;
+       by = &bx; tstb();
+
+       lb = 0; hb = 10;
+       fy = &fx; tstf();
+
        // width 1 (byte)
        lb = 0; hb = 10;
        by = bx[lb:hb]; tstb();