]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: optimize existence-only map lookups
authorJosh Bleecher Snyder <josharian@gmail.com>
Mon, 22 Dec 2014 19:33:47 +0000 (11:33 -0800)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 7 Jan 2015 22:36:06 +0000 (22:36 +0000)
The compiler converts 'val, ok = m[key]' to

        tmp, ok = <runtime call>
        val = *tmp

For lookups of the form '_, ok = m[key]',
the second statement is unnecessary.
By not generating it we save a nil check.

Change-Id: I21346cc195cb3c62e041af8b18770c0940358695
Reviewed-on: https://go-review.googlesource.com/1975
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/gc/walk.c
test/nilcheck.go

index f54302dc28fa5fa97705fb2259366ed2f085b90c..48dd17a6af129c51ae23f62133f2456a047b699e 100644 (file)
@@ -794,8 +794,6 @@ walkexpr(Node **np, NodeList **init)
                //   var,b = mapaccess2*(t, m, i)
                //   a = *var
                a = n->list->n;
-               var = temp(ptrto(t->type));
-               var->typecheck = 1;
                fn = mapfn(p, t);
                r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key);
 
@@ -806,10 +804,17 @@ walkexpr(Node **np, NodeList **init)
                        r->type->type->down->type = n->list->next->n->type;
                n->rlist = list1(r);
                n->op = OAS2FUNC;
-               n->list->n = var;
-               walkexpr(&n, init);
-               *init = list(*init, n);
-               n = nod(OAS, a, nod(OIND, var, N));
+
+               // don't generate a = *var if a is _
+               if(!isblank(a)) {
+                       var = temp(ptrto(t->type));
+                       var->typecheck = 1;
+                       n->list->n = var;
+                       walkexpr(&n, init);
+                       *init = list(*init, n);
+                       n = nod(OAS, a, nod(OIND, var, N));
+               }
+
                typecheck(&n, Etop);
                walkexpr(&n, init);
                // mapaccess needs a zero value to be at least this big.
index fe05d05c9252904a25be7c8686cb8f514d36980f..99c3c5fdb6f150033d3eb2013b60cac015990187 100644 (file)
@@ -182,3 +182,8 @@ func f4(x *[10]int) {
        _ = &x[9] // ERROR "nil check"
 }
 
+func f5(m map[string]struct{}) bool {
+       // Existence-only map lookups should not generate a nil check
+       _, ok := m[""]
+       return ok
+}