diff options
author | 2017-04-19 20:32:01 +0200 | |
---|---|---|
committer | 2017-04-20 11:07:45 +0200 | |
commit | 916a432990e75519f002e970c57c060a878f3fc3 (patch) | |
tree | 09c8a6bade819639238570760e99d18a07e78812 | |
parent | f9efa42113c5bcf0aaadb73fbc3822b389cc5c96 (diff) |
Prepare dynamic LIPO transitions.
Add a dynamic equivalent for LIPO_COLLECTOR transition.
Rename LipoDataTransition (which handles DATA transition) to DisableLipoTransition. A future change will add a corresponding EnableLipoTransition (which will model TARGET_CONFIG_FOR_LIPO).
PiperOrigin-RevId: 153611898
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/DisableLipoTransition.java (renamed from src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/LipoDataTransition.java) | 40 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/LipoContextCollectorTransition.java | 55 | ||||
-rw-r--r-- | src/test/java/com/google/devtools/build/lib/rules/cpp/LipoTransitionsTest.java | 214 |
3 files changed, 283 insertions, 26 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/LipoDataTransition.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/DisableLipoTransition.java index d9b9ae06dc..c6314971c2 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/LipoDataTransition.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/DisableLipoTransition.java @@ -14,51 +14,39 @@ package com.google.devtools.build.lib.rules.cpp.transitions; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.PatchTransition; import com.google.devtools.build.lib.rules.cpp.CppOptions; -import com.google.devtools.build.lib.rules.cpp.FdoSupport; -import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode; /** - * Dynamic transition that turns off LIPO/FDO settings. + * Configuration transition that turns off LIPO/FDO settings. + * + * <p>Has no effect on non-LIPO-enabled configurations or the LIPO context collector + * configuration. * - * <p>This is suitable, for example, when visiting data dependencies of a C++ rule built with LIPO. */ -public final class LipoDataTransition implements PatchTransition { - public static final LipoDataTransition INSTANCE = new LipoDataTransition(); +public final class DisableLipoTransition implements PatchTransition { + public static final DisableLipoTransition INSTANCE = new DisableLipoTransition(); - private LipoDataTransition() {} + private DisableLipoTransition() {} @Override public BuildOptions apply(BuildOptions options) { - if (options.get(BuildConfiguration.Options.class).isHost) { - return options; - } - // If this target and its transitive closure don't have C++ options, there's no // LIPO context to change. if (!options.contains(CppOptions.class)) { return options; } - CppOptions cppOptions = options.get(CppOptions.class); - if (cppOptions.getLipoMode() == CrosstoolConfig.LipoMode.OFF) { - return options; - } - options = options.clone(); - cppOptions = options.get(CppOptions.class); - - // Once autoFdoLipoData is on, it stays on (through all future transitions). - if (!cppOptions.getAutoFdoLipoData() && cppOptions.getFdoOptimize() != null) { - cppOptions.autoFdoLipoDataForBuild = FdoSupport.isAutoFdo(cppOptions.getFdoOptimize()); + if (cppOptions.getLipoMode() == LipoMode.OFF || cppOptions.isLipoContextCollector()) { + return options; } - cppOptions.lipoModeForBuild = CrosstoolConfig.LipoMode.OFF; - cppOptions.fdoInstrumentForBuild = null; - cppOptions.fdoOptimizeForBuild = null; - return options; + BuildOptions lipoDisabledOptions = options.clone(); + lipoDisabledOptions.get(CppOptions.class).lipoConfigurationState = + CppOptions.LipoConfigurationState.IGNORE_LIPO; + return lipoDisabledOptions; } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/LipoContextCollectorTransition.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/LipoContextCollectorTransition.java new file mode 100644 index 0000000000..1259c7534c --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/transitions/LipoContextCollectorTransition.java @@ -0,0 +1,55 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.rules.cpp.transitions; + +import com.google.devtools.build.lib.analysis.config.BuildOptions; +import com.google.devtools.build.lib.analysis.config.PatchTransition; +import com.google.devtools.build.lib.rules.cpp.CppOptions; +import com.google.devtools.build.lib.rules.cpp.FdoSupport; + +/** + * Configuration transition that enters "LIPO context collector" mode on a + * "LIPO optimization"-enabled input configuration. + * + * <p>See {@link FdoSupport} for details. + */ +public class LipoContextCollectorTransition implements PatchTransition { + public static final LipoContextCollectorTransition INSTANCE = + new LipoContextCollectorTransition(); + + private LipoContextCollectorTransition() {} + + @Override + public BuildOptions apply(BuildOptions options) { + // If this target and its transitive closure don't have C++ options, there's no + // LIPO context to change. + if (!options.contains(CppOptions.class)) { + return options; + } + CppOptions cppOptions = options.get(CppOptions.class); + if (!cppOptions.isLipoOptimization()) { + return options; + } + BuildOptions collectorOptions = options.clone(); + collectorOptions.get(CppOptions.class).lipoConfigurationState = + CppOptions.LipoConfigurationState.LIPO_CONTEXT_COLLECTOR; + return collectorOptions; + } + + @Override + public boolean defaultsToSelf() { + return false; + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/LipoTransitionsTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/LipoTransitionsTest.java new file mode 100644 index 0000000000..0b1d7239af --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/LipoTransitionsTest.java @@ -0,0 +1,214 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.rules.cpp; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.analysis.config.BuildOptions; +import com.google.devtools.build.lib.analysis.config.PatchTransition; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.rules.cpp.transitions.DisableLipoTransition; +import com.google.devtools.build.lib.rules.cpp.transitions.LipoContextCollectorTransition; +import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.LipoMode; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests LIPO-related configuration transitions. + **/ +@RunWith(JUnit4.class) +public class LipoTransitionsTest extends BuildViewTestCase { + + private void useLipoOptimizationConfig() throws Exception { + useConfiguration( + "--compilation_mode=opt", + "--fdo_optimize=profile.zip", + "--lipo_context=//foo", + "--lipo=binary"); + } + + private CppOptions doTransition(PatchTransition transition, BuildOptions fromOptions) { + return transition.apply(fromOptions).get(CppOptions.class); + } + + @Test + public void expectedTargetConfig() throws Exception { + useLipoOptimizationConfig(); + CppOptions targetOptions = getTargetConfiguration().getOptions().get(CppOptions.class); + assertThat(targetOptions.isFdo()).isTrue(); + assertThat(targetOptions.isLipoOptimization()).isTrue(); + assertThat(targetOptions.isLipoOptimizationOrInstrumentation()).isTrue(); + assertThat(targetOptions.isLipoContextCollector()).isFalse(); + assertThat(targetOptions.getLipoContext()).isEqualTo(Label.parseAbsoluteUnchecked("//foo")); + assertThat(targetOptions.getLipoContextForBuild()) + .isEqualTo(Label.parseAbsoluteUnchecked("//foo")); + assertThat(targetOptions.getLipoMode()).isEqualTo(LipoMode.BINARY); + } + + @Test + public void disableLipoFromTargetConfig() throws Exception { + useLipoOptimizationConfig(); + CppOptions toOptions = + doTransition(DisableLipoTransition.INSTANCE, getTargetConfiguration().getOptions()); + assertThat(toOptions).isNotEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + assertThat(toOptions.isFdo()).isFalse(); + assertThat(toOptions.isLipoOptimization()).isFalse(); + assertThat(toOptions.isLipoOptimizationOrInstrumentation()).isFalse(); + assertThat(toOptions.isLipoContextCollector()).isFalse(); + assertThat(toOptions.getLipoContext()).isNull(); + assertThat(toOptions.getLipoContextForBuild()).isEqualTo(Label.parseAbsoluteUnchecked("//foo")); + assertThat(toOptions.getLipoMode()).isEqualTo(LipoMode.OFF); + } + + @Test + public void disableLipoFromContextCollectorConfig() throws Exception { + useLipoOptimizationConfig(); + BuildOptions contextCollectorOptions = + LipoContextCollectorTransition.INSTANCE.apply(getTargetConfiguration().getOptions()); + CppOptions toOptions = doTransition(DisableLipoTransition.INSTANCE, contextCollectorOptions); + assertThat(toOptions).isEqualTo(contextCollectorOptions.get(CppOptions.class)); + } + + @Test + public void disableLipoFromAlreadyDisabledConfig() throws Exception { + useLipoOptimizationConfig(); + BuildOptions dataOptions = + DisableLipoTransition.INSTANCE.apply(getTargetConfiguration().getOptions()); + CppOptions toOptions = doTransition(DisableLipoTransition.INSTANCE, dataOptions); + assertThat(toOptions).isEqualTo(dataOptions.get(CppOptions.class)); + } + + @Test + public void disableLipoFromHostConfig() throws Exception { + useLipoOptimizationConfig(); + CppOptions toOptions = + doTransition(DisableLipoTransition.INSTANCE, getHostConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getHostConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void disableLipoNoFdoBuild() throws Exception { + useConfiguration(); + CppOptions toOptions = + doTransition(DisableLipoTransition.INSTANCE, getTargetConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void disableLipoFdoInstrumentBuild() throws Exception { + useConfiguration("--fdo_instrument=profile.zip"); + CppOptions toOptions = + doTransition(DisableLipoTransition.INSTANCE, getTargetConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void disableLipoFdoOptimizeBuild() throws Exception { + useConfiguration("--fdo_optimize=profile.zip"); + CppOptions toOptions = + doTransition(DisableLipoTransition.INSTANCE, getTargetConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void disableLipoLipoInstrumentBuild() throws Exception { + useConfiguration("--fdo_instrument=profile.zip", "--lipo=binary", "--compilation_mode=opt"); + CppOptions toOptions = + doTransition(DisableLipoTransition.INSTANCE, getTargetConfiguration().getOptions()); + assertThat(toOptions).isNotEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + assertThat(toOptions.isFdo()).isFalse(); + assertThat(toOptions.isLipoOptimization()).isFalse(); + assertThat(toOptions.isLipoOptimizationOrInstrumentation()).isFalse(); + assertThat(toOptions.isLipoContextCollector()).isFalse(); + assertThat(toOptions.getLipoContext()).isNull(); + assertThat(toOptions.getLipoContextForBuild()).isNull(); + assertThat(toOptions.getLipoMode()).isEqualTo(LipoMode.OFF); + } + + @Test + public void contextCollectorFromTargetConfig() throws Exception { + useLipoOptimizationConfig(); + CppOptions toOptions = doTransition(LipoContextCollectorTransition.INSTANCE, + getTargetConfiguration().getOptions()); + assertThat(toOptions).isNotEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + assertThat(toOptions.isFdo()).isTrue(); + assertThat(toOptions.isLipoOptimization()).isFalse(); + assertThat(toOptions.isLipoOptimizationOrInstrumentation()).isFalse(); + assertThat(toOptions.isLipoContextCollector()).isTrue(); + assertThat(toOptions.getLipoContext()).isNull(); + assertThat(toOptions.getLipoContextForBuild()).isEqualTo(Label.parseAbsoluteUnchecked("//foo")); + assertThat(toOptions.getLipoMode()).isEqualTo(LipoMode.BINARY); + } + + @Test + public void contextCollectorFromContextCollectorConfig() throws Exception { + useLipoOptimizationConfig(); + BuildOptions contextCollectorOptions = + LipoContextCollectorTransition.INSTANCE.apply(getTargetConfiguration().getOptions()); + CppOptions toOptions = + doTransition(LipoContextCollectorTransition.INSTANCE, contextCollectorOptions); + assertThat(toOptions).isEqualTo(contextCollectorOptions.get(CppOptions.class)); + } + + @Test + public void contextCollectorFromDataConfig() throws Exception { + useLipoOptimizationConfig(); + BuildOptions dataOptions = + DisableLipoTransition.INSTANCE.apply(getTargetConfiguration().getOptions()); + CppOptions toOptions = doTransition(LipoContextCollectorTransition.INSTANCE, dataOptions); + assertThat(toOptions).isEqualTo(dataOptions.get(CppOptions.class)); + } + + @Test + public void contextCollectorFromHostConfig() throws Exception { + useLipoOptimizationConfig(); + CppOptions toOptions = + doTransition(LipoContextCollectorTransition.INSTANCE, getHostConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getHostConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void contextCollectorNoFdoBuild() throws Exception { + useConfiguration(); + CppOptions toOptions = doTransition(LipoContextCollectorTransition.INSTANCE, + getTargetConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void contextCollectorFdoInstrumentBuild() throws Exception { + useConfiguration("--fdo_instrument=profile.zip"); + CppOptions toOptions = doTransition(LipoContextCollectorTransition.INSTANCE, + getTargetConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void contextCollectorFdoOptimizeBuild() throws Exception { + useConfiguration("--fdo_optimize=profile.zip"); + CppOptions toOptions = doTransition(LipoContextCollectorTransition.INSTANCE, + getTargetConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + } + + @Test + public void contextCollectorLipoInstrumentBuild() throws Exception { + useConfiguration("--fdo_instrument=profile.zip", "--lipo=binary", "--compilation_mode=opt"); + CppOptions toOptions = doTransition(LipoContextCollectorTransition.INSTANCE, + getTargetConfiguration().getOptions()); + assertThat(toOptions).isEqualTo(getTargetConfiguration().getOptions().get(CppOptions.class)); + } +} |