Split CcSkyframeSupportValue

Split it into Crosstool and FDO specific values. This is a preparation to move
FDO specific value to rules implementation, and to remove Crosstool specific
value once Crosstool in Proto is removed.

https://github.com/bazelbuild/bazel/issues/6516

RELNOTES: None
PiperOrigin-RevId: 240360330
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
index 0304220..68f95e5 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
@@ -20,8 +20,10 @@
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.bazel.rules.cpp.BazelCppRuleClasses;
 import com.google.devtools.build.lib.bazel.rules.sh.BazelShRuleClasses;
-import com.google.devtools.build.lib.rules.cpp.CcSkyframeSupportFunction;
-import com.google.devtools.build.lib.rules.cpp.CcSkyframeSupportValue;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeCrosstoolSupportFunction;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeCrosstoolSupportValue;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeFdoSupportFunction;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeFdoSupportValue;
 import com.google.devtools.build.lib.runtime.BlazeModule;
 import com.google.devtools.build.lib.runtime.BlazeRuntime;
 import com.google.devtools.build.lib.runtime.Command;
@@ -312,7 +314,9 @@
   public void workspaceInit(
       BlazeRuntime runtime, BlazeDirectories directories, WorkspaceBuilder builder) {
     builder.addSkyFunction(
-        CcSkyframeSupportValue.SKYFUNCTION, new CcSkyframeSupportFunction(directories));
+        CcSkyframeFdoSupportValue.SKYFUNCTION, new CcSkyframeFdoSupportFunction(directories));
+    builder.addSkyFunction(
+        CcSkyframeCrosstoolSupportValue.SKYFUNCTION, new CcSkyframeCrosstoolSupportFunction());
   }
 
   @Override
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeSupportFunction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeCrosstoolSupportFunction.java
similarity index 70%
rename from src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeSupportFunction.java
rename to src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeCrosstoolSupportFunction.java
index f22629a..9588719 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeSupportFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeCrosstoolSupportFunction.java
@@ -14,9 +14,7 @@
 package com.google.devtools.build.lib.rules.cpp;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
 import com.google.devtools.build.lib.actions.FileValue;
-import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
 import com.google.devtools.build.lib.cmdline.PackageIdentifier;
 import com.google.devtools.build.lib.skyframe.PackageLookupValue;
@@ -38,39 +36,21 @@
 import javax.annotation.Nullable;
 
 /**
- * A {@link SkyFunction} that does things for FDO that a regular configured target is not allowed
- * to.
- *
- * <p>This only exists because the value of {@code --fdo_optimize} can be a workspace-relative path
- * and thus we need to depend on {@link BlazeDirectories} somehow, which neither the configuration
- * nor the analysis phase can "officially" do.
- *
- * <p>The fix is probably to make it possible for {@link
- * com.google.devtools.build.lib.analysis.actions.SymlinkAction} to create workspace-relative
- * symlinks because action execution can hopefully depend on {@link BlazeDirectories}.
- *
- * <p>There is also the awful and incorrect {@link Path#exists()} call in {@link
- * com.google.devtools.build.lib.view.proto.CcProtoProfileProvider#getProfile(
- * com.google.devtools.build.lib.analysis.RuleContext)} which needs a {@link Path}.
+ * A {@link SkyFunction} that does things for CROSSTOOL that a regular configured target is not
+ * allowed to (read a file from filesystem).
  */
-public class CcSkyframeSupportFunction implements SkyFunction {
+public class CcSkyframeCrosstoolSupportFunction implements SkyFunction {
 
   static final String CROSSTOOL_CONFIGURATION_FILENAME = "CROSSTOOL";
-  private final BlazeDirectories directories;
 
-  public CcSkyframeSupportFunction(BlazeDirectories directories) {
-    this.directories = Preconditions.checkNotNull(directories);
-  }
+  public CcSkyframeCrosstoolSupportFunction() {}
 
   @Nullable
   @Override
   public SkyValue compute(SkyKey skyKey, Environment env)
-      throws InterruptedException, CcSkyframeSupportException {
-    CcSkyframeSupportValue.Key key = (CcSkyframeSupportValue.Key) skyKey.argument();
-    Path fdoZipPath = null;
-    if (key.getFdoZipPath() != null) {
-      fdoZipPath = directories.getWorkspace().getRelative(key.getFdoZipPath());
-    }
+      throws InterruptedException, CcSkyframeCrosstoolSupportException {
+    CcSkyframeCrosstoolSupportValue.Key key =
+        (CcSkyframeCrosstoolSupportValue.Key) skyKey.argument();
 
     CrosstoolRelease crosstoolRelease = null;
     if (key.getPackageWithCrosstoolInIt() != null) {
@@ -98,7 +78,7 @@
         // 3. Parse the crosstool file the into CrosstoolRelease
         Path crosstoolFile = crosstoolFileValue.realRootedPath().asPath();
         if (!crosstoolFile.exists()) {
-          throw new CcSkyframeSupportException(
+          throw new CcSkyframeCrosstoolSupportException(
               String.format(
                   "there is no CROSSTOOL file at %s, which is needed for this cc_toolchain",
                   crosstool.toString()),
@@ -109,11 +89,11 @@
           crosstoolRelease = toReleaseConfiguration(crosstoolContent);
         }
       } catch (IOException | InvalidConfigurationException e) {
-        throw new CcSkyframeSupportException(e.getMessage(), key);
+        throw new CcSkyframeCrosstoolSupportException(e.getMessage(), key);
       }
     }
 
-    return new CcSkyframeSupportValue(fdoZipPath, crosstoolRelease);
+    return new CcSkyframeCrosstoolSupportValue(crosstoolRelease);
   }
 
   @Nullable
@@ -146,14 +126,11 @@
     }
   }
 
-  /** Exception encapsulating IOExceptions thrown in {@link CcSkyframeSupportFunction} */
-  public static class CcSkyframeSupportException extends SkyFunctionException {
+  /** Exception encapsulating IOExceptions thrown in {@link CcSkyframeCrosstoolSupportFunction} */
+  public static class CcSkyframeCrosstoolSupportException extends SkyFunctionException {
 
-    public CcSkyframeSupportException(Exception cause, CcSkyframeSupportValue.Key key) {
-      super(cause, key);
-    }
-
-    public CcSkyframeSupportException(String message, CcSkyframeSupportValue.Key key) {
+    public CcSkyframeCrosstoolSupportException(
+        String message, CcSkyframeCrosstoolSupportValue.Key key) {
       super(new CcCrosstoolException(message), key);
     }
   }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeCrosstoolSupportValue.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeCrosstoolSupportValue.java
new file mode 100644
index 0000000..6c8edd6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeCrosstoolSupportValue.java
@@ -0,0 +1,102 @@
+// Copyright 2014 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.collect.Interner;
+import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.concurrent.BlazeInterners;
+import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
+import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyFunctionName;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+import java.util.Objects;
+
+/**
+ * A container for the CROSSTOOL file content.
+ *
+ * <p>{@link CcSkyframeCrosstoolSupportValue} is created from {@link
+ * CcSkyframeCrosstoolSupportFunction} (a {@link SkyFunction}), which is requested from Skyframe by
+ * the {@code cc_toolchain}/{@code cc_toolchain_suite} rules. It's done this way because the path
+ * depends on both a command line argument and the location of the workspace and the latter is not
+ * available either during configuration creation or during the analysis phase.
+ */
+@AutoCodec
+@Immutable
+public class CcSkyframeCrosstoolSupportValue implements SkyValue {
+  public static final SkyFunctionName SKYFUNCTION =
+      SkyFunctionName.createHermetic("CROSSTOOL_SUPPORT");
+
+  /** {@link SkyKey} for {@link CcSkyframeCrosstoolSupportValue}. */
+  @Immutable
+  @AutoCodec
+  public static class Key implements SkyKey {
+    private static final Interner<Key> interner = BlazeInterners.newWeakInterner();
+
+    private final PackageIdentifier packageWithCrosstoolInIt;
+
+    private Key(PackageIdentifier packageWithCrosstoolInIt) {
+      this.packageWithCrosstoolInIt = packageWithCrosstoolInIt;
+    }
+
+    @AutoCodec.Instantiator
+    @AutoCodec.VisibleForSerialization
+    static Key of(PackageIdentifier packageWithCrosstoolInIt) {
+      return interner.intern(new Key(packageWithCrosstoolInIt));
+    }
+
+    public PackageIdentifier getPackageWithCrosstoolInIt() {
+      return packageWithCrosstoolInIt;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) {
+        return true;
+      }
+      if (!(o instanceof Key)) {
+        return false;
+      }
+      Key key = (Key) o;
+      return Objects.equals(packageWithCrosstoolInIt, key.packageWithCrosstoolInIt);
+    }
+
+    @Override
+    public int hashCode() {
+
+      return Objects.hash(packageWithCrosstoolInIt);
+    }
+
+    @Override
+    public SkyFunctionName functionName() {
+      return SKYFUNCTION;
+    }
+  }
+
+  private final CrosstoolRelease crosstoolRelease;
+
+  CcSkyframeCrosstoolSupportValue(CrosstoolRelease crosstoolRelease) {
+    this.crosstoolRelease = crosstoolRelease;
+  }
+
+  public CrosstoolRelease getCrosstoolRelease() {
+    return crosstoolRelease;
+  }
+
+  public static SkyKey key(PackageIdentifier packageWithCrosstoolInIt) {
+    return Key.of(packageWithCrosstoolInIt);
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeFdoSupportFunction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeFdoSupportFunction.java
new file mode 100644
index 0000000..a5863f4
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeFdoSupportFunction.java
@@ -0,0 +1,64 @@
+// Copyright 2014 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.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+import javax.annotation.Nullable;
+
+/**
+ * A {@link SkyFunction} that does things for FDO that a regular configured target is not allowed
+ * to.
+ *
+ * <p>This only exists because the value of {@code --fdo_optimize} can be a workspace-relative path
+ * and thus we need to depend on {@link BlazeDirectories} somehow, which neither the configuration
+ * nor the analysis phase can "officially" do.
+ *
+ * <p>The fix is probably to make it possible for {@link
+ * com.google.devtools.build.lib.analysis.actions.SymlinkAction} to create workspace-relative
+ * symlinks because action execution can hopefully depend on {@link BlazeDirectories}.
+ *
+ * <p>There is also the awful and incorrect {@link Path#exists()} call in {@link
+ * com.google.devtools.build.lib.view.proto.CcProtoProfileProvider#getProfile(
+ * com.google.devtools.build.lib.analysis.RuleContext)} which needs a {@link Path}.
+ */
+public class CcSkyframeFdoSupportFunction implements SkyFunction {
+
+  private final BlazeDirectories directories;
+
+  public CcSkyframeFdoSupportFunction(BlazeDirectories directories) {
+    this.directories = Preconditions.checkNotNull(directories);
+  }
+
+  @Nullable
+  @Override
+  public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException {
+    CcSkyframeFdoSupportValue.Key key = (CcSkyframeFdoSupportValue.Key) skyKey.argument();
+    Path fdoZipPath = null;
+    if (key.getFdoZipPath() != null) {
+      fdoZipPath = directories.getWorkspace().getRelative(key.getFdoZipPath());
+    }
+    return new CcSkyframeFdoSupportValue(fdoZipPath);
+  }
+
+  @Nullable
+  @Override
+  public String extractTag(SkyKey skyKey) {
+    return null;
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeSupportValue.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeFdoSupportValue.java
similarity index 62%
rename from src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeSupportValue.java
rename to src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeFdoSupportValue.java
index d5ece4b..09489ba 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeSupportValue.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkyframeFdoSupportValue.java
@@ -14,60 +14,49 @@
 package com.google.devtools.build.lib.rules.cpp;
 
 import com.google.common.collect.Interner;
-import com.google.devtools.build.lib.cmdline.PackageIdentifier;
 import com.google.devtools.build.lib.concurrent.BlazeInterners;
 import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.devtools.build.lib.vfs.Path;
 import com.google.devtools.build.lib.vfs.PathFragment;
-import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CrosstoolRelease;
 import com.google.devtools.build.skyframe.SkyFunction;
 import com.google.devtools.build.skyframe.SkyFunctionName;
 import com.google.devtools.build.skyframe.SkyKey;
 import com.google.devtools.build.skyframe.SkyValue;
 import java.util.Objects;
-import javax.annotation.Nullable;
 
 /**
  * A container for the path to the FDO profile.
  *
- * <p>{@link CcSkyframeSupportValue} is created from {@link CcSkyframeSupportFunction} (a {@link
- * SkyFunction}), which is requested from Skyframe by the {@code cc_toolchain}/{@code
+ * <p>{@link CcSkyframeFdoSupportValue} is created from {@link CcSkyframeFdoSupportFunction} (a
+ * {@link SkyFunction}), which is requested from Skyframe by the {@code cc_toolchain}/{@code
  * cc_toolchain_suite} rules. It's done this way because the path depends on both a command line
  * argument and the location of the workspace and the latter is not available either during
  * configuration creation or during the analysis phase.
  */
 @AutoCodec
 @Immutable
-public class CcSkyframeSupportValue implements SkyValue {
+public class CcSkyframeFdoSupportValue implements SkyValue {
   public static final SkyFunctionName SKYFUNCTION = SkyFunctionName.createHermetic("FDO_SUPPORT");
 
-  /** {@link SkyKey} for {@link CcSkyframeSupportValue}. */
+  /** {@link SkyKey} for {@link CcSkyframeFdoSupportValue}. */
   @Immutable
   @AutoCodec
   public static class Key implements SkyKey {
     private static final Interner<Key> interner = BlazeInterners.newWeakInterner();
 
-    @Nullable private final PathFragment fdoZipPath;
-    @Nullable private final PackageIdentifier packageWithCrosstoolInIt;
+    private final PathFragment fdoZipPath;
 
-    private Key(PathFragment fdoZipPath, PackageIdentifier packageWithCrosstoolInIt) {
+    private Key(PathFragment fdoZipPath) {
       this.fdoZipPath = fdoZipPath;
-      this.packageWithCrosstoolInIt = packageWithCrosstoolInIt;
     }
 
     @AutoCodec.Instantiator
     @AutoCodec.VisibleForSerialization
-    static Key of(PathFragment fdoZipPath, PackageIdentifier packageWithCrosstoolInIt) {
-      return interner.intern(new Key(fdoZipPath, packageWithCrosstoolInIt));
+    static Key of(PathFragment fdoZipPath) {
+      return interner.intern(new Key(fdoZipPath));
     }
 
-    @Nullable
-    public PackageIdentifier getPackageWithCrosstoolInIt() {
-      return packageWithCrosstoolInIt;
-    }
-
-    @Nullable
     public PathFragment getFdoZipPath() {
       return fdoZipPath;
     }
@@ -81,14 +70,13 @@
         return false;
       }
       Key key = (Key) o;
-      return Objects.equals(fdoZipPath, key.fdoZipPath)
-          && Objects.equals(packageWithCrosstoolInIt, key.packageWithCrosstoolInIt);
+      return Objects.equals(fdoZipPath, key.fdoZipPath);
     }
 
     @Override
     public int hashCode() {
 
-      return Objects.hash(fdoZipPath, packageWithCrosstoolInIt);
+      return Objects.hash(fdoZipPath);
     }
 
     @Override
@@ -103,22 +91,15 @@
   // This is all ridiculously incorrect and should be removed asap.
   private final Path fdoZipPath;
 
-  private final CrosstoolRelease crosstoolRelease;
-
-  CcSkyframeSupportValue(Path fdoZipPath, CrosstoolRelease crosstoolRelease) {
+  CcSkyframeFdoSupportValue(Path fdoZipPath) {
     this.fdoZipPath = fdoZipPath;
-    this.crosstoolRelease = crosstoolRelease;
   }
 
   public Path getFdoZipPath() {
     return fdoZipPath;
   }
 
-  public CrosstoolRelease getCrosstoolRelease() {
-    return crosstoolRelease;
-  }
-
-  public static SkyKey key(PathFragment fdoZipPath, PackageIdentifier packageWithCrosstoolInIt) {
-    return Key.of(fdoZipPath, packageWithCrosstoolInIt);
+  public static SkyKey key(PathFragment fdoZipPath) {
+    return Key.of(fdoZipPath);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderHelper.java
index 444aa7f..bcce9c6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProviderHelper.java
@@ -35,7 +35,7 @@
 import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
 import com.google.devtools.build.lib.collect.nestedset.Order;
 import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
-import com.google.devtools.build.lib.rules.cpp.CcSkyframeSupportFunction.CcSkyframeSupportException;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeCrosstoolSupportFunction.CcSkyframeCrosstoolSupportException;
 import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
 import com.google.devtools.build.lib.rules.cpp.FdoContext.BranchFdoMode;
 import com.google.devtools.build.lib.syntax.EvalException;
@@ -400,9 +400,23 @@
       protoProfileArtifact = fdoInputs.getSecond();
     }
 
-    CcSkyframeSupportValue ccSkyframeSupportValue = null;
-    SkyKey ccSupportKey = null;
+    if (fdoZip != null) {
+      SkyKey fdoKey = CcSkyframeFdoSupportValue.key(fdoZip);
+      SkyFunction.Environment skyframeEnv = ruleContext.getAnalysisEnvironment().getSkyframeEnv();
+      CcSkyframeFdoSupportValue ccSkyframeFdoSupportValue =
+          (CcSkyframeFdoSupportValue) skyframeEnv.getValue(fdoKey);
+      if (skyframeEnv.valuesMissing()) {
+        return null;
+      }
+      // fdoZip should be set if the profile is a path, fdoInputFile if it is an artifact, but
+      // never both
+      Preconditions.checkState(fdoInputFile == null);
+      fdoInputFile =
+          FdoInputFile.fromAbsolutePath(ccSkyframeFdoSupportValue.getFdoZipPath().asFragment());
+    }
+
     CToolchain toolchain = null;
+    CrosstoolRelease crosstoolFromCrosstoolFile = null;
 
     if (cppConfiguration.disableCrosstool() && attributes.getCcToolchainConfigInfo() == null) {
       ruleContext.ruleError(
@@ -410,43 +424,31 @@
               + "https://github.com/bazelbuild/bazel/issues/7320 for details.");
     }
 
-    if (attributes.getCcToolchainConfigInfo() != null) {
-      if (fdoZip != null) {
-        ccSupportKey = CcSkyframeSupportValue.key(fdoZip, /* packageWithCrosstoolInIt= */ null);
-      }
-    } else {
+    if (attributes.getCcToolchainConfigInfo() == null) {
       // Is there a toolchain proto available on the target directly?
       toolchain = parseToolchainFromAttributes(ruleContext, attributes);
       PackageIdentifier packageWithCrosstoolInIt = null;
       if (toolchain == null && crosstoolFromCcToolchainSuiteProtoAttribute == null) {
         packageWithCrosstoolInIt = ruleContext.getLabel().getPackageIdentifier();
       }
-      if (packageWithCrosstoolInIt != null || fdoZip != null) {
-        ccSupportKey = CcSkyframeSupportValue.key(fdoZip, packageWithCrosstoolInIt);
-      }
-    }
-    if (ccSupportKey != null) {
-      SkyFunction.Environment skyframeEnv = ruleContext.getAnalysisEnvironment().getSkyframeEnv();
-      try {
-        ccSkyframeSupportValue =
-            (CcSkyframeSupportValue)
-                skyframeEnv.getValueOrThrow(ccSupportKey, CcSkyframeSupportException.class);
-      } catch (CcSkyframeSupportException e) {
-        throw ruleContext.throwWithRuleError(e.getMessage());
-      }
-      if (skyframeEnv.valuesMissing()) {
-        return null;
+      if (packageWithCrosstoolInIt != null) {
+        SkyKey crosstoolKey = CcSkyframeCrosstoolSupportValue.key(packageWithCrosstoolInIt);
+        SkyFunction.Environment skyframeEnv = ruleContext.getAnalysisEnvironment().getSkyframeEnv();
+        try {
+          CcSkyframeCrosstoolSupportValue ccSkyframeCrosstoolSupportValue =
+              (CcSkyframeCrosstoolSupportValue)
+                  skyframeEnv.getValueOrThrow(
+                      crosstoolKey, CcSkyframeCrosstoolSupportException.class);
+          if (skyframeEnv.valuesMissing()) {
+            return null;
+          }
+          crosstoolFromCrosstoolFile = ccSkyframeCrosstoolSupportValue.getCrosstoolRelease();
+        } catch (CcSkyframeCrosstoolSupportException e) {
+          throw ruleContext.throwWithRuleError(e.getMessage());
+        }
       }
     }
 
-    if (fdoZip != null) {
-      // fdoZip should be set if the profile is a path, fdoInputFile if it is an artifact, but never
-      // both
-      Preconditions.checkState(fdoInputFile == null);
-      fdoInputFile =
-          FdoInputFile.fromAbsolutePath(ccSkyframeSupportValue.getFdoZipPath().asFragment());
-    }
-    
     CppToolchainInfo toolchainInfo =
         getCppToolchainInfo(
             ruleContext,
@@ -455,7 +457,7 @@
             cppConfiguration.getTransformedCpuFromOptions(),
             cppConfiguration.getCompilerFromOptions(),
             attributes,
-            ccSkyframeSupportValue,
+            crosstoolFromCrosstoolFile,
             toolchain,
             crosstoolFromCcToolchainSuiteProtoAttribute);
 
@@ -685,7 +687,7 @@
       String cpuFromOptions,
       String compilerFromOptions,
       CcToolchainAttributesProvider attributes,
-      CcSkyframeSupportValue ccSkyframeSupportValue,
+      CrosstoolRelease crosstoolFromCrosstoolFile,
       CToolchain toolchainFromCcToolchainAttribute,
       CrosstoolRelease crosstoolFromCcToolchainSuiteProtoAttribute)
       throws RuleErrorException, InterruptedException {
@@ -714,7 +716,7 @@
               cpuFromOptions,
               compilerFromOptions,
               crosstoolFromCcToolchainSuiteProtoAttribute,
-              ccSkyframeSupportValue);
+              crosstoolFromCrosstoolFile);
     }
 
     // If we found a toolchain, use it.
@@ -763,7 +765,7 @@
       String cpuFromOptions,
       String compilerFromOptions,
       CrosstoolRelease crosstoolFromCcToolchainSuiteProtoAttribute,
-      CcSkyframeSupportValue ccSkyframeSupportValue)
+      CrosstoolRelease crosstoolFromCrosstoolFile)
       throws RuleErrorException {
     try {
       CrosstoolRelease crosstoolRelease;
@@ -772,7 +774,7 @@
         crosstoolRelease = crosstoolFromCcToolchainSuiteProtoAttribute;
       } else {
         // We use the proto from the CROSSTOOL file
-        crosstoolRelease = ccSkyframeSupportValue.getCrosstoolRelease();
+        crosstoolRelease = crosstoolFromCrosstoolFile;
       }
 
       return CToolchainSelectionUtils.selectCToolchain(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java
index cd5c580..2f7483b 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainSuite.java
@@ -56,7 +56,7 @@
     if (ruleContext.attributes().isAttributeValueExplicitlySpecified("proto")) {
       try {
         crosstoolFromProtoAttribute =
-            CcSkyframeSupportFunction.toReleaseConfiguration(
+            CcSkyframeCrosstoolSupportFunction.toReleaseConfiguration(
                 ruleContext.attributes().get("proto", Type.STRING));
       } catch (InvalidConfigurationException e) {
         ruleContext.throwWithRuleError(e.getMessage());
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
index aeb658f..c7084db 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
@@ -26,8 +26,10 @@
 import com.google.devtools.build.lib.packages.util.MockCcSupport;
 import com.google.devtools.build.lib.packages.util.MockPythonSupport;
 import com.google.devtools.build.lib.packages.util.MockToolsConfig;
-import com.google.devtools.build.lib.rules.cpp.CcSkyframeSupportFunction;
-import com.google.devtools.build.lib.rules.cpp.CcSkyframeSupportValue;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeCrosstoolSupportFunction;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeCrosstoolSupportValue;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeFdoSupportFunction;
+import com.google.devtools.build.lib.rules.cpp.CcSkyframeFdoSupportValue;
 import com.google.devtools.build.lib.rules.repository.LocalRepositoryFunction;
 import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule;
 import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
@@ -132,8 +134,10 @@
             directories),
         SkyFunctions.REPOSITORY,
         new RepositoryLoaderFunction(),
-        CcSkyframeSupportValue.SKYFUNCTION,
-        new CcSkyframeSupportFunction(directories));
+        CcSkyframeFdoSupportValue.SKYFUNCTION,
+        new CcSkyframeFdoSupportFunction(directories),
+        CcSkyframeCrosstoolSupportValue.SKYFUNCTION,
+        new CcSkyframeCrosstoolSupportFunction());
   }
 
   // Allow subclasses to add extra repository functions.