aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/escape/escape.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/escape/escape.go')
-rw-r--r--src/cmd/compile/internal/escape/escape.go19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/escape/escape.go b/src/cmd/compile/internal/escape/escape.go
index c63383af43..bee3878f10 100644
--- a/src/cmd/compile/internal/escape/escape.go
+++ b/src/cmd/compile/internal/escape/escape.go
@@ -126,6 +126,11 @@ type location struct {
edges []edge // incoming edges
loopDepth int // loopDepth at declaration
+ // resultIndex records the tuple index (starting at 1) for
+ // PPARAMOUT variables within their function's result type.
+ // For non-PPARAMOUT variables it's 0.
+ resultIndex int
+
// derefs and walkgen are used during walkOne to track the
// minimal dereferences from the walk root.
derefs int // >= -1
@@ -259,11 +264,16 @@ func (b *batch) initFunc(fn *ir.Func) {
}
// Allocate locations for local variables.
- for _, dcl := range fn.Dcl {
- if dcl.Op() == ir.ONAME {
- e.newLoc(dcl, false)
+ for _, n := range fn.Dcl {
+ if n.Op() == ir.ONAME {
+ e.newLoc(n, false)
}
}
+
+ // Initialize resultIndex for result parameters.
+ for i, f := range fn.Type().Results().FieldSlice() {
+ e.oldLoc(f.Nname.(*ir.Name)).resultIndex = 1 + i
+ }
}
func (b *batch) walkFunc(fn *ir.Func) {
@@ -1609,8 +1619,7 @@ func (l *location) leakTo(sink *location, derefs int) {
// If sink is a result parameter and we can fit return bits
// into the escape analysis tag, then record a return leak.
if sink.isName(ir.PPARAMOUT) && sink.curfn == l.curfn {
- // TODO(mdempsky): Eliminate dependency on Vargen here.
- ri := int(sink.n.Name().Vargen) - 1
+ ri := sink.resultIndex - 1
if ri < numEscResults {
// Leak to result parameter.
l.paramEsc.AddResult(ri, derefs)