//===-- llvm/Target/TargetMachine.h - Target Information --------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines the TargetMachine and LLVMTargetMachine classes.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H

#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
#include <string>

namespace llvm {

class Function;
class GlobalValue;
class MachineModuleInfo;
class Mangler;
class MCAsmInfo;
class MCContext;
class MCInstrInfo;
class MCRegisterInfo;
class MCSubtargetInfo;
class MCSymbol;
class raw_pwrite_stream;
class PassManagerBuilder;
struct PerFunctionMIParsingState;
class SMDiagnostic;
class SMRange;
class Target;
class TargetIntrinsicInfo;
class TargetIRAnalysis;
class TargetTransformInfo;
class TargetLoweringObjectFile;
class TargetPassConfig;
class TargetSubtargetInfo;

// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
class PassManagerBase;
}
using legacy::PassManagerBase;

namespace yaml {
struct MachineFunctionInfo;
}

//===----------------------------------------------------------------------===//
///
/// Primary interface to the complete machine description for the target
/// machine.  All target-specific information should be accessible through this
/// interface.
///
class TargetMachine {
protected: // Can only create subclasses.
  TargetMachine(const Target &T, StringRef DataLayoutString,
                const Triple &TargetTriple, StringRef CPU, StringRef FS,
                const TargetOptions &Options);

  /// The Target that this machine was created for.
  const Target &TheTarget;

  /// DataLayout for the target: keep ABI type size and alignment.
  ///
  /// The DataLayout is created based on the string representation provided
  /// during construction. It is kept here only to avoid reparsing the string
  /// but should not really be used during compilation, because it has an
  /// internal cache that is context specific.
  const DataLayout DL;

  /// Triple string, CPU name, and target feature strings the TargetMachine
  /// instance is created with.
  Triple TargetTriple;
  std::string TargetCPU;
  std::string TargetFS;

  Reloc::Model RM = Reloc::Static;
  CodeModel::Model CMModel = CodeModel::Small;
  CodeGenOpt::Level OptLevel = CodeGenOpt::Default;

  /// Contains target specific asm information.
  std::unique_ptr<const MCAsmInfo> AsmInfo;
  std::unique_ptr<const MCRegisterInfo> MRI;
  std::unique_ptr<const MCInstrInfo> MII;
  std::unique_ptr<const MCSubtargetInfo> STI;

  unsigned RequireStructuredCFG : 1;
  unsigned O0WantsFastISel : 1;

public:
  const TargetOptions DefaultOptions;
  mutable TargetOptions Options;

  TargetMachine(const TargetMachine &) = delete;
  void operator=(const TargetMachine &) = delete;
  virtual ~TargetMachine();

  const Target &getTarget() const { return TheTarget; }

  const Triple &getTargetTriple() const { return TargetTriple; }
  StringRef getTargetCPU() const { return TargetCPU; }
  StringRef getTargetFeatureString() const { return TargetFS; }

  /// Virtual method implemented by subclasses that returns a reference to that
  /// target's TargetSubtargetInfo-derived member variable.
  virtual const TargetSubtargetInfo *getSubtargetImpl(const Function &) const {
    return nullptr;
  }
  virtual TargetLoweringObjectFile *getObjFileLowering() const {
    return nullptr;
  }

  /// Allocate and return a default initialized instance of the YAML
  /// representation for the MachineFunctionInfo.
  virtual yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const {
    return nullptr;
  }

  /// Allocate and initialize an instance of the YAML representation of the
  /// MachineFunctionInfo.
  virtual yaml::MachineFunctionInfo *
  convertFuncInfoToYAML(const MachineFunction &MF) const {
    return nullptr;
  }

  /// Parse out the target's MachineFunctionInfo from the YAML reprsentation.
  virtual bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &,
                                        PerFunctionMIParsingState &PFS,
                                        SMDiagnostic &Error,
                                        SMRange &SourceRange) const {
    return false;
  }

  /// This method returns a pointer to the specified type of
  /// TargetSubtargetInfo.  In debug builds, it verifies that the object being
  /// returned is of the correct type.
  template <typename STC> const STC &getSubtarget(const Function &F) const {
    return *static_cast<const STC*>(getSubtargetImpl(F));
  }

  /// Create a DataLayout.
  const DataLayout createDataLayout() const { return DL; }

  /// Test if a DataLayout if compatible with the CodeGen for this target.
  ///
  /// The LLVM Module owns a DataLayout that is used for the target independent
  /// optimizations and code generation. This hook provides a target specific
  /// check on the validity of this DataLayout.
  bool isCompatibleDataLayout(const DataLayout &Candidate) const {
    return DL == Candidate;
  }

  /// Get the pointer size for this target.
  ///
  /// This is the only time the DataLayout in the TargetMachine is used.
  unsigned getPointerSize(unsigned AS) const {
    return DL.getPointerSize(AS);
  }

  unsigned getPointerSizeInBits(unsigned AS) const {
    return DL.getPointerSizeInBits(AS);
  }

  unsigned getProgramPointerSize() const {
    return DL.getPointerSize(DL.getProgramAddressSpace());
  }

  unsigned getAllocaPointerSize() const {
    return DL.getPointerSize(DL.getAllocaAddrSpace());
  }

  /// Reset the target options based on the function's attributes.
  // FIXME: Remove TargetOptions that affect per-function code generation
  // from TargetMachine.
  void resetTargetOptions(const Function &F) const;

  /// Return target specific asm information.
  const MCAsmInfo *getMCAsmInfo() const { return AsmInfo.get(); }

  const MCRegisterInfo *getMCRegisterInfo() const { return MRI.get(); }
  const MCInstrInfo *getMCInstrInfo() const { return MII.get(); }
  const MCSubtargetInfo *getMCSubtargetInfo() const { return STI.get(); }

  /// If intrinsic information is available, return it.  If not, return null.
  virtual const TargetIntrinsicInfo *getIntrinsicInfo() const {
    return nullptr;
  }

  bool requiresStructuredCFG() const { return RequireStructuredCFG; }
  void setRequiresStructuredCFG(bool Value) { RequireStructuredCFG = Value; }

  /// Returns the code generation relocation model. The choices are static, PIC,
  /// and dynamic-no-pic, and target default.
  Reloc::Model getRelocationModel() const;

  /// Returns the code model. The choices are small, kernel, medium, large, and
  /// target default.
  CodeModel::Model getCodeModel() const;

  bool isPositionIndependent() const;

  bool shouldAssumeDSOLocal(const Module &M, const GlobalValue *GV) const;

  /// Returns true if this target uses emulated TLS.
  bool useEmulatedTLS() const;

  /// Returns the TLS model which should be used for the given global variable.
  TLSModel::Model getTLSModel(const GlobalValue *GV) const;

  /// Returns the optimization level: None, Less, Default, or Aggressive.
  CodeGenOpt::Level getOptLevel() const;

  /// Overrides the optimization level.
  void setOptLevel(CodeGenOpt::Level Level);

  void setFastISel(bool Enable) { Options.EnableFastISel = Enable; }
  bool getO0WantsFastISel() { return O0WantsFastISel; }
  void setO0WantsFastISel(bool Enable) { O0WantsFastISel = Enable; }
  void setGlobalISel(bool Enable) { Options.EnableGlobalISel = Enable; }
  void setGlobalISelAbort(GlobalISelAbortMode Mode) {
    Options.GlobalISelAbort = Mode;
  }
  void setMachineOutliner(bool Enable) {
    Options.EnableMachineOutliner = Enable;
  }
  void setSupportsDefaultOutlining(bool Enable) {
    Options.SupportsDefaultOutlining = Enable;
  }

  bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }

  bool getUniqueSectionNames() const { return Options.UniqueSectionNames; }

  /// Return true if data objects should be emitted into their own section,
  /// corresponds to -fdata-sections.
  bool getDataSections() const {
    return Options.DataSections;
  }

  /// Return true if functions should be emitted into their own section,
  /// corresponding to -ffunction-sections.
  bool getFunctionSections() const {
    return Options.FunctionSections;
  }

  /// Get a \c TargetIRAnalysis appropriate for the target.
  ///
  /// This is used to construct the new pass manager's target IR analysis pass,
  /// set up appropriately for this target machine. Even the old pass manager
  /// uses this to answer queries about the IR.
  TargetIRAnalysis getTargetIRAnalysis();

  /// Return a TargetTransformInfo for a given function.
  ///
  /// The returned TargetTransformInfo is specialized to the subtarget
  /// corresponding to \p F.
  virtual TargetTransformInfo getTargetTransformInfo(const Function &F);

  /// Allow the target to modify the pass manager, e.g. by calling
  /// PassManagerBuilder::addExtension.
  virtual void adjustPassManager(PassManagerBuilder &) {}

  /// These enums are meant to be passed into addPassesToEmitFile to indicate
  /// what type of file to emit, and returned by it to indicate what type of
  /// file could actually be made.
  enum CodeGenFileType {
    CGFT_AssemblyFile,
    CGFT_ObjectFile,
    CGFT_Null         // Do not emit any output.
  };

  /// Add passes to the specified pass manager to get the specified file
  /// emitted.  Typically this will involve several steps of code generation.
  /// This method should return true if emission of this file type is not
  /// supported, or false on success.
  /// \p MMI is an optional parameter that, if set to non-nullptr,
  /// will be used to set the MachineModuloInfo for this PM.
  virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,
                                   raw_pwrite_stream *, CodeGenFileType,
                                   bool /*DisableVerify*/ = true,
                                   MachineModuleInfo *MMI = nullptr) {
    return true;
  }

  /// 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.
  ///
  virtual bool addPassesToEmitMC(PassManagerBase &, MCContext *&,
                                 raw_pwrite_stream &,
                                 bool /*DisableVerify*/ = true) {
    return true;
  }

  /// True if subtarget inserts the final scheduling pass on its own.
  ///
  /// Branch relaxation, which must happen after block placement, can
  /// on some targets (e.g. SystemZ) expose additional post-RA
  /// scheduling opportunities.
  virtual bool targetSchedulesPostRAScheduling() const { return false; };

  void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV,
                         Mangler &Mang, bool MayAlwaysUsePrivate = false) const;
  MCSymbol *getSymbol(const GlobalValue *GV) const;
};

/// This class describes a target machine that is implemented with the LLVM
/// target-independent code generator.
///
class LLVMTargetMachine : public TargetMachine {
protected: // Can only create subclasses.
  LLVMTargetMachine(const Target &T, StringRef DataLayoutString,
                    const Triple &TT, StringRef CPU, StringRef FS,
                    const TargetOptions &Options, Reloc::Model RM,
                    CodeModel::Model CM, CodeGenOpt::Level OL);

  void initAsmInfo();

public:
  /// Get a TargetTransformInfo implementation for the target.
  ///
  /// The TTI returned uses the common code generator to answer queries about
  /// the IR.
  TargetTransformInfo getTargetTransformInfo(const Function &F) override;

  /// Create a pass configuration object to be used by addPassToEmitX methods
  /// for generating a pipeline of CodeGen passes.
  virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);

  /// Add passes to the specified pass manager to get the specified file
  /// emitted.  Typically this will involve several steps of code generation.
  /// \p MMI is an optional parameter that, if set to non-nullptr,
  /// will be used to set the MachineModuloInfofor this PM.
  bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
                           raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
                           bool DisableVerify = true,
                           MachineModuleInfo *MMI = nullptr) override;

  /// 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 addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
                         raw_pwrite_stream &Out,
                         bool DisableVerify = true) override;

  /// Returns true if the target is expected to pass all machine verifier
  /// checks. This is a stopgap measure to fix targets one by one. We will
  /// remove this at some point and always enable the verifier when
  /// EXPENSIVE_CHECKS is enabled.
  virtual bool isMachineVerifierClean() const { return true; }

  /// Adds an AsmPrinter pass to the pipeline that prints assembly or
  /// machine code from the MI representation.
  bool addAsmPrinter(PassManagerBase &PM, raw_pwrite_stream &Out,
                     raw_pwrite_stream *DwoOut, CodeGenFileType FileTYpe,
                     MCContext &Context);

  /// True if the target uses physical regs at Prolog/Epilog insertion
  /// time. If true (most machines), all vregs must be allocated before
  /// PEI. If false (virtual-register machines), then callee-save register
  /// spilling and scavenging are not needed or used.
  virtual bool usesPhysRegsForPEI() const { return true; }

  /// True if the target wants to use interprocedural register allocation by
  /// default. The -enable-ipra flag can be used to override this.
  virtual bool useIPRA() const {
    return false;
  }
};

/// Helper method for getting the code model, returning Default if
/// CM does not have a value. The tiny and kernel models will produce
/// an error, so targets that support them or require more complex codemodel
/// selection logic should implement and call their own getEffectiveCodeModel.
inline CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM,
                                              CodeModel::Model Default) {
  if (CM) {
    // By default, targets do not support the tiny and kernel models.
    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;
  }
  return Default;
}

} // end namespace llvm

#endif // LLVM_TARGET_TARGETMACHINE_H
