Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: missed devirtualization #51554

Open
CAFxX opened this issue Mar 9, 2022 · 0 comments
Open

cmd/compile: missed devirtualization #51554

CAFxX opened this issue Mar 9, 2022 · 0 comments
Labels
NeedsInvestigation Performance
Milestone

Comments

@CAFxX
Copy link
Contributor

@CAFxX CAFxX commented Mar 9, 2022

In the following snippet, the compiler should be able to devirtualize the fi.Foo() call, but currently this does not happen (godbolt):

package main

import "fmt"

type foo struct{}

func (_ foo) Foo() { fmt.Println("Foo") }

func main() {
	f := foo{}
	switch fi := any(f).(type) {
	case interface{ Foo() }:
		fi.Foo()
	}
}

The example is obviously artificial, but this definitely occurs in real code: e.g. see the code generated by envoyproxy/protoc-gen-validate, e.g. https://github.com/envoyproxy/go-control-plane/blob/99c9ceb26c9d7bf1705833b7debdebe9ae67c0ae/envoy/data/tap/v2alpha/transport.pb.validate.go.

Another use case that will become increasingly important with generics in 1.18 is to distinguish1 between different types provided in type unions, e.g.:

func Foo[Bytes interface{ []byte | string }](b Bytes) string {
	switch any(b).(type) {
	case []byte:
		return "[]byte"
	case string:
		return "string"
	}
    return "<unknown>"
}

As above, this missed devirtualization opportunity currently prevents (godbolt) the compiler from statically deducing the correct branch at compile-time, and pruning the dead branches.

This is somewhat related to #38992 in that also in this specific case it would be beneficial to run inlining again after devirtualization. For example, in the first example above, inlining after devirtualization would open up significant inlining opportunities in case an embedded message does not have validation rules (in which case its Validate* functions would simply return nil, potentially allowing to prune whole branches of the validation call tree)

Footnotes

  1. AFAICT this wouldn't currently be possible if the type constraint includes approximation elements (~T); the example does not use approximation elements for this reason

@ALTree ALTree added this to the Unplanned milestone Mar 9, 2022
@ALTree ALTree added the NeedsInvestigation label Mar 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Performance
Projects
None yet
Development

No branches or pull requests

2 participants