summaryrefslogtreecommitdiff
path: root/src/cmd/gc/inl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/inl.c')
-rw-r--r--src/cmd/gc/inl.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c
index 1cc13a304..f77b51d70 100644
--- a/src/cmd/gc/inl.c
+++ b/src/cmd/gc/inl.c
@@ -188,6 +188,7 @@ ishairy(Node *n, int *budget)
break;
case OCLOSURE:
+ case OCALLPART:
case ORANGE:
case OFOR:
case OSELECT:
@@ -357,7 +358,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 +566,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 +798,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;
}