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

Add generator driver cache to VBCSCompiler #55023

Merged
merged 7 commits into from
Aug 31, 2021

Conversation

chsienki
Copy link
Contributor

  • Create a new cache type
  • Make the compiler optionally take it
  • Pass in the cache when running on the server
  • Check the cache (if there is one) for a generator driver before creating a new one

This enables incrementalism in the compiler server so that subsequent command line builds will be faster when using incremental generators.

- Create a new cache type
- Make the compiler optionally take it
- Pass in the cache when running on the server
- Check the cache (if there is one) for a generator driver before creating a new one
@chsienki
Copy link
Contributor Author

My other concern here is misbehaving generators. If they store global state / do shenanigans they can effectively cause incremental builds to start failing. I think I'm ok with it, because we can always tell the user to not use the compiler server (or say 'dont use that generator' its broken) to get back to a good compilation state.

@chsienki
Copy link
Contributor Author

@dotnet/roslyn-compiler for review please

@333fred
Copy link
Member

333fred commented Jul 23, 2021

Done review pass (commit 1)

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

LGTM (commit 4)

@chsienki
Copy link
Contributor Author

Ping @dotnet/roslyn-compiler for a second review please

@sharwell
Copy link
Member

sharwell commented Jul 30, 2021

Really would like to see an MSBuild property capable of bypassing this cache...

Edit: Looks like /features:disable-generator-cache can be passed to the compiler with a bit of gymnastics for command line usage but kinda works.

RunWithCacheDisabled();
Assert.Equal(3, sourceCallbackCount);

// Clean up temp files
Copy link
Member

Choose a reason for hiding this comment

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

//

Consider clearing the cache and testing RunWithCacheDisabled(); then checking that the cache is still empty. (It wasn't clear from the calls above whether RunWithCacheDisabled() updates the cache even though it ignores the cache for getting a generator.)

@sharwell sharwell changed the title Add generator drive cache to VBCSCompiler: Add generator driver cache to VBCSCompiler Jul 30, 2021
src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs Outdated Show resolved Hide resolved
@@ -734,7 +736,45 @@ public virtual int Run(TextWriter consoleOutput, CancellationToken cancellationT
/// <param name="additionalTexts">Any additional texts that should be passed to the generators when run.</param>
/// <param name="generatorDiagnostics">Any diagnostics that were produced during generation</param>
/// <returns>A compilation that represents the original compilation with any additional, generated texts added to it.</returns>
private protected virtual Compilation RunGenerators(Compilation input, ParseOptions parseOptions, ImmutableArray<ISourceGenerator> generators, AnalyzerConfigOptionsProvider analyzerConfigOptionsProvider, ImmutableArray<AdditionalText> additionalTexts, DiagnosticBag generatorDiagnostics) { return input; }
private protected Compilation RunGenerators(Compilation input, ParseOptions parseOptions, ImmutableArray<ISourceGenerator> generators, AnalyzerConfigOptionsProvider analyzerConfigOptionsProvider, ImmutableArray<AdditionalText> additionalTexts, DiagnosticBag generatorDiagnostics)
Copy link
Member

Choose a reason for hiding this comment

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

One item I think that is missing here is a description of what is and is not valid to cache.

For example one invariant that must be true for this PR to be "safe" is that two different projects which have the same name and generators can re-use each others GeneratorDriver entries and that will not impact the correctness of the compilation. Given what we save in the driver today that should be safe. But surely there are some items that are not safe to save and it may be helpful to list them. Likely as a doc / doc comment on the GeneratorDriver itself.

@chsienki
Copy link
Contributor Author

@cston Any further feedback on this?

// Obviously that would remove the point of the cache, so we also key off of the output file name
// and output path so that collisions are unlikely and we'll usually get the correct cache for any
// given compilation.

PooledStringBuilder sb = PooledStringBuilder.GetInstance();
sb.Builder.Append(Arguments.GetOutputFilePath(Arguments.OutputFileName));
Copy link
Member

Choose a reason for hiding this comment

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

Were we going to add the path + file name to make multi-target caching work better?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We already are, if you look at GetOuputFilePath

Co-authored-by: Charles Stoner <chucks@microsoft.com>
@chsienki chsienki enabled auto-merge (squash) August 31, 2021 16:48
@chsienki chsienki merged commit e01c311 into dotnet:main Aug 31, 2021
@ghost ghost added this to the Next milestone Aug 31, 2021
@chsienki chsienki deleted the source-generators/vbcs_incrmental branch August 31, 2021 18:25
@dibarbet dibarbet modified the milestones: Next, 17.0.P4 Aug 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants