[Build] Skip unchanged CompileNativeAssembly files and stabilize typemap outputs#3
Closed
davidnguyen-tech wants to merge 3 commits intomainfrom
Closed
[Build] Skip unchanged CompileNativeAssembly files and stabilize typemap outputs#3davidnguyen-tech wants to merge 3 commits intomainfrom
davidnguyen-tech wants to merge 3 commits intomainfrom
Conversation
When _CompileNativeAssemblySources runs, it recompiles ALL .ll files even if only some have changed. This is because MSBuild's target-level Inputs/Outputs is all-or-nothing — if any .ll file is newer than any .o file, every file gets recompiled. Add a per-file timestamp check in RunAssembler() — if the output .o is newer than the input .ll, that file is skipped. This saves time on incremental CoreCLR builds where upstream generators use CopyIfStreamChanged to preserve .ll timestamps for unchanged files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add CompileNativeAssemblySourcesSkipsUnchangedFiles integration test that verifies on incremental CoreCLR builds, unchanged .ll files are not recompiled by the CompileNativeAssembly task while changed .ll files are still correctly compiled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove build-specific MVID data from the CoreCLR debug typemap assemblies array, making the generated .ll files byte-identical across incremental builds when only C# code changes (no type additions/removals). Generator changes (TypeMappingDebugNativeAssemblyGeneratorCLR.cs): - Remove mvid_hash field from TypeMapAssembly struct - Remove MVID field (was already NativeAssembler-ignored) - Sort data.UniqueAssemblies by name before building the assembly names blob, ensuring deterministic blob offsets - Sort uniqueAssemblies list by Name instead of mvid_hash Runtime changes (typemap.cc, xamarin-app.hh): - Remove mvid_hash from the native TypeMapAssembly struct - Replace MVID-based binary search with assembly iteration: for each assembly, construct "TypeName, AssemblyName" and look up in the managed-to-java map. The array is small (~80-100 entries), so iteration cost is negligible vs the previous hash+binary-search. This eliminates the root cause of typemaps.*.ll content changes during C#-only incremental edits. Combined with the per-file skip from commit d2f07a1, this saves ~2.85s per CoreCLR incremental build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Owner
Author
|
Superseded by dotnet#11055 (same branch in fork). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two complementary optimizations that together eliminate ~2.85s of unnecessary LLVM
llcrecompilation on incremental CoreCLR builds.Optimization 1: Per-file up-to-date check in CompileNativeAssembly
Adds per-file timestamp comparison in the
CompileNativeAssemblytask to skip recompilation of.llfiles whose.ooutput is already up-to-date. Before runningllcfor each source file inRunAssembler(), the task checks if the output.ofile exists and its last-write time is ≥ the input.llfile's last-write time. If so, the file is skipped with a debug log message:This preserves parallel compilation of changed files while skipping unchanged ones individually.
Optimization 2: Remove mvid_hash from TypeMapAssembly
Previously, typemap
.llfiles included amvid_hashfield computed from assembly MVIDs. Since MVIDs change on every rebuild (even when source is unchanged), this caused typemap.llfiles to be byte-different on every incremental build — defeating Optimization 1 for typemap object files.This commit removes the
mvid_hashfield and sorts typemap entries by assembly name instead. This makestypemaps.*.llfiles byte-identical across incremental builds when no assembly content changes, allowing Optimization 1 to skip their recompilation.Combined Impact
~2.85s saved per CoreCLR incremental build (measured on MAUI sample app). Without Optimization 2, only non-typemap
.llfiles benefit from the skip. With both optimizations, typemap.ll→.ocompilations are also skipped when assemblies are unchanged.Build Status
Testing
CompileNativeAssemblySourcesSkipsUnchangedFilesintegration test that verifies:_CompileNativeAssemblySourcestarget still runs (not skipped at target level).llfile is skipped at the per-file level (via log message assertion)