]> Cypherpunks repositories - gostls13.git/commitdiff
6g etc: groundwork for eliminating redundant bounds checks.
authorRuss Cox <rsc@golang.org>
Thu, 3 Dec 2009 01:30:07 +0000 (17:30 -0800)
committerRuss Cox <rsc@golang.org>
Thu, 3 Dec 2009 01:30:07 +0000 (17:30 -0800)
drop check in range over array.
drop check in [256]array indexed by byte.

R=ken2
https://golang.org/cl/163088

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/gc/range.c
src/cmd/gc/walk.c

index 6fc42f5acf83d6ff50e3f722b97a5194feb41771..dea94dc08d29602a822475bb0f41731c59f110e3 100644 (file)
@@ -547,7 +547,7 @@ agen(Node *n, Node *res)
                        v = mpgetfix(nr->val.u.xval);
                        if(isslice(nl->type)) {
 
-                               if(!debug['B']) {
+                               if(!debug['B'] && !n->etype) {
                                        n1 = n3;
                                        n1.op = OINDREG;
                                        n1.type = types[tptr];
@@ -599,7 +599,7 @@ agen(Node *n, Node *res)
                gmove(&n1, &n2);
                regfree(&n1);
 
-               if(!debug['B']) {
+               if(!debug['B'] && !n->etype) {
                        // check bounds
                        regalloc(&n4, types[TUINT32], N);
                        if(isslice(nl->type)) {
index b14c7d2f34db913e9e106a2eebf7c018b30347fc..5357d06fa0b123198136fbb4af0ef9020bf0324b 100644 (file)
@@ -1767,7 +1767,7 @@ oindex_const:
        v = mpgetfix(r->val.u.xval);
        if(o & ODynam) {
 
-               if(!debug['B']) {
+               if(!debug['B'] && !n->etype) {
                        n1 = *reg;
                        n1.op = OINDREG;
                        n1.type = types[tptr];
index 041f6c13c0514315a9e5f9e1bf09388781473474..1e7c6e4427783c9e9c389b87be6a2bde5a567719 100644 (file)
@@ -504,7 +504,7 @@ agen(Node *n, Node *res)
                        v = mpgetfix(nr->val.u.xval);
                        if(isslice(nl->type)) {
 
-                               if(!debug['B']) {
+                               if(!debug['B'] && !n->etype) {
                                        n1 = n3;
                                        n1.op = OINDREG;
                                        n1.type = types[tptr];
@@ -547,7 +547,7 @@ agen(Node *n, Node *res)
                gmove(&n1, &n2);
                regfree(&n1);
 
-               if(!debug['B']) {
+               if(!debug['B'] && !n->etype) {
                        // check bounds
                        if(isslice(nl->type)) {
                                n1 = n3;
index 4f3c85a6b3844dabf65462c856987bbff6e80d46..7461649ad974d30999fadeac690ce96c9a90c976 100644 (file)
@@ -1827,23 +1827,24 @@ oindex:
                agen(l, reg);
        }
 
+       if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) {
+               // cannot rely on page protections to
+               // catch array ptr == 0, so dereference.
+               n2 = *reg;
+               n2.op = OINDREG;
+               n2.type = types[TUINT8];
+               n2.xoffset = 0;
+               gins(ATESTB, nodintconst(0), &n2);
+       }
+
        // check bounds
-       if(!debug['B']) {
+       if(!debug['B'] && !n->etype) {
                if(o & ODynam) {
                        n2 = *reg;
                        n2.op = OINDREG;
                        n2.type = types[tptr];
                        n2.xoffset = Array_nel;
                } else {
-                       if(l->type->width >= unmappedzero && l->op == OIND) {
-                               // cannot rely on page protections to
-                               // catch array ptr == 0, so dereference.
-                               n2 = *reg;
-                               n2.op = OINDREG;
-                               n2.type = types[TUINT8];
-                               n2.xoffset = 0;
-                               gins(ATESTB, nodintconst(0), &n2);
-                       }
                        nodconst(&n2, types[TUINT64], l->type->bound);
                }
                gins(optoas(OCMP, types[TUINT32]), reg1, &n2);
@@ -1879,7 +1880,7 @@ oindex_const:
        v = mpgetfix(r->val.u.xval);
        if(o & ODynam) {
 
-               if(!debug['B']) {
+               if(!debug['B'] && !n->etype) {
                        n1 = *reg;
                        n1.op = OINDREG;
                        n1.type = types[tptr];
index 84cb4bcbe3e4bda79b7baffb5038b864c4a4ef69..3f0514a36de616dd27a35dca7857ee026086d882 100644 (file)
@@ -540,7 +540,7 @@ agen(Node *n, Node *res)
                        v = mpgetfix(nr->val.u.xval);
                        if(isslice(nl->type)) {
 
-                               if(!debug['B']) {
+                               if(!debug['B'] && !n->etype) {
                                        n1 = n3;
                                        n1.op = OINDREG;
                                        n1.type = types[tptr];
@@ -558,7 +558,7 @@ agen(Node *n, Node *res)
                                n1.xoffset = Array_array;
                                gmove(&n1, &n3);
                        } else
-                       if(!debug['B']) {
+                       if(!debug['B'] && !n->etype) {
                                if(v < 0)
                                        yyerror("out of bounds on array");
                                else
@@ -583,7 +583,7 @@ agen(Node *n, Node *res)
                gmove(&n1, &n2);
                regfree(&n1);
 
-               if(!debug['B']) {
+               if(!debug['B'] && !n->etype) {
                        // check bounds
                        if(isslice(nl->type)) {
                                n1 = n3;
index 758cd4f29b959528903ce7d59cd1b7e84f00db18..4147e8e6c9add1598598434cfd1c2469b7067af1 100644 (file)
@@ -91,7 +91,7 @@ walkrange(Node *n)
        Node *ohv1, *hv1, *hv2; // hidden (old) val 1, 2
        Node *ha, *hit; // hidden aggregate, iterator
        Node *a, *v1, *v2;      // not hidden aggregate, val 1, 2
-       Node *fn;
+       Node *fn, *tmp;
        NodeList *body, *init;
        Type *th, *t;
 
@@ -128,8 +128,11 @@ walkrange(Node *n)
                n->nincr = nod(OASOP, hv1, nodintconst(1));
                n->nincr->etype = OADD;
                body = list1(nod(OAS, v1, hv1));
-               if(v2)
-                       body = list(body, nod(OAS, v2, nod(OINDEX, ha, hv1)));
+               if(v2) {
+                       tmp = nod(OINDEX, ha, hv1);
+                       tmp->etype = 1; // no bounds check
+                       body = list(body, nod(OAS, v2, tmp));
+               }
                break;
 
        case TMAP:
index 3c3a00cfd6df961f7ee4387317b9621d66d2d56d..62bbf9f5abea731c4bb0906ab41f02e2802295ce 100644 (file)
@@ -787,6 +787,14 @@ walkexpr(Node **np, NodeList **init)
        case OINDEX:
                walkexpr(&n->left, init);
                walkexpr(&n->right, init);
+               
+               // if range of type cannot exceed static array bound,
+               // disable bounds check
+               if(!isslice(n->left->type))
+               if(n->right->type->width < 4)
+               if((1<<(8*n->right->type->width)) <= n->left->type->bound)
+                       n->etype = 1;
+
                goto ret;
 
        case OINDEXMAP: