diff options
author | Russ Cox <rsc@golang.org> | 2014-02-13 19:59:09 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-02-13 19:59:09 -0500 |
commit | 627d914dff9f9b31d835a6aaa57073364c13638a (patch) | |
tree | 6f45bea4f8f604dd9313cb582c5550478d81de1f /src | |
parent | 21040f3f52f99a0fff5a3a7a707352f7a32b5e93 (diff) | |
download | go-627d914dff9f9b31d835a6aaa57073364c13638a.tar.gz |
cmd/gc: relax address-of escape analysis
Make the loop nesting depth of &x depend on where x is declared,
not on where the &x appears. The latter is only a conservative
estimate of the former. Being more careful can avoid some
variables escaping, and it is easier to reason about.
It would have avoided issue 7313, although that was still a bug
worth fixing.
Not much effect in the tree: one variable in the whole tree
is saved from a heap allocation (something in x509 parsing).
LGTM=daniel.morsing
R=daniel.morsing
CC=golang-codereviews
https://codereview.appspot.com/62380043
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/gc/esc.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c index c038dfc58..5a1a9ed21 100644 --- a/src/cmd/gc/esc.c +++ b/src/cmd/gc/esc.c @@ -328,6 +328,7 @@ escfunc(EscState *e, Node *func) ll->n->escloopdepth = 0; break; case PPARAM: + ll->n->escloopdepth = 1; if(ll->n->type && !haspointers(ll->n->type)) break; if(curfn->nbody == nil && !curfn->noescape) @@ -335,7 +336,6 @@ escfunc(EscState *e, Node *func) else ll->n->esc = EscNone; // prime for escflood later e->noesc = list(e->noesc, ll->n); - ll->n->escloopdepth = 1; break; } } @@ -630,7 +630,6 @@ esc(EscState *e, Node *n) escassign(e, n, a); } // fallthrough - case OADDR: case OMAKECHAN: case OMAKEMAP: case OMAKESLICE: @@ -639,6 +638,24 @@ esc(EscState *e, Node *n) n->esc = EscNone; // until proven otherwise e->noesc = list(e->noesc, n); break; + + case OADDR: + n->esc = EscNone; // until proven otherwise + e->noesc = list(e->noesc, n); + // current loop depth is an upper bound on actual loop depth + // of addressed value. + n->escloopdepth = e->loopdepth; + // for &x, use loop depth of x. + if(n->left->op == ONAME) { + switch(n->left->class) { + case PAUTO: + case PPARAM: + case PPARAMOUT: + n->escloopdepth = n->left->escloopdepth; + break; + } + } + break; } lineno = lno; |