aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Googler <noreply@google.com>2018-05-16 17:26:26 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-05-16 17:27:54 -0700
commitcc0f41dccc55bb1380b10cc65281632676192a8d (patch)
treedee53a4fd2c139e15e0f13d87b23d51a3de23953
parentc251ead49b1689984f32832047529e5469674c69 (diff)
Build support for passing a software cache prefetching hints file.
This flag assumes llvm supports an experimental 'prefetch-hints-flag' flag. The Bazel support simply plumbs the provided file through to the compiler. The flag is independent from the other fdo_ flags, and may be applied in any combination with them. RELNOTES: Introduce build support for providing cache prefetch hints. PiperOrigin-RevId: 196916547
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java47
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java17
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoInputFile.java103
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java42
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsProvider.java37
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsRule.java78
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java38
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java26
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java47
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportProvider.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportValue.java34
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/cpp/ProfileArtifacts.java43
20 files changed, 494 insertions, 90 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java
index b21b211871..be7f016365 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java
@@ -34,6 +34,7 @@ import com.google.devtools.build.lib.rules.cpp.CppConfigurationLoader;
import com.google.devtools.build.lib.rules.cpp.CppOptions;
import com.google.devtools.build.lib.rules.cpp.CppRuleClasses.CcIncludeScanningRule;
import com.google.devtools.build.lib.rules.cpp.CpuTransformer;
+import com.google.devtools.build.lib.rules.cpp.FdoPrefetchHintsRule;
import com.google.devtools.build.lib.rules.cpp.FdoProfileRule;
import com.google.devtools.build.lib.rules.platform.PlatformRules;
@@ -73,6 +74,7 @@ public class CcRules implements RuleSet {
builder.addRuleDefinition(new BazelCcImportRule());
builder.addRuleDefinition(new CcIncludeScanningRule());
builder.addRuleDefinition(new FdoProfileRule());
+ builder.addRuleDefinition(new FdoPrefetchHintsRule());
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
index ebf00f8eaf..21ccb4a116 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java
@@ -843,6 +843,9 @@ public final class CcCommon {
allFeatures.add(CppRuleClasses.ENABLE_AFDO_THINLTO);
}
}
+ if (cppConfiguration.getFdoPrefetchHintsLabel() != null) {
+ allRequestedFeaturesBuilder.add(CppRuleClasses.FDO_PREFETCH_HINTS);
+ }
if (cppConfiguration.isLipoOptimizationOrInstrumentation()) {
// Map LIPO to ThinLTO for LLVM builds.
if (toolchain.isLLVMCompiler() && fdoMode != FdoMode.OFF) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
index 5209e1c230..5dc9e75bf6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java
@@ -182,6 +182,29 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
return pathPrefix.getRelative(path);
}
+ private Artifact getPrefetchHintsArtifact(
+ FdoInputFile prefetchHintsFile, RuleContext ruleContext) {
+ Artifact prefetchHintsArtifact = null;
+ if (prefetchHintsFile != null) {
+ prefetchHintsArtifact = prefetchHintsFile.getArtifact();
+ if (prefetchHintsArtifact == null) {
+ prefetchHintsArtifact =
+ ruleContext.getUniqueDirectoryArtifact(
+ "fdo",
+ prefetchHintsFile.getAbsolutePath().getBaseName(),
+ ruleContext.getBinOrGenfilesDirectory());
+ ruleContext.registerAction(
+ new SymlinkAction(
+ ruleContext.getActionOwner(),
+ PathFragment.create(prefetchHintsFile.getAbsolutePath().getPathString()),
+ prefetchHintsArtifact,
+ "Symlinking LLVM Cache Prefetch Hints Profile "
+ + prefetchHintsFile.getAbsolutePath().getPathString()));
+ }
+ }
+ return prefetchHintsArtifact;
+ }
+
/*
* This function checks the format of the input profile data and converts it to
* the indexed format (.profdata) if necessary.
@@ -317,7 +340,14 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
CppToolchainInfo toolchainInfo = getCppToolchainInfo(ruleContext, cppConfiguration);
PathFragment fdoZip = null;
+ FdoInputFile prefetchHints = null;
if (configuration.getCompilationMode() == CompilationMode.OPT) {
+ if (cppConfiguration.getFdoPrefetchHintsLabel() != null) {
+ FdoPrefetchHintsProvider provider =
+ ruleContext.getPrerequisite(
+ ":fdo_prefetch_hints", Mode.TARGET, FdoPrefetchHintsProvider.PROVIDER);
+ prefetchHints = provider.getInputFile();
+ }
if (cppConfiguration.getFdoPath() != null) {
fdoZip = cppConfiguration.getFdoPath();
} else if (cppConfiguration.getFdoOptimizeLabel() != null) {
@@ -342,10 +372,11 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
FdoProfileProvider fdoProvider =
ruleContext.getPrerequisite(
CcToolchainRule.FDO_PROFILE_ATTR, Mode.TARGET, FdoProfileProvider.PROVIDER);
+ FdoInputFile inputFile = fdoProvider.getInputFile();
fdoZip =
- fdoProvider.getFdoPath() != null
- ? fdoProvider.getFdoPath()
- : fdoProvider.getProfileArtifact().getPath().asFragment();
+ inputFile.getAbsolutePath() != null
+ ? inputFile.getAbsolutePath()
+ : inputFile.getArtifact().getPath().asFragment();
}
}
@@ -373,7 +404,11 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
SkyKey fdoKey =
FdoSupportValue.key(
- cppConfiguration.getLipoMode(), fdoZip, cppConfiguration.getFdoInstrument(), fdoMode);
+ cppConfiguration.getLipoMode(),
+ fdoZip,
+ prefetchHints,
+ cppConfiguration.getFdoInstrument(),
+ fdoMode);
SkyFunction.Environment skyframeEnv = ruleContext.getAnalysisEnvironment().getSkyframeEnv();
FdoSupportValue fdoSupport;
@@ -527,6 +562,8 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
return null;
}
}
+ Artifact hintsArtifact = getPrefetchHintsArtifact(prefetchHints, ruleContext);
+ ProfileArtifacts profileArtifacts = new ProfileArtifacts(profileArtifact, hintsArtifact);
reportInvalidOptions(ruleContext, toolchainInfo);
@@ -578,7 +615,7 @@ public class CcToolchain implements RuleConfiguredTargetFactory {
.addNativeDeclaredProvider(ccProvider)
.addNativeDeclaredProvider(templateVariableInfo)
.addProvider(
- fdoSupport.getFdoSupport().createFdoSupportProvider(ruleContext, profileArtifact))
+ fdoSupport.getFdoSupport().createFdoSupportProvider(ruleContext, profileArtifacts))
.setFilesToBuild(crosstool)
.addProvider(RunfilesProvider.simple(Runfiles.EMPTY));
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
index a7bf17bf51..bdba98899c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainRule.java
@@ -85,6 +85,12 @@ public final class CcToolchainRule implements RuleDefinition {
null,
(rule, attributes, cppConfig) -> cppConfig.getFdoProfileLabel());
+ private static final LabelLateBoundDefault<?> FDO_PREFETCH_HINTS =
+ LabelLateBoundDefault.fromTargetConfiguration(
+ CppConfiguration.class,
+ null,
+ (rule, attributes, cppConfig) -> cppConfig.getFdoPrefetchHintsLabel());
+
/**
* Returns true if zipper should be loaded. We load the zipper executable if FDO optimization is
* enabled through --fdo_optimize or --fdo_profile
@@ -179,6 +185,11 @@ public final class CcToolchainRule implements RuleDefinition {
.mandatoryProviders(ImmutableList.of(FdoProfileProvider.PROVIDER.id()))
.value(FDO_PROFILE_VALUE))
.add(
+ attr(":fdo_prefetch_hints", LABEL)
+ .allowedRuleClasses("fdo_prefetch_hints")
+ .mandatoryProviders(ImmutableList.of(FdoPrefetchHintsProvider.PROVIDER.id()))
+ .value(FDO_PREFETCH_HINTS))
+ .add(
attr(TransitiveLipoInfoProvider.LIPO_CONTEXT_COLLECTOR, LABEL)
.cfg(LipoContextCollectorTransition.INSTANCE)
.value(CppRuleClasses.LIPO_CONTEXT_COLLECTOR)
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java
index 6b6247eab1..b0938b83af 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java
@@ -94,6 +94,8 @@ public enum CompileBuildVariables {
FDO_INSTRUMENT_PATH("fdo_instrument_path"),
/** Path to the fdo profile artifact */
FDO_PROFILE_PATH("fdo_profile_path"),
+ /** Path to the cache prefetch profile artifact */
+ FDO_PREFETCH_HINTS_PATH("fdo_prefetch_hints_path"),
/** Variable for includes that compiler needs to include into sources. */
INCLUDES("includes");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
index f1ec0a19a3..efd741a6c3 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppActionConfigs.java
@@ -31,6 +31,8 @@ public class CppActionConfigs {
MAC
}
+ // Note: these configs won't be added to the crosstools that defines no_legacy_features feature
+ // (e.g. ndk, apple, enclave crosstools). Those need to be modified separately.
public static String getCppActionConfigs(
CppPlatform platform,
ImmutableSet<String> existingFeatureNames,
@@ -402,6 +404,21 @@ public class CppActionConfigs {
" }",
"}"),
ifTrue(
+ !existingFeatureNames.contains(CppRuleClasses.FDO_PREFETCH_HINTS),
+ "feature {",
+ " name: 'fdo_prefetch_hints'",
+ " flag_set {",
+ " action: 'c-compile'",
+ " action: 'c++-compile'",
+ " action: 'lto-backend'",
+ " expand_if_all_available: 'fdo_prefetch_hints_path'",
+ " flag_group {",
+ " flag: '-Xclang-only=-mllvm'",
+ " flag: '-Xclang-only=-prefetch-hints-file=%{fdo_prefetch_hints_path}'",
+ " }",
+ " }",
+ "}"),
+ ifTrue(
!existingFeatureNames.contains(CppRuleClasses.AUTOFDO),
"feature {",
" name: 'autofdo'",
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
index 4761c2b6d4..568f418ad5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java
@@ -1333,6 +1333,10 @@ public final class CppConfiguration extends BuildConfiguration.Fragment {
return fdoOptimizeLabel;
}
+ public Label getFdoPrefetchHintsLabel() {
+ return cppOptions.getFdoPrefetchHintsLabel();
+ }
+
public Label getFdoProfileLabel() {
return cppOptions.getFdoProfileLabel();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
index 3192605a04..713dd2b242 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppOptions.java
@@ -480,6 +480,24 @@ public class CppOptions extends FragmentOptions {
return enableLipoSettings() ? fdoOptimizeForBuild : null;
}
+ @Option(
+ name = "fdo_prefetch_hints",
+ defaultValue = "null",
+ converter = LabelConverter.class,
+ category = "flags",
+ documentationCategory = OptionDocumentationCategory.OUTPUT_PARAMETERS,
+ effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+ help = "Use cache prefetch hints."
+ )
+ public Label fdoPrefetchHintsLabel;
+
+ /**
+ * Returns the --fdo_prefetch_hints value.
+ */
+ public Label getFdoPrefetchHintsLabel() {
+ return fdoPrefetchHintsLabel;
+ }
+
/**
* Returns the --autofdo_lipo_data value for this configuration. This is false except for data
* configurations under LIPO builds.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
index da10c03d71..2862cbc67e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppRuleClasses.java
@@ -372,6 +372,11 @@ public class CppRuleClasses {
public static final String FDO_OPTIMIZE = "fdo_optimize";
/**
+ * A string constant for the cache prefetch hints feature.
+ */
+ public static final String FDO_PREFETCH_HINTS = "fdo_prefetch_hints";
+
+ /**
* A string constant for the autofdo feature.
*/
public static final String AUTOFDO = "autofdo";
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoInputFile.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoInputFile.java
new file mode 100644
index 0000000000..d9644032b6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoInputFile.java
@@ -0,0 +1,103 @@
+// Copyright 2018 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 com.google.common.base.Preconditions;
+import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.Objects;
+
+/**
+ * Value object reused by fdo configurations that may be either an artifact or a path.
+ */
+@Immutable
+public final class FdoInputFile {
+
+ private final Artifact artifact;
+ private final PathFragment absolutePath;
+
+ private FdoInputFile(Artifact artifact, PathFragment absolutePath) {
+ Preconditions.checkArgument((artifact == null) != (absolutePath == null));
+ Preconditions.checkArgument(absolutePath == null || absolutePath.isAbsolute());
+ this.artifact = artifact;
+ this.absolutePath = absolutePath;
+ }
+
+ public Artifact getArtifact() {
+ return artifact;
+ }
+
+ public PathFragment getAbsolutePath() {
+ return absolutePath;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof FdoInputFile)) {
+ return false;
+ }
+
+ FdoInputFile that = (FdoInputFile) o;
+ return Objects.equals(this.artifact, that.artifact)
+ && Objects.equals(this.absolutePath, that.absolutePath);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(artifact, absolutePath);
+ }
+
+ public static FdoInputFile create(RuleContext ruleContext) {
+
+ boolean isLabel = ruleContext.attributes().isAttributeValueExplicitlySpecified("profile");
+ boolean isAbsolutePath =
+ ruleContext.attributes().isAttributeValueExplicitlySpecified("absolute_path_profile");
+
+ if (isLabel == isAbsolutePath) {
+ ruleContext.ruleError("exactly one of profile and absolute_path_profile should be specified");
+ return null;
+ }
+
+ if (isLabel) {
+ Artifact artifact = ruleContext.getPrerequisiteArtifact("profile", Mode.TARGET);
+ if (!artifact.isSourceArtifact()) {
+ ruleContext.attributeError("profile", " the target is not an input file");
+ }
+ return new FdoInputFile(artifact, null);
+ } else {
+ if (!ruleContext.getFragment(CppConfiguration.class).isFdoAbsolutePathEnabled()) {
+ ruleContext.attributeError(
+ "absolute_path_profile",
+ "this attribute cannot be used when --enable_fdo_profile_absolute_path is false");
+ return null;
+ }
+ String pathString = ruleContext.getExpander().expand("absolute_path_profile");
+ PathFragment absolutePath = PathFragment.create(pathString);
+ if (!absolutePath.isAbsolute()) {
+ ruleContext.attributeError(
+ "absolute_path_profile",
+ String.format("%s is not an absolute path", absolutePath.getPathString()));
+ return null;
+ }
+ return new FdoInputFile(null, absolutePath);
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java
new file mode 100644
index 0000000000..7dcff8fbc0
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHints.java
@@ -0,0 +1,42 @@
+// Copyright 2018 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 com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
+import com.google.devtools.build.lib.analysis.ConfiguredTarget;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.Runfiles;
+import com.google.devtools.build.lib.analysis.RunfilesProvider;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+
+/** Implementation for the {@code fdo_prefetch_hints} rule. */
+@Immutable
+public final class FdoPrefetchHints implements RuleConfiguredTargetFactory {
+ @Override
+ public ConfiguredTarget create(RuleContext ruleContext)
+ throws RuleErrorException, ActionConflictException {
+
+ FdoInputFile inputFile = FdoInputFile.create(ruleContext);
+ if (ruleContext.hasErrors()) {
+ return null;
+ }
+
+ return new RuleConfiguredTargetBuilder(ruleContext)
+ .addNativeDeclaredProvider(new FdoPrefetchHintsProvider(inputFile))
+ .addProvider(RunfilesProvider.simple(Runfiles.EMPTY))
+ .build();
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsProvider.java
new file mode 100644
index 0000000000..e7a7ebf26e
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsProvider.java
@@ -0,0 +1,37 @@
+// Copyright 2018 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 com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.packages.NativeInfo;
+import com.google.devtools.build.lib.packages.NativeProvider;
+
+/** Provider that contains the profile used for prefetch hints. */
+@Immutable
+public final class FdoPrefetchHintsProvider extends NativeInfo {
+ public static final NativeProvider<FdoPrefetchHintsProvider> PROVIDER =
+ new NativeProvider<FdoPrefetchHintsProvider>(
+ FdoPrefetchHintsProvider.class, "FdoPrefetchHintsInfo") {};
+
+ private final FdoInputFile fdoInputFile;
+
+ public FdoPrefetchHintsProvider(FdoInputFile fdoInputFile) {
+ super(PROVIDER);
+ this.fdoInputFile = fdoInputFile;
+ }
+
+ public FdoInputFile getInputFile() {
+ return fdoInputFile;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsRule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsRule.java
new file mode 100644
index 0000000000..c706474f07
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoPrefetchHintsRule.java
@@ -0,0 +1,78 @@
+// Copyright 2018 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.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.syntax.Type;
+import com.google.devtools.build.lib.util.FileType;
+import com.google.devtools.build.lib.util.FileTypeSet;
+
+/** {@code fdo_prefetch_hints} rule class. */
+public final class FdoPrefetchHintsRule implements RuleDefinition {
+ @Override
+ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ .requiresConfigurationFragments(CppConfiguration.class)
+ /* <!-- #BLAZE_RULE(fdo_prefetch_hints).ATTRIBUTE(profile) -->
+ Label of the hints profile. The hints file has the .afdo extension
+ The label can also point to an fdo_absolute_path_profile rule.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(
+ attr("profile", LABEL)
+ .allowedFileTypes(
+ FileTypeSet.of(
+ FileType.of(".afdo")))
+ .singleArtifact())
+ /* <!-- #BLAZE_RULE(fdo_profile).ATTRIBUTE(absolute_path_profile) -->
+ Absolute path to the FDO profile. The FDO file may only have the .afdo extension.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("absolute_path_profile", Type.STRING))
+ .advertiseProvider(FdoPrefetchHintsProvider.class)
+ .build();
+ }
+
+ @Override
+ public Metadata getMetadata() {
+ return RuleDefinition.Metadata.builder()
+ .name("fdo_prefetch_hints")
+ .ancestors(BaseRuleClasses.BaseRule.class)
+ .factoryClass(FdoPrefetchHints.class)
+ .build();
+ }
+}
+
+/*<!-- #BLAZE_RULE (NAME = fdo_prefetch_hints, TYPE = LIBRARY, FAMILY = Cpp) -->
+
+<p>Represents an FDO prefetch hints profile that is either in the workspace or at a specified
+absolute path.
+Examples:</p>
+
+<pre class="code">
+fdo_prefetch_hints(
+ name = "hints",
+ profile = "//path/to/hints:profile.afdo",
+)
+
+fdo_profile(
+ name = "hints_abs",
+ absolute_path_profile = "/absolute/path/profile.afdo",
+)
+</pre>
+<!-- #END_BLAZE_RULE -->*/
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java
index 2e4131fbc4..0fbfe8593e 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfile.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.cpp;
-import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
@@ -21,9 +20,7 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
-import com.google.devtools.build.lib.vfs.PathFragment;
/** Implementation for the {@code fdo_profile} rule. */
@Immutable
@@ -32,42 +29,13 @@ public final class FdoProfile implements RuleConfiguredTargetFactory {
public ConfiguredTarget create(RuleContext ruleContext)
throws RuleErrorException, ActionConflictException {
- FdoProfileProvider provider;
-
- boolean isLabel = ruleContext.attributes().isAttributeValueExplicitlySpecified("profile");
- boolean isAbsolutePath =
- ruleContext.attributes().isAttributeValueExplicitlySpecified("absolute_path_profile");
-
- if (isLabel == isAbsolutePath) {
- ruleContext.ruleError("exactly one of profile and absolute_path_profile should be specified");
+ FdoInputFile inputFile = FdoInputFile.create(ruleContext);
+ if (ruleContext.hasErrors()) {
return null;
}
- if (isLabel) {
- Artifact artifact = ruleContext.getPrerequisiteArtifact("profile", Mode.TARGET);
- if (!artifact.isSourceArtifact()) {
- ruleContext.attributeError("profile", " the target is not an input file");
- }
- provider = FdoProfileProvider.fromArtifact(artifact);
- } else {
- if (!ruleContext.getFragment(CppConfiguration.class).isFdoAbsolutePathEnabled()) {
- ruleContext.attributeError(
- "absolute_path_profile",
- "this attribute cannot be used when --enable_fdo_profile_absolute_path is false");
- return null;
- }
- String path = ruleContext.getExpander().expand("absolute_path_profile");
- PathFragment fdoPath = PathFragment.create(path);
- if (!fdoPath.isAbsolute()) {
- ruleContext.attributeError(
- "absolute_path_profile",
- String.format("%s is not an absolute path", fdoPath.getPathString()));
- }
- provider = FdoProfileProvider.fromAbsolutePath(fdoPath);
- }
-
return new RuleConfiguredTargetBuilder(ruleContext)
- .addNativeDeclaredProvider(provider)
+ .addNativeDeclaredProvider(new FdoProfileProvider(inputFile))
.addProvider(RunfilesProvider.simple(Runfiles.EMPTY))
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java
index b5c73bdc0c..876d164efa 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoProfileProvider.java
@@ -13,11 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.cpp;
-import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.packages.NativeProvider;
-import com.google.devtools.build.lib.vfs.PathFragment;
/** Provider that contains the profile used for FDO. */
@Immutable
@@ -25,28 +23,14 @@ public final class FdoProfileProvider extends NativeInfo {
public static final NativeProvider<FdoProfileProvider> PROVIDER =
new NativeProvider<FdoProfileProvider>(FdoProfileProvider.class, "FdoProfileInfo") {};
- private final Artifact profileArtifact;
- private final PathFragment fdoPath;
+ private final FdoInputFile fdoInputFile;
- private FdoProfileProvider(Artifact profileArtifact, PathFragment fdoPath) {
+ public FdoProfileProvider(FdoInputFile fdoInputFile) {
super(PROVIDER);
- this.profileArtifact = profileArtifact;
- this.fdoPath = fdoPath;
+ this.fdoInputFile = fdoInputFile;
}
- public static FdoProfileProvider fromAbsolutePath(PathFragment fdoPath) {
- return new FdoProfileProvider(/* profileArtifact= */ null, fdoPath);
- }
-
- public static FdoProfileProvider fromArtifact(Artifact profileArtifact) {
- return new FdoProfileProvider(profileArtifact, /* fdoPath= */ null);
- }
-
- public Artifact getProfileArtifact() {
- return profileArtifact;
- }
-
- public PathFragment getFdoPath() {
- return fdoPath;
+ public FdoInputFile getInputFile() {
+ return fdoInputFile;
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
index e10ca70cd0..f657c0775b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupport.java
@@ -605,13 +605,20 @@ public class FdoSupport {
FeatureConfiguration featureConfiguration,
FdoSupportProvider fdoSupportProvider) {
+ ImmutableMap.Builder<String, String> variablesBuilder = ImmutableMap.builder();
+
+ if ((fdoSupportProvider != null)
+ && (fdoSupportProvider.getPrefetchHintsArtifact() != null)) {
+ variablesBuilder.put(
+ CompileBuildVariables.FDO_PREFETCH_HINTS_PATH.getVariableName(),
+ fdoSupportProvider.getPrefetchHintsArtifact().getExecPathString());
+ }
+
// FDO is disabled -> do nothing.
if ((fdoInstrument == null) && (fdoRoot == null)) {
return ImmutableMap.of();
}
- ImmutableMap.Builder<String, String> variablesBuilder = ImmutableMap.builder();
-
if (featureConfiguration.isEnabled(CppRuleClasses.FDO_INSTRUMENT)) {
variablesBuilder.put(
CompileBuildVariables.FDO_INSTRUMENT_PATH.getVariableName(), fdoInstrument);
@@ -663,19 +670,21 @@ public class FdoSupport {
LipoContextProvider lipoContextProvider =
toolchain.isLLVMCompiler() ? null : CppHelper.getLipoContextProvider(ruleContext);
+ ImmutableSet.Builder<Artifact> auxiliaryInputs = ImmutableSet.builder();
+
+ if (fdoSupportProvider.getPrefetchHintsArtifact() != null) {
+ auxiliaryInputs.add(fdoSupportProvider.getPrefetchHintsArtifact());
+ }
// If --fdo_optimize was not specified, we don't have any additional inputs.
if (fdoProfile == null) {
- return ImmutableSet.of();
+ return auxiliaryInputs.build();
} else if (fdoMode == FdoMode.LLVM_FDO || fdoMode == FdoMode.AUTO_FDO) {
- ImmutableSet.Builder<Artifact> auxiliaryInputs = ImmutableSet.builder();
auxiliaryInputs.add(fdoSupportProvider.getProfileArtifact());
if (lipoContextProvider != null) {
auxiliaryInputs.addAll(getAutoFdoImports(ruleContext, sourceExecPath, lipoContextProvider));
}
return auxiliaryInputs.build();
} else {
- ImmutableSet.Builder<Artifact> auxiliaryInputs = ImmutableSet.builder();
-
PathFragment objectName =
FileSystemUtils.appendExtension(outputName, usePic ? ".pic.o" : ".o");
@@ -803,18 +812,22 @@ public class FdoSupport {
* AutoFDO is disabled, no build variable is added and returns null.
*/
@ThreadSafe
- public Artifact buildProfileForLtoBackend(
+ public ProfileArtifacts buildProfileForLtoBackend(
FdoSupportProvider fdoSupportProvider,
FeatureConfiguration featureConfiguration,
CcToolchainVariables.Builder buildVariables,
RuleContext ruleContext) {
+ Artifact prefetch = fdoSupportProvider.getPrefetchHintsArtifact();
+ if (prefetch != null) {
+ buildVariables.addStringVariable("fdo_prefetch_hints_path", prefetch.getExecPathString());
+ }
if (!featureConfiguration.isEnabled(CppRuleClasses.AUTOFDO)) {
- return null;
+ return new ProfileArtifacts(null, prefetch);
}
Artifact profile = fdoSupportProvider.getProfileArtifact();
buildVariables.addStringVariable("fdo_profile_path", profile.getExecPathString());
- return profile;
+ return new ProfileArtifacts(profile, prefetch);
}
/**
@@ -827,20 +840,20 @@ public class FdoSupport {
}
public FdoSupportProvider createFdoSupportProvider(
- RuleContext ruleContext, Artifact profileArtifact) {
+ RuleContext ruleContext, ProfileArtifacts profiles) {
if (fdoRoot == null) {
- return new FdoSupportProvider(this, null, null);
+ return new FdoSupportProvider(this, profiles, null);
}
if (fdoMode == FdoMode.LLVM_FDO) {
- Preconditions.checkState(profileArtifact != null);
- return new FdoSupportProvider(this, profileArtifact, null);
+ Preconditions.checkState(profiles != null && profiles.getProfileArtifact() != null);
+ return new FdoSupportProvider(this, profiles, null);
}
Preconditions.checkState(fdoPath != null);
PathFragment profileRootRelativePath = getAutoProfileRootRelativePath(fdoProfile);
- profileArtifact =
+ Artifact profileArtifact =
ruleContext
.getAnalysisEnvironment()
.getDerivedArtifact(fdoPath.getRelative(profileRootRelativePath), fdoRoot);
@@ -854,7 +867,11 @@ public class FdoSupport {
gcdaArtifacts.put(path, gcdaArtifact);
}
- return new FdoSupportProvider(this, profileArtifact, gcdaArtifacts.build());
+ return new FdoSupportProvider(
+ this,
+ new ProfileArtifacts(
+ profileArtifact, profiles == null ? null : profiles.getPrefetchHintsArtifact()),
+ gcdaArtifacts.build());
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportProvider.java
index 72715f02ba..2ff61051b6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportProvider.java
@@ -28,14 +28,14 @@ import com.google.devtools.build.lib.vfs.PathFragment;
@AutoCodec
public class FdoSupportProvider implements TransitiveInfoProvider {
private final FdoSupport fdoSupport;
- private final Artifact profileArtifact;
+ private final ProfileArtifacts profileArtifacts;
private final ImmutableMap<PathFragment, Artifact> gcdaArtifacts;
@AutoCodec.Instantiator
- public FdoSupportProvider(FdoSupport fdoSupport, Artifact profileArtifact,
+ public FdoSupportProvider(FdoSupport fdoSupport, ProfileArtifacts profileArtifacts,
ImmutableMap<PathFragment, Artifact> gcdaArtifacts) {
this.fdoSupport = fdoSupport;
- this.profileArtifact = profileArtifact;
+ this.profileArtifacts = profileArtifacts;
this.gcdaArtifacts = gcdaArtifacts;
}
@@ -43,7 +43,10 @@ public class FdoSupportProvider implements TransitiveInfoProvider {
return fdoSupport;
}
public Artifact getProfileArtifact() {
- return profileArtifact;
+ return profileArtifacts != null ? profileArtifacts.getProfileArtifact() : null;
+ }
+ public Artifact getPrefetchHintsArtifact() {
+ return profileArtifacts != null ? profileArtifacts.getPrefetchHintsArtifact() : null;
}
public ImmutableMap<PathFragment, Artifact> getGcdaArtifacts() {
return gcdaArtifacts;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportValue.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportValue.java
index 83c8173ec6..f6bad1f0b2 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportValue.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FdoSupportValue.java
@@ -47,20 +47,33 @@ public class FdoSupportValue implements SkyValue {
private final LipoMode lipoMode;
private final PathFragment fdoZip;
+ private final FdoInputFile fdoPrefetchHintsFile;
private final String fdoInstrument;
private final FdoMode fdoMode;
- private Key(LipoMode lipoMode, PathFragment fdoZip, String fdoInstrument, FdoMode fdoMode) {
+ private Key(
+ LipoMode lipoMode,
+ PathFragment fdoZip,
+ FdoInputFile fdoPrefetchHintsFile,
+ String fdoInstrument,
+ FdoMode fdoMode) {
this.lipoMode = lipoMode;
this.fdoZip = fdoZip;
+ this.fdoPrefetchHintsFile = fdoPrefetchHintsFile;
this.fdoInstrument = fdoInstrument;
this.fdoMode = fdoMode;
}
@AutoCodec.Instantiator
@AutoCodec.VisibleForSerialization
- static Key of(LipoMode lipoMode, PathFragment fdoZip, String fdoInstrument, FdoMode fdoMode) {
- return interner.intern(new Key(lipoMode, fdoZip, fdoInstrument, fdoMode));
+ static Key of(
+ LipoMode lipoMode,
+ PathFragment fdoZip,
+ FdoInputFile fdoPrefetchHintsFile,
+ String fdoInstrument,
+ FdoMode fdoMode) {
+ return interner.intern(
+ new Key(lipoMode, fdoZip, fdoPrefetchHintsFile, fdoInstrument, fdoMode));
}
public LipoMode getLipoMode() {
@@ -71,6 +84,10 @@ public class FdoSupportValue implements SkyValue {
return fdoZip;
}
+ public FdoInputFile getFdoPrefetchHintsFile() {
+ return fdoPrefetchHintsFile;
+ }
+
public String getFdoInstrument() {
return fdoInstrument;
}
@@ -92,13 +109,14 @@ public class FdoSupportValue implements SkyValue {
Key that = (Key) o;
return Objects.equals(this.lipoMode, that.lipoMode)
&& Objects.equals(this.fdoZip, that.fdoZip)
+ && Objects.equals(this.fdoPrefetchHintsFile, that.fdoPrefetchHintsFile)
&& Objects.equals(this.fdoMode, that.fdoMode)
&& Objects.equals(this.fdoInstrument, that.fdoInstrument);
}
@Override
public int hashCode() {
- return Objects.hash(lipoMode, fdoZip, fdoInstrument);
+ return Objects.hash(lipoMode, fdoZip, fdoPrefetchHintsFile, fdoInstrument);
}
@Override
@@ -118,7 +136,11 @@ public class FdoSupportValue implements SkyValue {
}
public static SkyKey key(
- LipoMode lipoMode, PathFragment fdoZip, String fdoInstrument, FdoMode fdoMode) {
- return Key.of(lipoMode, fdoZip, fdoInstrument, fdoMode);
+ LipoMode lipoMode,
+ PathFragment fdoZip,
+ FdoInputFile fdoPrefetchHintsFile,
+ String fdoInstrument,
+ FdoMode fdoMode) {
+ return Key.of(lipoMode, fdoZip, fdoPrefetchHintsFile, fdoInstrument, fdoMode);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java
index df6dba73d0..f3e6d688a9 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LtoBackendArtifacts.java
@@ -230,10 +230,18 @@ public final class LtoBackendArtifacts {
// The input to the LTO backend step is the bitcode file.
buildVariablesBuilder.addStringVariable(
"thinlto_input_bitcode_file", bitcodeFile.getExecPath().toString());
- Artifact autoFdoProfile = fdoSupport.getFdoSupport().buildProfileForLtoBackend(
- fdoSupport, featureConfiguration, buildVariablesBuilder, ruleContext);
- if (autoFdoProfile != null) {
- builder.addInput(autoFdoProfile);
+ ProfileArtifacts profileArtifacts =
+ Preconditions.checkNotNull(
+ fdoSupport
+ .getFdoSupport()
+ .buildProfileForLtoBackend(
+ fdoSupport, featureConfiguration, buildVariablesBuilder, ruleContext));
+
+ if (profileArtifacts.getProfileArtifact() != null) {
+ builder.addInput(profileArtifacts.getProfileArtifact());
+ }
+ if (profileArtifacts.getPrefetchHintsArtifact() != null) {
+ builder.addInput(profileArtifacts.getPrefetchHintsArtifact());
}
if (generateDwo) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/ProfileArtifacts.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/ProfileArtifacts.java
new file mode 100644
index 0000000000..1b46d99dba
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/ProfileArtifacts.java
@@ -0,0 +1,43 @@
+// Copyright 2018 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 com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+
+/**
+ * ProfileArtifacts groups together Artifacts that may be used as inputs for feedback-driven
+ * optimization.
+ */
+@Immutable
+public class ProfileArtifacts {
+ private final Artifact profileArtifact;
+ private final Artifact prefetchHintsArtifact;
+
+ public ProfileArtifacts(Artifact profileArtifact) {
+ this(profileArtifact, null);
+ }
+ public ProfileArtifacts(Artifact profileArtifact, Artifact prefetchHintsArtifact) {
+ this.profileArtifact = profileArtifact;
+ this.prefetchHintsArtifact = prefetchHintsArtifact;
+ }
+
+ public Artifact getProfileArtifact() {
+ return profileArtifact;
+ }
+ public Artifact getPrefetchHintsArtifact() {
+ return prefetchHintsArtifact;
+ }
+}