]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: don't emit write barriers for *tmp if tmp=&PAUTO
authorDmitry Vyukov <dvyukov@google.com>
Mon, 26 Jan 2015 14:19:00 +0000 (17:19 +0300)
committerDmitry Vyukov <dvyukov@google.com>
Tue, 27 Jan 2015 18:09:29 +0000 (18:09 +0000)
This is another case where we can say that the address refers to stack.
We create such temps for OSTRUCTLIT initialization.

This eliminates a handful of write barriers today.
But this come up a prerequisite for another change (capturing vars by value),
otherwise we emit writebarriers in writebarrier itself when
capture writebarrier arguments by value.

Change-Id: Ibba93acd0f5431c5a4c3d90ef1e622cb9a7ff50e
Reviewed-on: https://go-review.googlesource.com/3285
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c

index 3727fdde9ce6712d354434cf2d21517171140822..c71cee9b87d7fbb3b53cf57fbf5c1c8d90f27650 100644 (file)
@@ -1666,6 +1666,9 @@ reswitch:
        case OAS:
                ok |= Etop;
                typecheckas(n);
+               // Code that creates temps does not bother to set defn, so do it here.
+               if(n->left->op == ONAME && strncmp(n->left->sym->name, "autotmp_", 8) == 0)
+                       n->left->defn = n;
                goto ret;
 
        case OAS2:
index b1d1bdd3369e171f09ca4cabc411e34cb28aaec6..c5901b799e08dba0ca6ff5e42dff092339f483e5 100644 (file)
@@ -1920,9 +1920,19 @@ callnew(Type *t)
 static int
 isstack(Node *n)
 {
+       Node *defn;
+
        while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
                n = n->left;
-       
+
+       // If n is *autotmp and autotmp = &foo, replace n with foo.
+       // We introduce such temps when initializing struct literals.
+       if(n->op == OIND && n->left->op == ONAME && strncmp(n->left->sym->name, "autotmp_", 8) == 0) {
+               defn = n->left->defn;
+               if(defn != N && defn->op == OAS && defn->right->op == OADDR)
+                       n = defn->right->left;
+       }
+
        switch(n->op) {
        case OINDREG:
                // OINDREG only ends up in walk if it's indirect of SP.