//===-- NVPTXTargetMachine.cpp - Define TargetMachine for NVPTX -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Top-level implementation for the NVPTX target.
//
//===----------------------------------------------------------------------===//

#include "NVPTXTargetMachine.h"
#include "NVPTX.h"
#include "NVPTXAliasAnalysis.h"
#include "NVPTXMachineFunctionInfo.h"
#include "NVPTXTargetObjectFile.h"
#include "NVPTXTargetTransformInfo.h"
#include "TargetInfo/NVPTXTargetInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/IntrinsicsNVPTX.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/IPO/ExpandVariadics.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVN.h"
#include "llvm/Transforms/Vectorize/LoadStoreVectorizer.h"
#include <cassert>
#include <optional>
#include <string>

using namespace llvm;

// LSV is still relatively new; this switch lets us turn it off in case we
// encounter (or suspect) a bug.
cl::opt<bool>
    DisableLoadStoreVectorizer("disable-nvptx-load-store-vectorizer",
                               cl::desc("Disable load/store vectorizer"),
                               cl::init(false), cl::Hidden);

// NVPTX IR Peephole is a new pass; this option will lets us turn it off in case
// we encounter some issues.
cl::opt<bool> DisableNVPTXIRPeephole("disable-nvptx-ir-peephole",
                                     cl::desc("Disable NVPTX IR Peephole"),
                                     cl::init(false), cl::Hidden);

// TODO: Remove this flag when we are confident with no regressions.
static cl::opt<bool> DisableRequireStructuredCFG(
    "disable-nvptx-require-structured-cfg",
    cl::desc("Transitional flag to turn off NVPTX's requirement on preserving "
             "structured CFG. The requirement should be disabled only when "
             "unexpected regressions happen."),
    cl::init(false), cl::Hidden);

extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeNVPTXTarget() {
  // Register the target.
  RegisterTargetMachine<NVPTXTargetMachine> X(getTheNVPTXTarget32());
  RegisterTargetMachine<NVPTXTargetMachine> Y(getTheNVPTXTarget64());

  PassRegistry &PR = *PassRegistry::getPassRegistry();
  // FIXME: This pass is really intended to be invoked during IR optimization,
  // but it's very NVPTX-specific.
  initializeNVVMReflectLegacyPassPass(PR);
  initializeNVVMIntrRangePass(PR);
  initializeGenericToNVVMLegacyPassPass(PR);
  initializeNVPTXAllocaHoistingLegacyPassPass(PR);
  initializeNVPTXAsmPrinterPass(PR);
  initializeNVPTXAssignValidGlobalNamesLegacyPassPass(PR);
  initializeNVPTXAtomicLowerLegacyPassPass(PR);
  initializeNVPTXLowerArgsLegacyPassPass(PR);
  initializeNVPTXPromoteParamAlignLegacyPassPass(PR);
  initializeNVPTXMarkKernelPtrsGlobalLegacyPassPass(PR);
  initializeNVPTXLowerAllocaLegacyPassPass(PR);
  initializeNVPTXLowerUnreachableLegacyPassPass(PR);
  initializeNVPTXCtorDtorLoweringLegacyPass(PR);
  initializeNVPTXLowerAggrCopiesLegacyPassPass(PR);
  initializeNVPTXProxyRegErasureLegacyPassPass(PR);
  initializeNVPTXForwardParamsLegacyPassPass(PR);
  initializeNVPTXAddressFolderLegacyPassPass(PR);
  initializeNVPTXDAGToDAGISelLegacyPass(PR);
  initializeNVPTXAAWrapperPassPass(PR);
  initializeNVPTXExternalAAWrapperPass(PR);
  initializeNVPTXPeepholeLegacyPassPass(PR);
  initializeNVPTXTagInvariantLoadLegacyPassPass(PR);
  initializeNVPTXIRPeepholePass(PR);
  initializeNVPTXPrologEpilogLegacyPassPass(PR);
}

NVPTXTargetMachine::NVPTXTargetMachine(const Target &T, const Triple &TT,
                                       StringRef CPU, StringRef FS,
                                       const TargetOptions &Options,
                                       std::optional<Reloc::Model> RM,
                                       std::optional<CodeModel::Model> CM,
                                       CodeGenOptLevel OL, bool JIT)
    // The pic relocation model is used regardless of what the client has
    // specified, as it is the only relocation model currently supported.
    : CodeGenTargetMachineImpl(T, TT, CPU, FS, Options, Reloc::PIC_,
                               getEffectiveCodeModel(CM, CodeModel::Small), OL),
      TLOF(std::make_unique<NVPTXTargetObjectFile>()),
      Subtarget(TT, CPU, FS, *this) {
  if (!DisableRequireStructuredCFG)
    setRequiresStructuredCFG(true);
  // NVPTX does not produce verifier-clean MIR yet; see isMachineVerifierClean()
  // for the legacy pass manager equivalent.
  setEnableDefaultMachineVerifier(false);
  initAsmInfo();
}

NVPTXTargetMachine::~NVPTXTargetMachine() = default;

namespace {

/// NVPTXPassConfig mirrors the NewPM implementation in NVPTXCodeGenPassBuilder
/// in NVPTXCodeGenPassBuilder.cpp; the two must be kept in sync until this path
/// is removed.
class NVPTXPassConfig : public TargetPassConfig {
public:
  NVPTXPassConfig(NVPTXTargetMachine &TM, PassManagerBase &PM)
      : TargetPassConfig(TM, PM) {}

  NVPTXTargetMachine &getNVPTXTargetMachine() const {
    return getTM<NVPTXTargetMachine>();
  }

  void addIRPasses() override;
  bool addInstSelector() override;
  void addPreRegAlloc() override;
  void addPostRegAlloc() override;

  FunctionPass *createTargetRegisterAllocator(bool) override;
  void addFastRegAlloc() override;
  void addOptimizedRegAlloc() override;

  bool addRegAssignAndRewriteFast() override {
    llvm_unreachable("should not be used");
  }

  bool addRegAssignAndRewriteOptimized() override {
    llvm_unreachable("should not be used");
  }

private:
  // If the opt level is aggressive, add GVN; otherwise, add EarlyCSE. This
  // function is only called in opt mode.
  void addEarlyCSEOrGVNPass();

  // Add passes that propagate special memory spaces.
  void addAddressSpaceInferencePasses();

  // Add passes that perform straight-line scalar optimizations.
  void addStraightLineScalarOptimizationPasses();
};

} // end anonymous namespace

TargetPassConfig *NVPTXTargetMachine::createPassConfig(PassManagerBase &PM) {
  return new NVPTXPassConfig(*this, PM);
}

MachineFunctionInfo *NVPTXTargetMachine::createMachineFunctionInfo(
    BumpPtrAllocator &Allocator, const Function &F,
    const TargetSubtargetInfo *STI) const {
  return NVPTXMachineFunctionInfo::create<NVPTXMachineFunctionInfo>(Allocator,
                                                                    F, STI);
}

void NVPTXTargetMachine::registerEarlyDefaultAliasAnalyses(AAManager &AAM) {
  AAM.registerFunctionAnalysis<NVPTXAA>();
}

TargetTransformInfo
NVPTXTargetMachine::getTargetTransformInfo(const Function &F) const {
  return TargetTransformInfo(std::make_unique<NVPTXTTIImpl>(this, F));
}

std::pair<const Value *, unsigned>
NVPTXTargetMachine::getPredicatedAddrSpace(const Value *V) const {
  if (auto *II = dyn_cast<IntrinsicInst>(V)) {
    switch (II->getIntrinsicID()) {
    case Intrinsic::nvvm_isspacep_const:
      return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_CONST);
    case Intrinsic::nvvm_isspacep_global:
      return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_GLOBAL);
    case Intrinsic::nvvm_isspacep_local:
      return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_LOCAL);
    case Intrinsic::nvvm_isspacep_shared:
      return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_SHARED);
    case Intrinsic::nvvm_isspacep_shared_cluster:
      return std::make_pair(II->getArgOperand(0),
                            llvm::ADDRESS_SPACE_SHARED_CLUSTER);
    default:
      break;
    }
  }
  return std::make_pair(nullptr, -1);
}

void NVPTXPassConfig::addEarlyCSEOrGVNPass() {
  if (getOptLevel() == CodeGenOptLevel::Aggressive)
    // Disable scalar PRE due to Register Pressure increase
    addPass(createGVNPass(/*ScalarPRE=*/false));
  else
    addPass(createEarlyCSEPass());
}

void NVPTXPassConfig::addAddressSpaceInferencePasses() {
  // NVPTXLowerArgs emits alloca for byval parameters which can often
  // be eliminated by SROA.
  addPass(createSROAPass(/*PreserveCFG=*/true,
                         /*AggregateToVector=*/true));
  addPass(createNVPTXLowerAllocaLegacyPass());
  // TODO: Consider running InferAddressSpaces during opt, earlier in the
  // compilation flow.
  addPass(createInferAddressSpacesPass());
  addPass(createNVPTXAtomicLowerLegacyPass());
}

void NVPTXPassConfig::addStraightLineScalarOptimizationPasses() {
  addPass(createSeparateConstOffsetFromGEPPass());
  addPass(createSpeculativeExecutionPass());
  // ReassociateGEPs exposes more opportunites for SLSR. See
  // the example in reassociate-geps-and-slsr.ll.
  addPass(createStraightLineStrengthReducePass());
  // SeparateConstOffsetFromGEP and SLSR creates common expressions which GVN or
  // EarlyCSE can reuse. GVN generates significantly better code than EarlyCSE
  // for some of our benchmarks.
  addEarlyCSEOrGVNPass();
  // Run NaryReassociate after EarlyCSE/GVN to be more effective.
  addPass(createNaryReassociatePass());
  // NaryReassociate on GEPs creates redundant common expressions, so run
  // EarlyCSE after it.
  addPass(createEarlyCSEPass());
}

void NVPTXPassConfig::addIRPasses() {
  // The following passes are known to not play well with virtual regs hanging
  // around after register allocation (which in our case, is *all* registers).
  // We explicitly disable them here.  We do, however, need some functionality
  // of the PrologEpilogCodeInserter pass, so we emulate that behavior in the
  // NVPTXPrologEpilog pass (see NVPTXPrologEpilogPass.cpp).
  disablePass(&PrologEpilogCodeInserterID);
  disablePass(&MachineLateInstrsCleanupID);
  disablePass(&MachineCopyPropagationID);
  disablePass(&TailDuplicateLegacyID);
  disablePass(&StackMapLivenessID);
  disablePass(&PostRAMachineSinkingID);
  disablePass(&PostRASchedulerID);
  disablePass(&FuncletLayoutID);
  disablePass(&PatchableFunctionID);
  disablePass(&ShrinkWrapID);
  disablePass(&RemoveLoadsIntoFakeUsesID);

  addPass(createNVPTXAAWrapperPass());
  addPass(createNVPTXExternalAAWrapperPass());

  // NVVMReflectPass is added in addEarlyAsPossiblePasses, so hopefully running
  // it here does nothing.  But since we need it for correctness when lowering
  // to NVPTX, run it here too, in case whoever built our pass pipeline didn't
  // call addEarlyAsPossiblePasses.
  const NVPTXSubtarget &ST = *getTM<NVPTXTargetMachine>().getSubtargetImpl();
  addPass(createNVVMReflectPass(ST.getSmVersion()));

  if (getOptLevel() != CodeGenOptLevel::None)
    addPass(createNVPTXImageOptimizerLegacyPass());
  addPass(createNVPTXAssignValidGlobalNamesLegacyPass());
  addPass(createGenericToNVVMLegacyPass());

  // Lower variadic calls before address space inference.
  addPass(createExpandVariadicsPass(ExpandVariadicsMode::Lowering));

  // NVPTXLowerArgs is required for correctness and should be run right
  // before the address space inference passes.
  if (getNVPTXTargetMachine().getDrvInterface() == NVPTX::CUDA)
    addPass(createNVPTXMarkKernelPtrsGlobalPass());
  addPass(createNVPTXPromoteParamAlignPass());
  addPass(createNVPTXLowerArgsPass());
  if (getOptLevel() != CodeGenOptLevel::None) {
    addAddressSpaceInferencePasses();
    addStraightLineScalarOptimizationPasses();
  } else {
    // Required for correct stack lowering
    addPass(createNVPTXLowerAllocaLegacyPass());
  }

  addPass(createAtomicExpandLegacyPass());
  addPass(createNVPTXCtorDtorLoweringLegacyPass());

  // === LSR and other generic IR passes ===
  TargetPassConfig::addIRPasses();
  // EarlyCSE is not always strong enough to clean up what LSR produces. For
  // example, GVN can combine
  //
  //   %0 = add %a, %b
  //   %1 = add %b, %a
  //
  // and
  //
  //   %0 = shl nsw %a, 2
  //   %1 = shl %a, 2
  //
  // but EarlyCSE can do neither of them.
  if (getOptLevel() != CodeGenOptLevel::None) {
    addEarlyCSEOrGVNPass();
    if (!DisableLoadStoreVectorizer)
      addPass(createLoadStoreVectorizerPass());
    addPass(createSROAPass(/*PreserveCFG=*/true,
                           /*AggregateToVector=*/true));
    addPass(createNVPTXTagInvariantLoadsPass());
    if (!DisableNVPTXIRPeephole)
      addPass(createNVPTXIRPeepholePass());
  }

  if (ST.hasPTXASUnreachableBug()) {
    // Run LowerUnreachable to WAR a ptxas bug. See the commit description of
    // 1ee4d880e8760256c606fe55b7af85a4f70d006d for more details.
    const auto &Options = getNVPTXTargetMachine().Options;
    addPass(createNVPTXLowerUnreachableLegacyPass(Options.TrapUnreachable,
                                                  Options.NoTrapAfterNoreturn));
  }
}

bool NVPTXPassConfig::addInstSelector() {
  addPass(createNVPTXLowerAggrCopiesLegacyPass());
  addPass(createNVPTXAllocaHoistingLegacyPass());
  addPass(createNVPTXISelDag(getNVPTXTargetMachine(), getOptLevel()));
  addPass(createNVPTXReplaceImageHandlesLegacyPass());

  return false;
}

void NVPTXPassConfig::addPreRegAlloc() {
  addPass(createNVPTXForwardParamsLegacyPass());
  if (getOptLevel() != CodeGenOptLevel::None)
    addPass(createNVPTXAddressFolderLegacyPass());
  // Remove Proxy Register pseudo instructions used to keep `callseq_end` alive.
  addPass(createNVPTXProxyRegErasureLegacyPass());
}

void NVPTXPassConfig::addPostRegAlloc() {
  addPass(createNVPTXPrologEpilogLegacyPass());
  if (getOptLevel() != CodeGenOptLevel::None) {
    // NVPTXPrologEpilogPass calculates frame object offset and replace frame
    // index with VRFrame register. NVPTXPeephole need to be run after that and
    // will replace VRFrame with VRFrameLocal when possible.
    addPass(createNVPTXPeepholeLegacyPass());
  }
}

FunctionPass *NVPTXPassConfig::createTargetRegisterAllocator(bool) {
  return nullptr; // No reg alloc
}

void NVPTXPassConfig::addFastRegAlloc() {
  addPass(&PHIEliminationID);
  addPass(&TwoAddressInstructionPassID);
}

void NVPTXPassConfig::addOptimizedRegAlloc() {
  addPass(&ProcessImplicitDefsID);
  addPass(&MachineLoopInfoID);
  addPass(&PHIEliminationID);

  addPass(&TwoAddressInstructionPassID);
  addPass(&RegisterCoalescerID);

  // PreRA instruction scheduling.
  if (addPass(&MachineSchedulerID))
    printAndVerify("After Machine Scheduling");

  addPass(&StackSlotColoringID);

  // FIXME: Needs physical registers
  // addPass(&MachineLICMID);

  printAndVerify("After StackSlotColoring");
}
