Skip to content

cmd/gc: duplicate allocation created by inlining #4667

@rsc

Description

@rsc
In the code below, BuildOutput{1,2,3} should all allocate twice - once for the int64 and
once for the Output struct, and they should continue to allocate twice (at most) after
being inlined into BenchmarkBuildOutput{1,2,3}. However, BenchmarkBuildOutput{2,3} show
3 allocations each, not 2. (That is, there are three calls to new in the function.) The
first two allocations are for int64 values, and the first allocation is discarded
entirely. This looks like the compiler is reevaluating "new(int64)" multiple
times, or something like that.

package foo

import (
    "testing"
)

const usec = 1005

type Output struct {
    TimestampMsec *int64
}

// -test.benchmem reports 2 allocs/op
func BuildOutput1(usec int64) *Output {
    msec := usec / 1e3
    p := new(int64)
    *p = msec
    return &Output{TimestampMsec: p}
}

// -test.benchmem reports 3 allocs/op
func BuildOutput2(usec int64) *Output {
    msec := usec / 1e3
    p := &msec
    return &Output{TimestampMsec: p}
}

// -test.benchmem reports 3 allocs/op
func BuildOutput3(usec int64) *Output {
    msec := usec / 1e3
    return &Output{TimestampMsec: &msec}
}

func BenchmarkBuildOutput1(b *testing.B) {
    for i := 0; i < b.N; i++ {
        BuildOutput1(usec)
    }
}

func BenchmarkBuildOutput2(b *testing.B) {
    for i := 0; i < b.N; i++ {
        BuildOutput2(usec)
    }
}

func BenchmarkBuildOutput3(b *testing.B) {
    for i := 0; i < b.N; i++ {
        BuildOutput3(usec)
    }
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions