Cache the invocation of TestTrimmingTransition.applyTransition. This implementation uses the pre-existing BuildOptionsCache class inside TestTrimmingTransition to resolve the performance issue with --trim_test_configuration on longwide. (Previous attempts used a SkyFunction, a custom cache at ConfigurationResolve, or a custom cache at TestTrimmingTransition.) PiperOrigin-RevId: 329607319
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/BUILD index 1a26394..f367071 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/BUILD +++ b/src/main/java/com/google/devtools/build/lib/analysis/BUILD
@@ -2270,6 +2270,7 @@ srcs = ["test/TestTrimmingTransitionFactory.java"], deps = [ ":config/build_options", + ":config/build_options_cache", ":config/fragment_options", ":config/transitions/no_transition", ":config/transitions/patch_transition",
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java index a759b25..3faac3c 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/test/TestTrimmingTransitionFactory.java
@@ -15,6 +15,7 @@ import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.analysis.config.BuildOptions; +import com.google.devtools.build.lib.analysis.config.BuildOptionsCache; import com.google.devtools.build.lib.analysis.config.BuildOptionsView; import com.google.devtools.build.lib.analysis.config.FragmentOptions; import com.google.devtools.build.lib.analysis.config.transitions.NoTransition; @@ -42,6 +43,14 @@ public enum TestTrimmingTransition implements PatchTransition { INSTANCE; + // This cache is to prevent major slowdowns when using --trim_test_configuration. This + // transition is always invoked on every target in the top-level invocation. Thus, a wide + // invocation, like //..., will cause the transition to be invoked on a large number of targets + // leading to significant performance degradation. (Notably, the transition itself is somewhat + // fast; however, the post-processing of the BuildOptions results into a BuildConfiguration + // takes a significant amount of time). + private static final BuildOptionsCache<Integer> cache = new BuildOptionsCache<>(); + @Override public ImmutableSet<Class<? extends FragmentOptions>> requiresOptionFragments() { return ImmutableSet.of(TestOptions.class); @@ -58,9 +67,15 @@ // nothing to do, trimming is disabled return originalOptions.underlying(); } - return originalOptions.underlying().toBuilder() - .removeFragmentOptions(TestOptions.class) - .build(); + return cache.applyTransition( + originalOptions, + // The transition uses no non-BuildOptions arguments + 0, + () -> { + return originalOptions.underlying().toBuilder() + .removeFragmentOptions(TestOptions.class) + .build(); + }); } } @@ -75,7 +90,7 @@ } Set<String> referencedTestOptions = - new LinkedHashSet<String>(ruleClass.getOptionReferenceFunction().apply(rule)); + new LinkedHashSet<>(ruleClass.getOptionReferenceFunction().apply(rule)); referencedTestOptions.retainAll(TEST_OPTIONS); if (!referencedTestOptions.isEmpty()) { // Test-option-referencing config_setting; no need to trim here.