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: unnecessary hash/eq functions for global arrays #30528

Open
dsnet opened this Issue Mar 1, 2019 · 4 comments

Comments

Projects
None yet
4 participants
@dsnet
Copy link
Member

dsnet commented Mar 1, 2019

This is a generalization of the problem described in #30449.

Suppose we have a unexported global variable:

var myArray [4]T

and none of the operations performed on this array:

  • let the array itself escape from the package (implies that the variable is unexported)
  • rely on comparability of the array (e.g., use of == or as a map key)

For example, operations like indexing (e.g., myArray[3]) and slicing (e.g., myArray[:]) are permitted.

If the above conditions are met, I believe that hash/eq functions need not be generated for that array since it is provably not used in the package, and cannot be used dynamically since the array itself does not escape from the package.


The use case for this is code like:

var globalMessageTypes [2]protoimpl.MesageType // Desire no hash/eq functions for this type

func (T) Type() protoreflect.MessageType {
    return &globalMessageTypes[0]
}

func (R) Type() protoreflect.MessageType {
    return &globalMessageTypes[1]
}

func init() {
    for i := range ... {
        globalMessageTypes[i] = ...
    }
}

We declare globalMessageTypes as an array so that the T.Type and R.Type methods do not need a bounds check when indexing into the global array. However, the generated hash/eq functions add significant binary bloat.

The workaround to this is to use a global slice instead of an array, but that has other issues (see #30529).

@cherrymui

This comment has been minimized.

Copy link
Contributor

cherrymui commented Mar 2, 2019

However, the generated hash/eq functions add significant binary bloat.

Are you talking about the binary size of the executable? Or the object file? I would think the linker deadcode eliminates the hash/eq functions if they are not called.

@cherrymui

This comment has been minimized.

Copy link
Contributor

cherrymui commented Mar 2, 2019

That said, we probably should fix the compiler to not generate them in the first place.

@dsnet

This comment has been minimized.

Copy link
Member Author

dsnet commented Mar 3, 2019

Are you talking about the binary size of the executable? Or the object file?

Definitely object file, not sure about binary. The issue @neild and I were running into was that the linker was OOMing. There are many reasons for an OOM, but one contributor were (presumably) the size of the object file inputs, for which the hash/eq functions were a non-trivial contributor of bloat.

@josharian

This comment has been minimized.

Copy link
Contributor

josharian commented Mar 3, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.