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

gccgo: oddity with export data and init functions #34618

Open
thanm opened this issue Sep 30, 2019 · 1 comment
Open

gccgo: oddity with export data and init functions #34618

thanm opened this issue Sep 30, 2019 · 1 comment
Assignees
Milestone

Comments

@thanm
Copy link
Member

@thanm thanm commented Sep 30, 2019

What version of Go are you using (go version)?

gccgo tip

$ go version
go version go1.13 gccgo (GCC) 10.0.0 20190916 (experimental) linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

Compile this package with gccgo:

package c

import "sort"

func init() {
	sort.Sort(byMaskLength(xpolicyTable))
}

type byMaskLength []policyTableEntry

func (s byMaskLength) Len() int           { return len(s) }
func (s byMaskLength) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
func (s byMaskLength) Less(i, j int) bool { return s[i].Label < s[j].Label }

type policyTableEntry struct {
	Label int
}

type policyTable []policyTableEntry

var xpolicyTable = policyTable{}

//go:noinline
func F() int {
	return xpolicyTable[0].Label
}

What did you expect to see?

Expected a single entry

func F () <type -11>

in the export data for the package, since that is the only exported identifier.

What did you see instead?

Export data includes the 'byMaskLength' type and its associated methods, which was a surprise.

I poked around at this and discovered that the lowering phase is running inlinabliity analysis on init functions, and it decides as part of this that the init() function is inlinable. This means that we include the types reachable from it in the export data (even though the init function itself is not emitted as an inline candidate.

@thanm thanm added this to the Gccgo milestone Sep 30, 2019
@thanm thanm self-assigned this Sep 30, 2019
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Oct 11, 2019

I think it's not just init functions. In this case the byMaskLength methods are themselves inlinable, so they are emitted into the export data, so byMaskLength is exported. The compiler doesn't currently distinguish between inlinable functions/methods and exported inlinable functions/methods.

Probably we need to mark all inlinable functions, exported or not, but then seed the list of inlinable functions passed to Collect_export_references with only the exported functions and exported methods of exported types. And mark those on the list so that we write out their function bodies. Then traverse them, and where we see references to other inlinable but not-yet-exported functions/methods, add those to the list too, and mark them to write out their function bodies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.