// Copyright 2015 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.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
import com.google.devtools.build.lib.actions.CommandLine;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.analysis.RuleErrorConsumer;
import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.ExpansionException;
import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration;
import com.google.devtools.build.lib.rules.cpp.CppConfiguration.Tool;
import com.google.devtools.build.lib.rules.cpp.CppLinkAction.LinkArtifactFactory;
import com.google.devtools.build.lib.starlarkbuildapi.cpp.LtoBackendArtifactsApi;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
import net.starlark.java.eval.EvalException;
import net.starlark.java.eval.StarlarkThread;

/**
 * LtoBackendArtifacts represents a set of artifacts for a single ThinLTO backend compile.
 *
 * <p>ThinLTO expands the traditional 2 step compile (N x compile .cc, 1x link (N .o files) into a 4
 * step process:
 *
 * <ul>
 *   <li>1. Bitcode generation (N times). This is produces intermediate LLVM bitcode from a source
 *       file. For this product, it reuses the .o extension.
 *   <li>2. Indexing (once on N files). This takes all bitcode .o files, and for each .o file, it
 *       decides from which other .o files symbols can be inlined. In addition, it generates an
 *       index for looking up these symbols, and an imports file for identifying new input files for
 *       each step 3 {@link LtoBackendAction}.
 *   <li>3. Backend compile (N times). This is the traditional compilation, and uses the same
 *       command line as the Bitcode generation in 1). Since the compiler has many bit code files
 *       available, it can inline functions and propagate constants across .o files. This step is
 *       costly, as it will do traditional optimization. The result is a .lto.o file, a traditional
 *       ELF object file.
 *   <li>4. Backend link (once). This is the traditional link, and produces the final executable.
 * </ul>
 */
public final class LtoBackendArtifacts implements LtoBackendArtifactsApi<Artifact> {

  // A file containing mapping of symbol => bitcode file containing the symbol.
  // It will be null when this is a shared non-lto backend.
  @Nullable private final Artifact index;

  // The bitcode file which is the input of the compile.
  private final Artifact bitcodeFile;

  // A file containing a list of bitcode files necessary to run the backend step.
  // It will be null when this is a shared non-lto backend.
  @Nullable private final Artifact imports;

  // The result of executing the above command line, an ELF object file.
  private final Artifact objectFile;

  // The corresponding dwoFile if fission is used.
  private Artifact dwoFile;

  LtoBackendArtifacts(
      RuleErrorConsumer ruleErrorConsumer,
      BuildOptions buildOptions,
      CppConfiguration cppConfiguration,
      PathFragment ltoOutputRootPrefix,
      Artifact bitcodeFile,
      BitcodeFiles allBitcodeFiles,
      ActionConstructionContext actionConstructionContext,
      RepositoryName repositoryName,
      BuildConfiguration configuration,
      LinkArtifactFactory linkArtifactFactory,
      FeatureConfiguration featureConfiguration,
      CcToolchainProvider ccToolchain,
      FdoContext fdoContext,
      boolean usePic,
      boolean generateDwo,
      List<String> userCompileFlags)
      throws RuleErrorException {
    this.bitcodeFile = bitcodeFile;
    PathFragment obj =
        ltoOutputRootPrefix.getRelative(
            bitcodeFile.getOutputDirRelativePath(configuration.isSiblingRepositoryLayout()));

    objectFile =
        linkArtifactFactory.create(actionConstructionContext, repositoryName, configuration, obj);
    imports =
        linkArtifactFactory.create(
            actionConstructionContext,
            repositoryName,
            configuration,
            FileSystemUtils.appendExtension(obj, ".imports"));
    index =
        linkArtifactFactory.create(
            actionConstructionContext,
            repositoryName,
            configuration,
            FileSystemUtils.appendExtension(obj, ".thinlto.bc"));

    scheduleLtoBackendAction(
        ruleErrorConsumer,
        buildOptions,
        cppConfiguration,
        actionConstructionContext,
        repositoryName,
        featureConfiguration,
        ccToolchain,
        fdoContext,
        usePic,
        generateDwo,
        configuration,
        linkArtifactFactory,
        userCompileFlags,
        allBitcodeFiles);
  }

  // Interface to create an LTO backend that does not perform any cross-module optimization.
  public LtoBackendArtifacts(
      RuleErrorConsumer ruleErrorConsumer,
      BuildOptions buildOptions,
      CppConfiguration cppConfiguration,
      PathFragment ltoOutputRootPrefix,
      Artifact bitcodeFile,
      ActionConstructionContext actionConstructionContext,
      RepositoryName repositoryName,
      BuildConfiguration configuration,
      LinkArtifactFactory linkArtifactFactory,
      FeatureConfiguration featureConfiguration,
      CcToolchainProvider ccToolchain,
      FdoContext fdoContext,
      boolean usePic,
      boolean generateDwo,
      List<String> userCompileFlags)
      throws RuleErrorException {
    this.bitcodeFile = bitcodeFile;

    PathFragment obj =
        ltoOutputRootPrefix.getRelative(
            bitcodeFile.getOutputDirRelativePath(configuration.isSiblingRepositoryLayout()));
    objectFile =
        linkArtifactFactory.create(actionConstructionContext, repositoryName, configuration, obj);
    imports = null;
    index = null;

    scheduleLtoBackendAction(
        ruleErrorConsumer,
        buildOptions,
        cppConfiguration,
        actionConstructionContext,
        repositoryName,
        featureConfiguration,
        ccToolchain,
        fdoContext,
        usePic,
        generateDwo,
        configuration,
        linkArtifactFactory,
        userCompileFlags,
        /*bitcodeFiles=*/ null);
  }

  public Artifact getObjectFile() {
    return objectFile;
  }

  @Override
  public Artifact getObjectFileForStarlark(StarlarkThread thread) throws EvalException {
    CcModule.checkPrivateStarlarkificationAllowlist(thread);
    return objectFile;
  }

  Artifact getBitcodeFile() {
    return bitcodeFile;
  }

  public Artifact getDwoFile() {
    return dwoFile;
  }

  void addIndexingOutputs(ImmutableSet.Builder<Artifact> builder) {
    // For objects from linkstatic libraries, we may not be including them in the LTO indexing
    // step when linked into a test, but rather will use shared non-LTO backends for better
    // scalability when running large numbers of tests.
    if (index == null) {
      return;
    }
    builder.add(imports);
    builder.add(index);
  }

  private void scheduleLtoBackendAction(
      RuleErrorConsumer ruleErrorConsumer,
      BuildOptions buildOptions,
      CppConfiguration cppConfiguration,
      ActionConstructionContext actionConstructionContext,
      RepositoryName repositoryName,
      FeatureConfiguration featureConfiguration,
      CcToolchainProvider ccToolchain,
      FdoContext fdoContext,
      boolean usePic,
      boolean generateDwo,
      BuildConfiguration configuration,
      LinkArtifactFactory linkArtifactFactory,
      List<String> userCompileFlags,
      @Nullable BitcodeFiles bitcodeFiles)
      throws RuleErrorException {
    LtoBackendAction.Builder builder = new LtoBackendAction.Builder();

    builder.addInput(bitcodeFile);

    Preconditions.checkState(
        (index == null) == (imports == null),
        "Either both or neither index and imports files should be null");
    if (imports != null) {
      builder.addImportsInfo(bitcodeFiles, imports);
      // Although the imports file is not used by the LTOBackendAction while the action is
      // executing, it is needed during the input discovery phase, and we must list it as an input
      // to the action in order for it to be preserved under --discard_orphaned_artifacts.
      builder.addInput(imports);
    }
    if (index != null) {
      builder.addInput(index);
    }
    builder.addTransitiveInputs(ccToolchain.getCompilerFiles());

    builder.addOutput(objectFile);

    builder.setProgressMessage("LTO Backend Compile %s", objectFile.getExecPath());
    builder.setMnemonic("CcLtoBackendCompile");

    CcToolchainVariables.Builder buildVariablesBuilder =
        CcToolchainVariables.builder(ccToolchain.getBuildVariables(buildOptions, cppConfiguration));
    if (index != null) {
      buildVariablesBuilder.addStringVariable("thinlto_index", index.getExecPath().toString());
    } else {
      // An empty input indicates not to perform cross-module optimization.
      buildVariablesBuilder.addStringVariable("thinlto_index", "/dev/null");
    }
    // The output from the LTO backend step is a native object file.
    buildVariablesBuilder.addStringVariable(
        "thinlto_output_object_file", objectFile.getExecPath().toString());
    // The input to the LTO backend step is the bitcode file.
    buildVariablesBuilder.addStringVariable(
        "thinlto_input_bitcode_file", bitcodeFile.getExecPath().toString());
    addProfileForLtoBackend(builder, fdoContext, featureConfiguration, buildVariablesBuilder);
    // Add the context sensitive instrument path to the backend.
    if (featureConfiguration.isEnabled(CppRuleClasses.CS_FDO_INSTRUMENT)) {
      buildVariablesBuilder.addStringVariable(
          CompileBuildVariables.CS_FDO_INSTRUMENT_PATH.getVariableName(),
          ccToolchain.getCSFdoInstrument());
    }

    if (generateDwo) {
      dwoFile =
          linkArtifactFactory.create(
              actionConstructionContext,
              repositoryName,
              configuration,
              FileSystemUtils.replaceExtension(
                  objectFile.getOutputDirRelativePath(configuration.isSiblingRepositoryLayout()),
                  ".dwo"));
      builder.addOutput(dwoFile);
      buildVariablesBuilder.addStringVariable(
          CompileBuildVariables.PER_OBJECT_DEBUG_INFO_FILE.getVariableName(),
          dwoFile.getExecPathString());
      buildVariablesBuilder.addStringVariable(
          CompileBuildVariables.IS_USING_FISSION.getVariableName(), "");
    }
    buildVariablesBuilder.addStringSequenceVariable(
        CompileBuildVariables.USER_COMPILE_FLAGS.getVariableName(), userCompileFlags);

    CcToolchainVariables buildVariables = buildVariablesBuilder.build();

    if (cppConfiguration.useStandaloneLtoIndexingCommandLines()) {
      if (!featureConfiguration.actionIsConfigured(CppActionNames.LTO_BACKEND)) {
        throw ruleErrorConsumer.throwWithRuleError(
            "Thinlto build is requested, but the C++ toolchain doesn't define an action_config for"
                + " 'lto-backend' action.");
      }
      PathFragment compiler =
          PathFragment.create(
              featureConfiguration.getToolPathForAction(CppActionNames.LTO_BACKEND));
      builder.setExecutable(compiler);
    } else {
      PathFragment compiler = ccToolchain.getToolPathFragment(Tool.GCC, ruleErrorConsumer);
      builder.setExecutable(compiler);
    }

    CommandLine ltoCommandLine =
        new CommandLine() {

          @Override
          public Iterable<String> arguments() throws CommandLineExpansionException {
            return arguments(/* artifactExpander= */ null);
          }

          @Override
          public Iterable<String> arguments(ArtifactExpander artifactExpander)
              throws CommandLineExpansionException {
            ImmutableList.Builder<String> args = ImmutableList.builder();
            try {
              args.addAll(
                  featureConfiguration.getCommandLine(
                      CppActionNames.LTO_BACKEND, buildVariables, artifactExpander));
            } catch (ExpansionException e) {
              throw new CommandLineExpansionException(e.getMessage());
            }
            // If this is a PIC compile (set based on the CppConfiguration), the PIC
            // option should be added after the rest of the command line so that it
            // cannot be overridden. This is consistent with the ordering in the
            // CppCompileAction's compiler options.
            if (usePic) {
              args.add("-fPIC");
            }
            return args.build();
          }
        };
    builder.addCommandLine(ltoCommandLine);

    actionConstructionContext.registerAction(builder.build(actionConstructionContext));
  }

  /**
   * Adds the AFDO profile path to the variable builder and the profile tothe inputs of the action.
   */
  @ThreadSafe
  private static void addProfileForLtoBackend(
      LtoBackendAction.Builder builder,
      FdoContext fdoContext,
      FeatureConfiguration featureConfiguration,
      CcToolchainVariables.Builder buildVariables) {
    Artifact prefetch = fdoContext.getPrefetchHintsArtifact();
    if (prefetch != null) {
      buildVariables.addStringVariable("fdo_prefetch_hints_path", prefetch.getExecPathString());
      builder.addInput(fdoContext.getPrefetchHintsArtifact());
    }
    if (fdoContext.getPropellerOptimizeInputFile() != null
        && fdoContext.getPropellerOptimizeInputFile().getCcArtifact() != null) {
      buildVariables.addStringVariable(
          "propeller_optimize_cc_path",
          fdoContext.getPropellerOptimizeInputFile().getCcArtifact().getExecPathString());
      builder.addInput(fdoContext.getPropellerOptimizeInputFile().getCcArtifact());
    }
    if (fdoContext.getPropellerOptimizeInputFile() != null
        && fdoContext.getPropellerOptimizeInputFile().getLdArtifact() != null) {
      buildVariables.addStringVariable(
          "propeller_optimize_ld_path",
          fdoContext.getPropellerOptimizeInputFile().getLdArtifact().getExecPathString());
      builder.addInput(fdoContext.getPropellerOptimizeInputFile().getLdArtifact());
    }
    if (!featureConfiguration.isEnabled(CppRuleClasses.AUTOFDO)
        && !featureConfiguration.isEnabled(CppRuleClasses.CS_FDO_OPTIMIZE)
        && !featureConfiguration.isEnabled(CppRuleClasses.XBINARYFDO)) {
      return;
    }

    FdoContext.BranchFdoProfile branchFdoProfile =
        Preconditions.checkNotNull(fdoContext.getBranchFdoProfile());
    Artifact profile = branchFdoProfile.getProfileArtifact();
    buildVariables.addStringVariable("fdo_profile_path", profile.getExecPathString());
    builder.addInput(branchFdoProfile.getProfileArtifact());
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof LtoBackendArtifacts)) {
      return false;
    }
    LtoBackendArtifacts that = (LtoBackendArtifacts) o;
    return Objects.equals(index, that.index)
        && bitcodeFile.equals(that.bitcodeFile)
        && Objects.equals(imports, that.imports)
        && objectFile.equals(that.objectFile)
        && Objects.equals(dwoFile, that.dwoFile);
  }

  @Override
  public int hashCode() {
    return Objects.hash(index, bitcodeFile, imports, objectFile, dwoFile);
  }
}
