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

Optimization remarks #15242

Closed
wants to merge 5 commits into from
Closed

Optimization remarks #15242

wants to merge 5 commits into from

Conversation

gwenzek
Copy link
Sponsor Contributor

@gwenzek gwenzek commented Apr 10, 2023

Why

LLVM has the possibility of outputting detailed logs of which optimizations it tried to apply and which failed.
The feature is relatively unknown, but I found it pretty useful to understand what LLVM is actually doing on complex C++ code.
I propose to expose this LLVM feature in zig build-xxx.

References:
https://www.llvm.org/docs/Remarks.html
https://www.youtube.com/watch?v=qmEsx4MbKoc

Example

The default remark serializer implemented in LLVM generates a very verbose YAML file,
but one can use llvm "opt-viewer" to convert it to more readable html file merging the souce code and annotations.

Here is an example for the following simple Zig program:

const C = extern struct {
    m_cond: bool,
};

export fn method1(self: C) void {
    var i: u8 = 0;
    while (i < 5) : (i += 1) {
        if (self.m_cond)
            f();
    }
}

extern fn f() void;

image

Implememtation choices

llc exposes 5 flags for remarks:

  • -pass-remarks-output= Enables the serialization of remarks to a file specified in .
  • -pass-remarks-format= Specifies the output format of the serialized remarks. (default YAML)
  • -pass-remarks-filter= Only passes whose name match the given (POSIX) regular expression will be serialized to the final output.
  • -pass-remarks-with-hotness With PGO, include profile count in optimization remarks.
  • -pass-remarks-hotness-threshold The minimum profile count required for an optimization remark to be emitted.

I chose to only add an -femit-opt-remarks flag to Zig, mimicking -femit-asm or -femit-llvm-ir behavior.
The format is YAML by default with LLVM and the tools I saw to display the information seems to assume YAML.
This seems reasonable for a first iteration.
I'm not sure there is a lot of value of chosing at compile time which remarks should/shouldn't be written, I feel this filtering is better suited for the display stage. For info the remarks generated for Zig itself is a 600Mb yaml file.
Last;y AFAIK Zig doesn't have PGO support, and if it did the combination of PGO + remarks flag should default to include the PGO in the remarks.

Future work

Optimization remarks should also be collected during LTO.

@gwenzek
Copy link
Sponsor Contributor Author

gwenzek commented Apr 10, 2023

There was two issues with the first version of my PR, the first one is fixed, the second one seems a bit more complicated.

  • The destructor of the "RemarksStreamer" object was never called. The destructor is responsible for flushing the stream and closing the OS handle. I've added a handle to the LLVM.Object struct, and closing it into deinit.
  • The file names in the remarks are not complete: eg "std/io/reader.zig" just becomes "reader.zig" which makes it ambiguous and hard for downstream tools to identify the original file name.

@gwenzek
Copy link
Sponsor Contributor Author

gwenzek commented Jul 23, 2023

In the light of #16270, I don't think it makes sense to expose more LLVM optimization flags to main Zig CLI. I'll figure out a build.zig rule to expose this feature once #13265 is implemented.

@gwenzek gwenzek closed this Jul 23, 2023
@gwenzek gwenzek deleted the opt_remarks branch January 31, 2024 20:24
@gwenzek gwenzek restored the opt_remarks branch January 31, 2024 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant