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/RegisterBankInfo.h"
26#include "llvm/CodeGen/TargetSubtargetInfo.h"
27#include "llvm/IR/DataLayout.h"
28#include "llvm/IR/Module.h"
29#include "llvm/Target/TargetMachine.h"
30#include "llvm/TargetParser/Triple.h"
31
32#define GET_SUBTARGETINFO_HEADER
33#include "SPIRVGenSubtargetInfo.inc"
34
35namespace llvm {
36class StringRef;
37class SPIRVTargetMachine;
38
39class SPIRVSubtarget : public SPIRVGenSubtargetInfo {
40public:
41 // Enum for the SPIR-V environment: Kernel, Shader or Unknown.
42 enum SPIRVEnvType { Kernel, Shader, Unknown };
43
44private:
45 const unsigned PointerSize;
46 VersionTuple SPIRVVersion;
47 VersionTuple OpenCLVersion;
48
49 SmallSet<SPIRV::Extension::Extension, 4> AvailableExtensions;
50 SmallSet<SPIRV::InstructionSet::InstructionSet, 4> AvailableExtInstSets;
51 std::unique_ptr<SPIRVGlobalRegistry> GR;
52
53 SPIRVInstrInfo InstrInfo;
54 SPIRVFrameLowering FrameLowering;
55 SPIRVTargetLowering TLInfo;
56 Triple TargetTriple;
57 SPIRVEnvType Env;
58
59 // GlobalISel related APIs.
60 std::unique_ptr<CallLowering> CallLoweringInfo;
61 std::unique_ptr<RegisterBankInfo> RegBankInfo;
62 std::unique_ptr<LegalizerInfo> Legalizer;
63 std::unique_ptr<InstructionSelector> InstSelector;
64 std::unique_ptr<InlineAsmLowering> InlineAsmInfo;
65
66 void initAvailableExtInstSets();
67 void accountForAMDShaderTrinaryMinmax();
68
69public:
70 // This constructor initializes the data members to match that
71 // of the specified triple.
72 SPIRVSubtarget(const Triple &TT, const std::string &CPU,
73 const std::string &FS, const SPIRVTargetMachine &TM);
74 SPIRVSubtarget &initSubtargetDependencies(StringRef CPU, StringRef FS);
75
76 void initAvailableExtensions(const ExtensionSet &AllowedExtIds);
77 void resolveEnvFromModule(const Module &M);
78
79 // Parses features string setting specified subtarget options.
80 // The definition of this function is auto generated by tblgen.
81 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
82 unsigned getPointerSize() const { return PointerSize; }
83 unsigned getBound() const { return GR->getBound(); }
84 bool canDirectlyComparePointers() const;
85 void setEnv(SPIRVEnvType E);
86 SPIRVEnvType getEnv() const { return Env; }
87 bool isKernel() const { return getEnv() == Kernel; }
88 bool isShader() const { return getEnv() == Shader; }
89 bool isLogicalSPIRV() const { return TargetTriple.isSPIRVLogical(); }
90 bool isPhysicalSPIRV() const {
91 return TargetTriple.getArch() == Triple::spirv32 ||
92 TargetTriple.getArch() == Triple::spirv64;
93 }
94 const std::string &getTargetTripleAsStr() const { return TargetTriple.str(); }
95 VersionTuple getSPIRVVersion() const { return SPIRVVersion; };
96 bool isAtLeastSPIRVVer(VersionTuple VerToCompareTo) const;
97 bool isAtLeastOpenCLVer(VersionTuple VerToCompareTo) const;
98 // TODO: implement command line args or other ways to determine this.
99 bool hasOpenCLFullProfile() const { return true; }
100 bool hasOpenCLImageSupport() const { return true; }
101 const SmallSet<SPIRV::Extension::Extension, 4> &
102 getAllAvailableExtensions() const {
103 return AvailableExtensions;
104 }
105 bool canUseExtension(SPIRV::Extension::Extension E) const;
106 bool canUseExtInstSet(SPIRV::InstructionSet::InstructionSet E) const;
107 SPIRV::InstructionSet::InstructionSet getPreferredInstructionSet() const;
108
109 SPIRVGlobalRegistry *getSPIRVGlobalRegistry() const { return GR.get(); }
110
111 const CallLowering *getCallLowering() const override {
112 return CallLoweringInfo.get();
113 }
114 const RegisterBankInfo *getRegBankInfo() const override {
115 return RegBankInfo.get();
116 }
117 const LegalizerInfo *getLegalizerInfo() const override {
118 return Legalizer.get();
119 }
120 InstructionSelector *getInstructionSelector() const override {
121 return InstSelector.get();
122 }
123 const InlineAsmLowering *getInlineAsmLowering() const override {
124 return InlineAsmInfo.get();
125 }
126 const SPIRVInstrInfo *getInstrInfo() const override { return &InstrInfo; }
127 const SPIRVFrameLowering *getFrameLowering() const override {
128 return &FrameLowering;
129 }
130 const SPIRVTargetLowering *getTargetLowering() const override {
131 return &TLInfo;
132 }
133 const SPIRVRegisterInfo *getRegisterInfo() const override {
134 return &InstrInfo.getRegisterInfo();
135 }
136
137 static bool classof(const TargetSubtargetInfo *ST) {
138 return ST->getTargetTriple().isSPIRV();
139 }
140
141 static constexpr unsigned MaxLegalAddressSpace = 6;
142
143 // Adds known SPIR-V extensions to the global list of allowed extensions that
144 // SPIRVSubtarget module owns as
145 // cl::opt<ExtensionSet, ...> global variable.
146 static void addExtensionsToClOpt(const ExtensionSet &AllowList);
147};
148} // namespace llvm
149
150#endif // LLVM_LIB_TARGET_SPIRV_SPIRVSUBTARGET_H
151