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

[clang] Introduce copy-on-write CompilerInvocation #65412

Merged
merged 1 commit into from
Sep 7, 2023

Conversation

jansvoboda11
Copy link
Contributor

@jansvoboda11 jansvoboda11 commented Sep 5, 2023

This PR introduces new copy-on-write CompilerInvocation class (CowCompilerInvocation), which will be used by the dependency scanner to reduce the number of copies performed when generating command lines for discovered modules.

@jansvoboda11 jansvoboda11 requested a review from a team as a code owner September 5, 2023 20:29
@github-actions github-actions bot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Sep 5, 2023
@benlangmuir
Copy link
Collaborator

I haven't dug into this in depth yet, but did you consider keeping the normal function names for the const versions and only rename the mutating ones? My thinking is you could use CowCompilerInvocation as a drop-in replacement for CompilerInvocation in immutable settings.

@jansvoboda11
Copy link
Contributor Author

I did, but decided against it. There are places in Clang where we store the result of the const function in some kind of long-lived data structure, and someplace else modify the result of the non-const function, expecting the change to be reflected.

I wanted to make the semantic difference clear on both ends in case someone was inclined to swap CompilerInvocation for CowCompilerInvocation. I'm not sure this is the best way to prevent misuse of the API, so I'm open to alternatives.

Note that you can use CompilerInvocationBase to get the behavior you're describing. I use it to implement generateCC1CommandLine(), but it's supposed to be used sparingly. Maybe putting it into some kind of detail namespace would communicate this even better, but that pollutes the friend declarations.

@benlangmuir
Copy link
Collaborator

There are places in Clang where we store the result of the const function in some kind of long-lived data structure, and someplace else modify the result of the non-const function, expecting the change to be reflected.

I would be comfortable with this, because you would still have to call a distinctly named function (getMut...) in order to do the mutation itself IIUC. If they are const-casting of course that wouldn't be enough.

Note that you can use CompilerInvocationBase to get the behavior you're describing.

I think CompilerInvocationBase goes a step farther than what I described, because it would give you the mutating methods with the original names, no?

@jansvoboda11
Copy link
Contributor Author

There are places in Clang where we store the result of the const function in some kind of long-lived data structure, and someplace else modify the result of the non-const function, expecting the change to be reflected.

I would be comfortable with this, because you would still have to call a distinctly named function (getMut...) in order to do the mutation itself IIUC. If they are const-casting of course that wouldn't be enough.

Ok, if you're fine with that, I'll use the original names for the const getters on CowCompilerInvocation.

Note that you can use CompilerInvocationBase to get the behavior you're describing.

I think CompilerInvocationBase goes a step farther than what I described, because it would give you the mutating methods with the original names, no?

No, CompilerInvocationBase doesn't have the mutating functions. RefBase and ValBase only expose the const getters. CompilerInvocationBase only adds the generate*() functions on top of those. The non-const getters are specific to CompilerInvocation and CowCompilerInvocation.

@jansvoboda11 jansvoboda11 changed the title [clang][deps] Optimize command line generation [clang] Introduce copy-on-write CompilerInvocation Sep 6, 2023
@jansvoboda11
Copy link
Contributor Author

I evicted a couple of commits from this PR in order to work better with the new GitHub PR "squash and merge" workflow. I'll create new PRs for the remaining commits.

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

GenerateFileSystemArgs(getFileSystemOpts(), Consumer);
GenerateMigratorArgs(getMigratorOpts(), Consumer);
GenerateAnalyzerArgs(getAnalyzerOpts(), Consumer);
GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer, false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer, false);
GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer, /*DefaultDiagColor=*/false);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in #65647.

clang/include/clang/Frontend/CompilerInvocation.h Outdated Show resolved Hide resolved
clang/include/clang/Frontend/CompilerInvocation.h Outdated Show resolved Hide resolved
clang/include/clang/Frontend/CompilerInvocation.h Outdated Show resolved Hide resolved
clang/include/clang/Frontend/CompilerInvocation.h Outdated Show resolved Hide resolved
clang/include/clang/Frontend/CompilerInvocation.h Outdated Show resolved Hide resolved
clang/lib/Frontend/CompilerInvocation.cpp Outdated Show resolved Hide resolved
clang/lib/Frontend/CompilerInvocation.cpp Outdated Show resolved Hide resolved
@jansvoboda11
Copy link
Contributor Author

Made the entirety of ValBase ref-counted in #65647, which also resolves some other comments here.

Copy link
Collaborator

@benlangmuir benlangmuir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This basically LGTM, but could we add some unit tests for the new type?

When adopted in the dependency scanner, this will speed up execution and reduce memory usage.
@jansvoboda11 jansvoboda11 merged commit e1cc299 into llvm:main Sep 7, 2023
1 of 2 checks passed
@jansvoboda11 jansvoboda11 deleted the cow-ci branch September 7, 2023 21:01
jansvoboda11 added a commit to apple/llvm-project that referenced this pull request Sep 12, 2023
This PR introduces new copy-on-write `CompilerInvocation` class
(`CowCompilerInvocation`), which will be used by the dependency scanner
to reduce the number of copies performed when generating command lines
for discovered modules.
jansvoboda11 added a commit to apple/llvm-project that referenced this pull request Oct 5, 2023
This PR introduces new copy-on-write `CompilerInvocation` class
(`CowCompilerInvocation`), which will be used by the dependency scanner
to reduce the number of copies performed when generating command lines
for discovered modules.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema"
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants