text: //===-- AMDGPUTargetMachine.h - AMDGPU TargetMachine Interface --*- 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
  //
  //===----------------------------------------------------------------------===//
  //
  /// \file
  /// The AMDGPU TargetMachine interface definition for hw codgen targets.
  //
  //===----------------------------------------------------------------------===//
  
  #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETMACHINE_H
  #define LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETMACHINE_H
  
  #include "AMDGPUSubtarget.h"
  #include "llvm/ADT/Optional.h"
  #include "llvm/ADT/StringMap.h"
  #include "llvm/ADT/StringRef.h"
  #include "llvm/Analysis/TargetTransformInfo.h"
  #include "llvm/Support/CodeGen.h"
  #include "llvm/Target/TargetMachine.h"
  #include <memory>
  
  namespace llvm {
  
  //===----------------------------------------------------------------------===//
  // AMDGPU Target Machine (R600+)
  //===----------------------------------------------------------------------===//
  
  class AMDGPUTargetMachine : public LLVMTargetMachine {
  protected:
    std::unique_ptr<TargetLoweringObjectFile> TLOF;
  
    StringRef getGPUName(const Function &F) const;
    StringRef getFeatureString(const Function &F) const;
  
  public:
    static bool EnableLateStructurizeCFG;
    static bool EnableFunctionCalls;
  
    AMDGPUTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
                        StringRef FS, TargetOptions Options,
                        Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
                        CodeGenOpt::Level OL);
    ~AMDGPUTargetMachine() override;
  
    const TargetSubtargetInfo *getSubtargetImpl() const;
    const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override = 0;
  
    TargetLoweringObjectFile *getObjFileLowering() const override {
      return TLOF.get();
    }
  
    // TODO schi merge void addPreLinkPasses(PassManagerBase & PM) override;
  
    void adjustPassManager(PassManagerBuilder &) override;
  
    /// Get the integer value of a null pointer in the given address space.
    uint64_t getNullPointerValue(unsigned AddrSpace) const {
      return (AddrSpace == AMDGPUAS::LOCAL_ADDRESS ||
              AddrSpace == AMDGPUAS::REGION_ADDRESS) ? -1 : 0;
    }
  };
  
  //===----------------------------------------------------------------------===//
  // R600 Target Machine (R600 -> Cayman)
  //===----------------------------------------------------------------------===//
  
  class R600TargetMachine final : public AMDGPUTargetMachine {
  private:
    mutable StringMap<std::unique_ptr<R600Subtarget>> SubtargetMap;
  
  public:
    R600TargetMachine(const Target &T, const Triple &TT, StringRef CPU,
                      StringRef FS, TargetOptions Options,
                      Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
                      CodeGenOpt::Level OL, bool JIT);
  
    TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
  
    const R600Subtarget *getSubtargetImpl(const Function &) const override;
  
    TargetTransformInfo getTargetTransformInfo(const Function &F) override;
  
    bool isMachineVerifierClean() const override {
      return false;
    }
  };
  
  //===----------------------------------------------------------------------===//
  // GCN Target Machine (SI+)
  //===----------------------------------------------------------------------===//
  
  class GCNTargetMachine final : public AMDGPUTargetMachine {
  private:
    mutable StringMap<std::unique_ptr<GCNSubtarget>> SubtargetMap;
  
  public:
    GCNTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
                     StringRef FS, TargetOptions Options,
                     Optional<Reloc::Model> RM, Optional<CodeModel::Model> CM,
                     CodeGenOpt::Level OL, bool JIT);
  
    TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
  
    const GCNSubtarget *getSubtargetImpl(const Function &) const override;
  
    TargetTransformInfo getTargetTransformInfo(const Function &F) override;
  
    bool useIPRA() const override {
      return true;
    }
  
    yaml::MachineFunctionInfo *createDefaultFuncInfoYAML() const override;
    yaml::MachineFunctionInfo *
    convertFuncInfoToYAML(const MachineFunction &MF) const override;
    bool parseMachineFunctionInfo(const yaml::MachineFunctionInfo &,
                                  PerFunctionMIParsingState &PFS,
                                  SMDiagnostic &Error,
                                  SMRange &SourceRange) const override;
  };
  
  } // end namespace llvm
  
  #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUTARGETMACHINE_H
  