diff options
Diffstat (limited to 'src/cmd/gc/inl.c')
-rw-r--r-- | src/cmd/gc/inl.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c index 1cc13a304..850bb36ec 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -357,7 +357,7 @@ inlnode(Node **np) } case OCLOSURE: - // TODO do them here (or earlier) instead of in walkcallclosure, + // TODO do them here (or earlier), // so escape analysis can avoid more heapmoves. return; } @@ -565,24 +565,31 @@ mkinlcall1(Node **np, Node *fn, int isddd) inlretvars = nil; i = 0; // Make temp names to use instead of the originals - for(ll = dcl; ll; ll=ll->next) + for(ll = dcl; ll; ll=ll->next) { + if(ll->n->class == PPARAMOUT) // return values handled below. + continue; if(ll->n->op == ONAME) { ll->n->inlvar = inlvar(ll->n); // Typecheck because inlvar is not necessarily a function parameter. typecheck(&ll->n->inlvar, Erv); if ((ll->n->class&~PHEAP) != PAUTO) ninit = list(ninit, nod(ODCL, ll->n->inlvar, N)); // otherwise gen won't emit the allocations for heapallocs - if (ll->n->class == PPARAMOUT) // we rely on the order being correct here - inlretvars = list(inlretvars, ll->n->inlvar); } + } - // anonymous return values, synthesize names for use in assignment that replaces return - if(inlretvars == nil && fn->type->outtuple > 0) - for(t = getoutargx(fn->type)->type; t; t = t->down) { + // temporaries for return values. + for(t = getoutargx(fn->type)->type; t; t = t->down) { + if(t != T && t->nname != N && !isblank(t->nname)) { + m = inlvar(t->nname); + typecheck(&m, Erv); + t->nname->inlvar = m; + } else { + // anonymous return values, synthesize names for use in assignment that replaces return m = retvar(t, i++); - ninit = list(ninit, nod(ODCL, m, N)); - inlretvars = list(inlretvars, m); } + ninit = list(ninit, nod(ODCL, m, N)); + inlretvars = list(inlretvars, m); + } // assign receiver. if(fn->type->thistuple && n->left->op == ODOTMETH) { @@ -790,6 +797,12 @@ inlvar(Node *var) n->class = PAUTO; n->used = 1; n->curfn = curfn; // the calling function, not the called one + + // esc pass wont run if we're inlining into a iface wrapper + // luckily, we can steal the results from the target func + if(var->esc == EscHeap) + addrescapes(n); + curfn->dcl = list(curfn->dcl, n); return n; } |