Skip to content

compiler: no stack allocation for varargs that don't escape #4604

Open
@eliasnaur

Description

@eliasnaur

Test:

package main

import "testing"

func TestContentAllocs(t *testing.T) {
	res := testing.Benchmark(func(b *testing.B) {
		for range b.N {
			callVariadicString()
			callVariadicStruct()
		}
	})
	if a := res.AllocsPerOp(); a > 0 {
		t.Errorf("%d allocs, expected 0", a)
	}
}

var sink bool
var sink2 string
var sink3 SomeStruct

type SomeStruct struct {
	v int
}

func callVariadicStruct() {
	variadic(new(SomeStruct))
}

func callVariadicString() {
	str := "hi"
	if sink {
		str = "somethingelse"
	}
	variadic(str)
}

//go:noinline
func variadic(args ...any) {
	for _, a := range args {
		switch a := a.(type) {
		case string:
			sink2 = a
		case *SomeStruct:
			sink3 = *a
		}
	}
}

Tests

$ go test -gcflags=-l      # disable inlining
PASS
ok  	example.com	1.815s
$ tinygo test -opt 2
--- FAIL: TestContentAllocs (2.18s)
    2 allocs, expected 0
FAIL
FAIL	example.com	2.384s

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions