From: Dmitry Vyukov Date: Mon, 26 Jan 2015 14:19:00 +0000 (+0300) Subject: cmd/gc: don't emit write barriers for *tmp if tmp=&PAUTO X-Git-Tag: go1.5beta1~2258 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a7bb393628cbd6c5934e4bc34a45e1f0eabc908e;p=gostls13.git cmd/gc: don't emit write barriers for *tmp if tmp=&PAUTO 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 --- diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 3727fdde9c..c71cee9b87 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -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: diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index b1d1bdd336..c5901b799e 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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.