//===-- CodeGenTargetMachineImpl.cpp --------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file This file implements the CodeGenTargetMachineImpl class.
///
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/CodeGenTargetMachineImpl.h"
#include "llvm/Analysis/RuntimeLibcallInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/BasicTTIImpl.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Target/RegisterTargetPassConfigCallback.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;

static cl::opt<bool>
    EnableTrapUnreachable("trap-unreachable", cl::Hidden,
                          cl::desc("Enable generating trap for unreachable"));

static cl::opt<bool> EnableNoTrapAfterNoreturn(
    "no-trap-after-noreturn", cl::Hidden,
    cl::desc("Do not emit a trap instruction for 'unreachable' IR instructions "
             "after noreturn calls, even if --trap-unreachable is set."));

void CodeGenTargetMachineImpl::initAsmInfo() {
  MRI.reset(TheTarget.createMCRegInfo(getTargetTriple()));
  assert(MRI && "Unable to create reg info");
  MII.reset(TheTarget.createMCInstrInfo());
  assert(MII && "Unable to create instruction info");
  // FIXME: Having an MCSubtargetInfo on the target machine is a hack due
  // to some backends having subtarget feature dependent module level
  // code generation. This is similar to the hack in the AsmPrinter for
  // module level assembly etc.
  STI.reset(TheTarget.createMCSubtargetInfo(getTargetTriple(), getTargetCPU(),
                                            getTargetFeatureString()));
  assert(STI && "Unable to create subtarget info");

  MCAsmInfo *TmpAsmInfo =
      TheTarget.createMCAsmInfo(*MRI, getTargetTriple(), Options.MCOptions);
  // TargetSelect.h moved to a different directory between LLVM 2.9 and 3.0,
  // and if the old one gets included then MCAsmInfo will be NULL and
  // we'll crash later.
  // Provide the user with a useful error message about what's wrong.
  assert(TmpAsmInfo && "MCAsmInfo not initialized. "
                       "Make sure you include the correct TargetSelect.h"
                       "and that InitializeAllTargetMCs() is being invoked!");

  if (Options.MCOptions.DisableIntegratedAS) {
    TmpAsmInfo->setUseIntegratedAssembler(false);
    // If there is explict option disable integratedAS, we can't use it for
    // inlineasm either.
    TmpAsmInfo->setParseInlineAsmUsingAsmParser(false);
  }

  TmpAsmInfo->setPreserveAsmComments(Options.MCOptions.PreserveAsmComments);

  TmpAsmInfo->setFullRegisterNames(Options.MCOptions.PPCUseFullRegisterNames);

  AsmInfo.reset(TmpAsmInfo);
}

CodeGenTargetMachineImpl::CodeGenTargetMachineImpl(
    const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
    const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM,
    CodeGenOptLevel OL)
    : TargetMachine(T, TT.computeDataLayout(Options.MCOptions.getABIName()), TT,
                    CPU, FS, Options) {
  this->RM = RM;
  this->CMModel = CM;
  this->OptLevel = OL;

  if (EnableTrapUnreachable)
    this->Options.TrapUnreachable = true;
  if (EnableNoTrapAfterNoreturn)
    this->Options.NoTrapAfterNoreturn = true;
}

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

/// addPassesToX helper drives creation and initialization of TargetPassConfig.
static TargetPassConfig *
addPassesToGenerateCode(CodeGenTargetMachineImpl &TM, PassManagerBase &PM,
                        bool DisableVerify,
                        MachineModuleInfoWrapperPass &MMIWP) {
  // Targets may override createPassConfig to provide a target-specific
  // subclass.
  TargetPassConfig *PassConfig = TM.createPassConfig(PM);
  // Set PassConfig options provided by TargetMachine.
  PassConfig->setDisableVerify(DisableVerify);
  PM.add(PassConfig);
  PM.add(&MMIWP);

  const TargetOptions &Options = TM.Options;
  TargetLibraryInfoImpl TLII(TM.getTargetTriple(), Options.VecLib);
  PM.add(new TargetLibraryInfoWrapperPass(TLII));
  PM.add(
      new RuntimeLibraryInfoWrapper(Options.MCOptions.ABIName, Options.VecLib));

  invokeGlobalTargetPassConfigCallbacks(TM, PM, PassConfig);

  if (PassConfig->addISelPasses())
    return nullptr;
  PassConfig->addMachinePasses();
  PassConfig->setInitialized();
  return PassConfig;
}

bool CodeGenTargetMachineImpl::addAsmPrinter(PassManagerBase &PM,
                                             raw_pwrite_stream &Out,
                                             raw_pwrite_stream *DwoOut,
                                             CodeGenFileType FileType,
                                             MCContext &Context) {
  Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =
      createMCStreamer(Out, DwoOut, FileType, Context);
  if (!MCStreamerOrErr) {
    Context.reportError(SMLoc(), toString(MCStreamerOrErr.takeError()));
    return true;
  }

  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
  FunctionPass *Printer =
      getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));
  if (!Printer)
    return true;

  PM.add(Printer);
  return false;
}

Expected<std::unique_ptr<MCStreamer>>
CodeGenTargetMachineImpl::createMCStreamer(raw_pwrite_stream &Out,
                                           raw_pwrite_stream *DwoOut,
                                           CodeGenFileType FileType,
                                           MCContext &Context) {
  const MCSubtargetInfo &STI = getMCSubtargetInfo();
  const MCAsmInfo &MAI = getMCAsmInfo();
  const MCRegisterInfo &MRI = getMCRegisterInfo();
  const MCInstrInfo &MII = *getMCInstrInfo();

  std::unique_ptr<MCStreamer> AsmStreamer;

  switch (FileType) {
  case CodeGenFileType::AssemblyFile: {
    std::unique_ptr<MCInstPrinter> InstPrinter(getTarget().createMCInstPrinter(
        getTargetTriple(), MAI.getOutputAssemblerDialect(), MAI, MII, MRI));
    for (StringRef Opt : Options.MCOptions.InstPrinterOptions)
      if (!InstPrinter->applyTargetSpecificCLOption(Opt))
        return createStringError("invalid InstPrinter option '" + Opt + "'");

    // Create a code emitter if asked to show the encoding.
    std::unique_ptr<MCCodeEmitter> MCE;
    if (Options.MCOptions.ShowMCEncoding)
      MCE.reset(getTarget().createMCCodeEmitter(MII, Context));

    std::unique_ptr<MCAsmBackend> MAB(
        getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions));
    auto FOut = std::make_unique<formatted_raw_ostream>(Out);
    MCStreamer *S = getTarget().createAsmStreamer(
        Context, std::move(FOut), std::move(InstPrinter), std::move(MCE),
        std::move(MAB));
    AsmStreamer.reset(S);
    break;
  }
  case CodeGenFileType::ObjectFile: {
    // Create the code emitter for the target if it exists.  If not, .o file
    // emission fails.
    MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, Context);
    if (!MCE)
      return make_error<StringError>("createMCCodeEmitter failed",
                                     inconvertibleErrorCode());
    MCAsmBackend *MAB =
        getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
    if (!MAB)
      return make_error<StringError>("createMCAsmBackend failed",
                                     inconvertibleErrorCode());

    Triple T(getTargetTriple());
    AsmStreamer.reset(getTarget().createMCObjectStreamer(
        T, Context, std::unique_ptr<MCAsmBackend>(MAB),
        DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut)
               : MAB->createObjectWriter(Out),
        std::unique_ptr<MCCodeEmitter>(MCE), STI));
    break;
  }
  case CodeGenFileType::Null:
    // The Null output is intended for use for performance analysis and testing,
    // not real users.
    AsmStreamer.reset(getTarget().createNullStreamer(Context));
    break;
  }

  return std::move(AsmStreamer);
}

bool CodeGenTargetMachineImpl::addPassesToEmitFile(
    PassManagerBase &PM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
    CodeGenFileType FileType, bool DisableVerify,
    MachineModuleInfoWrapperPass *MMIWP) {
  // Add common CodeGen passes.
  if (!MMIWP)
    MMIWP = new MachineModuleInfoWrapperPass(this);
  TargetPassConfig *PassConfig =
      addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
  if (!PassConfig)
    return true;

  if (PassConfig->willCompleteCodeGenPipeline()) {
    if (addAsmPrinter(PM, Out, DwoOut, FileType, MMIWP->getMMI().getContext()))
      return true;
  } else {
    if (PassConfig->getMachineVerifierMode() == MachineVerifierMode::End)
      PM.add(createMachineVerifierPass("At end of pipeline"));
    // MIR printing is redundant with -filetype=null.
    if (FileType != CodeGenFileType::Null)
      PM.add(createPrintMIRPass(Out));
  }

  PM.add(createFreeMachineFunctionPass());
  return false;
}

/// addPassesToEmitMC - Add passes to the specified pass manager to get
/// machine code emitted with the MCJIT. This method returns true if machine
/// code is not supported. It fills the MCContext Ctx pointer which can be
/// used to build custom MCStreamer.
///
bool CodeGenTargetMachineImpl::addPassesToEmitMC(PassManagerBase &PM,
                                                 MCContext *&Ctx,
                                                 raw_pwrite_stream &Out,
                                                 bool DisableVerify) {
  // Add common CodeGen passes.
  MachineModuleInfoWrapperPass *MMIWP = new MachineModuleInfoWrapperPass(this);
  TargetPassConfig *PassConfig =
      addPassesToGenerateCode(*this, PM, DisableVerify, *MMIWP);
  if (!PassConfig)
    return true;
  assert(PassConfig->willCompleteCodeGenPipeline() &&
         "Cannot emit MC with limited codegen pipeline");

  Ctx = &MMIWP->getMMI().getContext();
  // libunwind is unable to load compact unwind dynamically, so we must generate
  // DWARF unwind info for the JIT.
  Options.MCOptions.EmitDwarfUnwind = EmitDwarfUnwindType::Always;

  // Create the code emitter for the target if it exists.  If not, .o file
  // emission fails.
  const MCSubtargetInfo &STI = getMCSubtargetInfo();
  const MCRegisterInfo &MRI = getMCRegisterInfo();
  std::unique_ptr<MCCodeEmitter> MCE(
      getTarget().createMCCodeEmitter(*getMCInstrInfo(), *Ctx));
  if (!MCE)
    return true;
  MCAsmBackend *MAB =
      getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);
  if (!MAB)
    return true;

  const Triple &T = getTargetTriple();
  std::unique_ptr<MCStreamer> AsmStreamer(getTarget().createMCObjectStreamer(
      T, *Ctx, std::unique_ptr<MCAsmBackend>(MAB), MAB->createObjectWriter(Out),
      std::move(MCE), STI));

  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
  FunctionPass *Printer =
      getTarget().createAsmPrinter(*this, std::move(AsmStreamer));
  if (!Printer)
    return true;

  PM.add(Printer);
  PM.add(createFreeMachineFunctionPass());

  return false; // success!
}
