//===-- SystemZTargetMachine.cpp - Define TargetMachine for SystemZ -------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "SystemZTargetMachine.h"
#include "MCTargetDesc/SystemZMCTargetDesc.h"
#include "SystemZ.h"
#include "SystemZMachineFunctionInfo.h"
#include "SystemZMachineScheduler.h"
#include "SystemZTargetObjectFile.h"
#include "SystemZTargetTransformInfo.h"
#include "TargetInfo/SystemZTargetInfo.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Transforms/Scalar.h"
#include <memory>
#include <optional>
#include <string>

using namespace llvm;

static cl::opt<bool> EnableMachineCombinerPass(
    "systemz-machine-combiner",
    cl::desc("Enable the machine combiner pass"),
    cl::init(true), cl::Hidden);

static cl::opt<bool> GenericSched(
    "generic-sched", cl::Hidden, cl::init(false),
    cl::desc("Run the generic pre-ra scheduler instead of the SystemZ "
             "scheduler."));

// NOLINTNEXTLINE(readability-identifier-naming)
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeSystemZTarget() {
  // Register the target.
  RegisterTargetMachine<SystemZTargetMachine> X(getTheSystemZTarget());
  auto &PR = *PassRegistry::getPassRegistry();
  initializeSystemZAsmPrinterPass(PR);
  initializeSystemZElimComparePass(PR);
  initializeSystemZShortenInstPass(PR);
  initializeSystemZLongBranchPass(PR);
  initializeSystemZLDCleanupPass(PR);
  initializeSystemZShortenInstPass(PR);
  initializeSystemZPostRewritePass(PR);
  initializeSystemZTDCPassPass(PR);
  initializeSystemZDAGToDAGISelLegacyPass(PR);
  initializeSystemZCopyPhysRegsPass(PR);
}

static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {
  if (TT.isOSzOS())
    return std::make_unique<TargetLoweringObjectFileGOFF>();

  // Note: Some times run with -triple s390x-unknown.
  // In this case, default to ELF unless z/OS specifically provided.
  return std::make_unique<SystemZELFTargetObjectFile>();
}

static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
  // Static code is suitable for use in a dynamic executable; there is no
  // separate DynamicNoPIC model.
  if (!RM || *RM == Reloc::DynamicNoPIC)
    return Reloc::Static;
  return *RM;
}

// For SystemZ we define the models as follows:
//
// Small:  BRASL can call any function and will use a stub if necessary.
//         Locally-binding symbols will always be in range of LARL.
//
// Medium: BRASL can call any function and will use a stub if necessary.
//         GOT slots and locally-defined text will always be in range
//         of LARL, but other symbols might not be.
//
// Large:  Equivalent to Medium for now.
//
// Kernel: Equivalent to Medium for now.
//
// This means that any PIC module smaller than 4GB meets the
// requirements of Small, so Small seems like the best default there.
//
// All symbols bind locally in a non-PIC module, so the choice is less
// obvious.  There are two cases:
//
// - When creating an executable, PLTs and copy relocations allow
//   us to treat external symbols as part of the executable.
//   Any executable smaller than 4GB meets the requirements of Small,
//   so that seems like the best default.
//
// - When creating JIT code, stubs will be in range of BRASL if the
//   image is less than 4GB in size.  GOT entries will likewise be
//   in range of LARL.  However, the JIT environment has no equivalent
//   of copy relocs, so locally-binding data symbols might not be in
//   the range of LARL.  We need the Medium model in that case.
static CodeModel::Model
getEffectiveSystemZCodeModel(std::optional<CodeModel::Model> CM,
                             Reloc::Model RM, bool JIT) {
  if (CM) {
    if (*CM == CodeModel::Tiny)
      report_fatal_error("Target does not support the tiny CodeModel", false);
    if (*CM == CodeModel::Kernel)
      report_fatal_error("Target does not support the kernel CodeModel", false);
    return *CM;
  }
  if (JIT)
    return RM == Reloc::PIC_ ? CodeModel::Small : CodeModel::Medium;
  return CodeModel::Small;
}

SystemZTargetMachine::SystemZTargetMachine(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)
    : CodeGenTargetMachineImpl(
          T, TT.computeDataLayout(), TT, CPU, FS, Options,
          getEffectiveRelocModel(RM),
          getEffectiveSystemZCodeModel(CM, getEffectiveRelocModel(RM), JIT),
          OL),
      TLOF(createTLOF(getTargetTriple())) {
  initAsmInfo();
}

SystemZTargetMachine::~SystemZTargetMachine() = default;

const SystemZSubtarget *
SystemZTargetMachine::getSubtargetImpl(const Function &F) const {
  Attribute CPUAttr = F.getFnAttribute("target-cpu");
  Attribute TuneAttr = F.getFnAttribute("tune-cpu");
  Attribute FSAttr = F.getFnAttribute("target-features");

  std::string CPU =
      CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
  std::string TuneCPU =
      TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
  std::string FS =
      FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;

  // FIXME: This is related to the code below to reset the target options,
  // we need to know whether the soft float and backchain flags are set on the
  // function, so we can enable them as subtarget features.
  bool SoftFloat = F.getFnAttribute("use-soft-float").getValueAsBool();
  if (SoftFloat)
    FS += FS.empty() ? "+soft-float" : ",+soft-float";
  bool BackChain = F.hasFnAttribute("backchain");
  if (BackChain)
    FS += FS.empty() ? "+backchain" : ",+backchain";

  auto &I = SubtargetMap[CPU + TuneCPU + FS];
  if (!I) {
    I = std::make_unique<SystemZSubtarget>(TargetTriple, CPU, TuneCPU, FS,
                                           *this);
  }

  return I.get();
}

ScheduleDAGInstrs *
SystemZTargetMachine::createMachineScheduler(MachineSchedContext *C) const {
  // Use GenericScheduler if requested on CL or for Z10 which has no sched
  // model.
  if (GenericSched ||
      !C->MF->getSubtarget().getSchedModel().hasInstrSchedModel())
    return nullptr;

  return createSchedLive<SystemZPreRASchedStrategy>(C);
}

ScheduleDAGInstrs *
SystemZTargetMachine::createPostMachineScheduler(MachineSchedContext *C) const {
  return createSchedPostRA<SystemZPostRASchedStrategy>(C);
}

namespace {

/// SystemZ Code Generator Pass Configuration Options.
class SystemZPassConfig : public TargetPassConfig {
public:
  SystemZPassConfig(SystemZTargetMachine &TM, PassManagerBase &PM)
    : TargetPassConfig(TM, PM) {}

  SystemZTargetMachine &getSystemZTargetMachine() const {
    return getTM<SystemZTargetMachine>();
  }

  void addIRPasses() override;
  bool addInstSelector() override;
  bool addILPOpts() override;
  void addPreRegAlloc() override;
  void addPostRewrite() override;
  void addPostRegAlloc() override;
  void addPreSched2() override;
  void addPreEmitPass() override;
};

} // end anonymous namespace

void SystemZPassConfig::addIRPasses() {
  if (getOptLevel() != CodeGenOptLevel::None) {
    addPass(createSystemZTDCPass());
    addPass(createLoopDataPrefetchPass());
  }

  addPass(createAtomicExpandLegacyPass());

  TargetPassConfig::addIRPasses();
}

bool SystemZPassConfig::addInstSelector() {
  addPass(createSystemZISelDag(getSystemZTargetMachine(), getOptLevel()));

  if (getOptLevel() != CodeGenOptLevel::None)
    addPass(createSystemZLDCleanupPass(getSystemZTargetMachine()));

  return false;
}

bool SystemZPassConfig::addILPOpts() {
  addPass(&EarlyIfConverterLegacyID);

  if (EnableMachineCombinerPass)
    addPass(&MachineCombinerID);

  return true;
}

void SystemZPassConfig::addPreRegAlloc() {
  addPass(createSystemZCopyPhysRegsPass(getSystemZTargetMachine()));
}

void SystemZPassConfig::addPostRewrite() {
  addPass(createSystemZPostRewritePass(getSystemZTargetMachine()));
}

void SystemZPassConfig::addPostRegAlloc() {
  // PostRewrite needs to be run at -O0 also (in which case addPostRewrite()
  // is not called).
  if (getOptLevel() == CodeGenOptLevel::None)
    addPass(createSystemZPostRewritePass(getSystemZTargetMachine()));
}

void SystemZPassConfig::addPreSched2() {
  if (getOptLevel() != CodeGenOptLevel::None)
    addPass(&IfConverterID);
}

void SystemZPassConfig::addPreEmitPass() {
  // Do instruction shortening before compare elimination because some
  // vector instructions will be shortened into opcodes that compare
  // elimination recognizes.
  if (getOptLevel() != CodeGenOptLevel::None)
    addPass(createSystemZShortenInstPass(getSystemZTargetMachine()));

  // We eliminate comparisons here rather than earlier because some
  // transformations can change the set of available CC values and we
  // generally want those transformations to have priority.  This is
  // especially true in the commonest case where the result of the comparison
  // is used by a single in-range branch instruction, since we will then
  // be able to fuse the compare and the branch instead.
  //
  // For example, two-address NILF can sometimes be converted into
  // three-address RISBLG.  NILF produces a CC value that indicates whether
  // the low word is zero, but RISBLG does not modify CC at all.  On the
  // other hand, 64-bit ANDs like NILL can sometimes be converted to RISBG.
  // The CC value produced by NILL isn't useful for our purposes, but the
  // value produced by RISBG can be used for any comparison with zero
  // (not just equality).  So there are some transformations that lose
  // CC values (while still being worthwhile) and others that happen to make
  // the CC result more useful than it was originally.
  //
  // Another reason is that we only want to use BRANCH ON COUNT in cases
  // where we know that the count register is not going to be spilled.
  //
  // Doing it so late makes it more likely that a register will be reused
  // between the comparison and the branch, but it isn't clear whether
  // preventing that would be a win or not.
  if (getOptLevel() != CodeGenOptLevel::None)
    addPass(createSystemZElimComparePass(getSystemZTargetMachine()));
  addPass(createSystemZLongBranchPass(getSystemZTargetMachine()));

  // Do final scheduling after all other optimizations, to get an
  // optimal input for the decoder (branch relaxation must happen
  // after block placement).
  if (getOptLevel() != CodeGenOptLevel::None)
    addPass(&PostMachineSchedulerID);
}

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

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

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