mirror of https://github.com/golang/go.git
cmd/gc: avoid duplicate allocation during inlining
Fixes #4667. R=ken2 CC=golang-dev https://golang.org/cl/7275046
This commit is contained in:
parent
fc6b530f0f
commit
a72f9f46a2
|
|
@ -266,6 +266,8 @@ gen(Node *n)
|
|||
Label *lab;
|
||||
int32 wasregalloc;
|
||||
|
||||
//dump("gen", n);
|
||||
|
||||
lno = setlineno(n);
|
||||
wasregalloc = anyregalloc();
|
||||
|
||||
|
|
|
|||
|
|
@ -553,6 +553,8 @@ mkinlcall1(Node **np, Node *fn, int isddd)
|
|||
|
||||
ninit = n->ninit;
|
||||
|
||||
//dumplist("ninit pre", ninit);
|
||||
|
||||
if (fn->defn) // local function
|
||||
dcl = fn->defn->dcl;
|
||||
else // imported function
|
||||
|
|
@ -566,7 +568,8 @@ mkinlcall1(Node **np, Node *fn, int isddd)
|
|||
ll->n->inlvar = inlvar(ll->n);
|
||||
// Typecheck because inlvar is not necessarily a function parameter.
|
||||
typecheck(&ll->n->inlvar, Erv);
|
||||
ninit = list(ninit, nod(ODCL, ll->n->inlvar, N)); // otherwise gen won't emit the allocations for heapallocs
|
||||
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);
|
||||
}
|
||||
|
|
@ -733,6 +736,7 @@ mkinlcall1(Node **np, Node *fn, int isddd)
|
|||
body = list(body, nod(OLABEL, inlretlabel, N));
|
||||
|
||||
typechecklist(body, Etop);
|
||||
//dumplist("ninit post", ninit);
|
||||
|
||||
call = nod(OINLCALL, N, N);
|
||||
call->ninit = ninit;
|
||||
|
|
@ -742,6 +746,7 @@ mkinlcall1(Node **np, Node *fn, int isddd)
|
|||
call->typecheck = 1;
|
||||
|
||||
setlno(call, n->lineno);
|
||||
//dumplist("call body", body);
|
||||
|
||||
*np = call;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
// run
|
||||
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var globl *int
|
||||
|
||||
func G() {
|
||||
F()
|
||||
}
|
||||
|
||||
func F() {
|
||||
var x int
|
||||
globl = &x
|
||||
}
|
||||
|
||||
func main() {
|
||||
nf := testing.AllocsPerRun(100, F)
|
||||
ng := testing.AllocsPerRun(100, G)
|
||||
if int(nf) != 1 {
|
||||
fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
|
||||
os.Exit(1)
|
||||
}
|
||||
if int(ng) != 1 {
|
||||
fmt.Printf("AllocsPerRun(100, G) = %v, want 1\n", ng)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue