xref: /llvm-project/llvm/lib/Target/SPIRV/SPIRVSubtarget.h (revision df122fc734ce002632f3bfe8a5fc5010349dba16)
1 //===-- SPIRVSubtarget.h - SPIR-V Subtarget Information --------*- C++ -*--===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the SPIR-V specific subclass of TargetSubtargetInfo.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
14 #define LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
15 
16 #include "SPIRVCallLowering.h"
17 #include "SPIRVFrameLowering.h"
18 #include "SPIRVISelLowering.h"
19 #include "SPIRVInlineAsmLowering.h"
20 #include "SPIRVInstrInfo.h"
21 #include "llvm/ADT/SmallSet.h"
22 #include "llvm/CodeGen/GlobalISel/CallLowering.h"
23 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
24 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
25 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
26 #include "llvm/CodeGen/TargetSubtargetInfo.h"
27 #include "llvm/IR/DataLayout.h"
28 #include "llvm/Target/TargetMachine.h"
29 #include "llvm/TargetParser/Triple.h"
30 
31 #define GET_SUBTARGETINFO_HEADER
32 #include "SPIRVGenSubtargetInfo.inc"
33 
34 namespace llvm {
35 class StringRef;
36 class SPIRVTargetMachine;
37 
38 class SPIRVSubtarget : public SPIRVGenSubtargetInfo {
39 private:
40   const unsigned PointerSize;
41   VersionTuple SPIRVVersion;
42   VersionTuple OpenCLVersion;
43 
44   SmallSet<SPIRV::Extension::Extension, 4> AvailableExtensions;
45   SmallSet<SPIRV::InstructionSet::InstructionSet, 4> AvailableExtInstSets;
46   std::unique_ptr<SPIRVGlobalRegistry> GR;
47 
48   SPIRVInstrInfo InstrInfo;
49   SPIRVFrameLowering FrameLowering;
50   SPIRVTargetLowering TLInfo;
51   Triple TargetTriple;
52 
53   // GlobalISel related APIs.
54   std::unique_ptr<CallLowering> CallLoweringInfo;
55   std::unique_ptr<RegisterBankInfo> RegBankInfo;
56   std::unique_ptr<LegalizerInfo> Legalizer;
57   std::unique_ptr<InstructionSelector> InstSelector;
58   std::unique_ptr<InlineAsmLowering> InlineAsmInfo;
59 
60   // TODO: Initialise the available extensions, extended instruction sets
61   // based on the environment settings.
62   void initAvailableExtInstSets();
63   void accountForAMDShaderTrinaryMinmax();
64 
65 public:
66   // This constructor initializes the data members to match that
67   // of the specified triple.
68   SPIRVSubtarget(const Triple &TT, const std::string &CPU,
69                  const std::string &FS, const SPIRVTargetMachine &TM);
70   SPIRVSubtarget &initSubtargetDependencies(StringRef CPU, StringRef FS);
71 
72   void initAvailableExtensions(
73       const std::set<SPIRV::Extension::Extension> &AllowedExtIds);
74 
75   // Parses features string setting specified subtarget options.
76   // The definition of this function is auto generated by tblgen.
77   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
78   unsigned getPointerSize() const { return PointerSize; }
79   unsigned getBound() const { return GR->getBound(); }
80   bool canDirectlyComparePointers() const;
81   // TODO: this environment is not implemented in Triple, we need to decide
82   // how to standardize its support. For now, let's assume SPIR-V with physical
83   // addressing is OpenCL, and Logical addressing is Vulkan.
84   bool isOpenCLEnv() const {
85     return TargetTriple.getArch() == Triple::spirv32 ||
86            TargetTriple.getArch() == Triple::spirv64;
87   }
88   bool isVulkanEnv() const { return TargetTriple.getArch() == Triple::spirv; }
89   const std::string &getTargetTripleAsStr() const { return TargetTriple.str(); }
90   VersionTuple getSPIRVVersion() const { return SPIRVVersion; };
91   bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const;
92   bool isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const;
93   // TODO: implement command line args or other ways to determine this.
94   bool hasOpenCLFullProfile() const { return true; }
95   bool hasOpenCLImageSupport() const { return true; }
96   const SmallSet<SPIRV::Extension::Extension, 4> &
97   getAllAvailableExtensions() const {
98     return AvailableExtensions;
99   }
100   bool canUseExtension(SPIRV::Extension::Extension E) const;
101   bool canUseExtInstSet(SPIRV::InstructionSet::InstructionSet E) const;
102   SPIRV::InstructionSet::InstructionSet getPreferredInstructionSet() const;
103 
104   SPIRVGlobalRegistry *getSPIRVGlobalRegistry() const { return GR.get(); }
105 
106   const CallLowering *getCallLowering() const override {
107     return CallLoweringInfo.get();
108   }
109   const RegisterBankInfo *getRegBankInfo() const override {
110     return RegBankInfo.get();
111   }
112   const LegalizerInfo *getLegalizerInfo() const override {
113     return Legalizer.get();
114   }
115   InstructionSelector *getInstructionSelector() const override {
116     return InstSelector.get();
117   }
118   const InlineAsmLowering *getInlineAsmLowering() const override {
119     return InlineAsmInfo.get();
120   }
121   const SPIRVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
122   const SPIRVFrameLowering *getFrameLowering() const override {
123     return &FrameLowering;
124   }
125   const SPIRVTargetLowering *getTargetLowering() const override {
126     return &TLInfo;
127   }
128   const SPIRVRegisterInfo *getRegisterInfo() const override {
129     return &InstrInfo.getRegisterInfo();
130   }
131 
132   static bool classof(const TargetSubtargetInfo *ST) {
133     return ST->getTargetTriple().isSPIRV();
134   }
135 
136   static constexpr unsigned MaxLegalAddressSpace = 6;
137 
138   // Adds known SPIR-V extensions to the global list of allowed extensions that
139   // SPIRVSubtarget module owns as
140   // cl::opt<std::set<SPIRV::Extension::Extension>, ...> global variable.
141   static void
142   addExtensionsToClOpt(const std::set<SPIRV::Extension::Extension> &AllowList);
143 };
144 } // namespace llvm
145 
146 #endif // LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
147