LLVM 20.0.0git
SPIRVModuleAnalysis.h
Go to the documentation of this file.
1//===- SPIRVModuleAnalysis.h - analysis of global instrs & regs -*- 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// The analysis collects instructions that should be output at the module level
10// and performs the global register numbering.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVMODULEANALYSIS_H
15#define LLVM_LIB_TARGET_SPIRV_SPIRVMODULEANALYSIS_H
16
18#include "SPIRVGlobalRegistry.h"
19#include "SPIRVUtils.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallSet.h"
23
24namespace llvm {
25class SPIRVSubtarget;
26class MachineFunction;
27class MachineModuleInfo;
28
29namespace SPIRV {
30// The enum contains logical module sections for the instruction collection.
32 // MB_Capabilities, MB_Extensions, MB_ExtInstImports, MB_MemoryModel,
33 MB_EntryPoints, // All OpEntryPoint instructions (if any).
34 // MB_ExecutionModes, MB_DebugSourceAndStrings,
35 MB_DebugNames, // All OpName and OpMemberName intrs.
36 MB_DebugStrings, // All OpString intrs.
37 MB_DebugModuleProcessed, // All OpModuleProcessed instructions.
38 MB_Annotations, // OpDecorate, OpMemberDecorate etc.
39 MB_TypeConstVars, // OpTypeXXX, OpConstantXXX, and global OpVariables.
40 MB_NonSemanticGlobalDI, // OpExtInst with e.g. DebugSource, DebugTypeBasic.
41 MB_ExtFuncDecls, // OpFunction etc. to declare for external funcs.
42 NUM_MODULE_SECTIONS // Total number of sections requiring basic blocks.
43};
44
46 const bool IsSatisfiable;
47 const std::optional<Capability::Capability> Cap;
49 const VersionTuple MinVer; // 0 if no min version is required.
50 const VersionTuple MaxVer; // 0 if no max version is required.
51
53 std::optional<Capability::Capability> Cap = {},
57 MaxVer(MaxVer) {}
58 Requirements(Capability::Capability Cap) : Requirements(true, {Cap}) {}
59};
60
62private:
63 CapabilityList MinimalCaps;
64
65 // AllCaps and AvailableCaps are related but different. AllCaps is a subset of
66 // AvailableCaps. AvailableCaps is the complete set of capabilities that are
67 // available to the current target. AllCaps is the set of capabilities that
68 // are required by the current module.
70 DenseSet<unsigned> AvailableCaps;
71
73 VersionTuple MinVersion; // 0 if no min version is defined.
74 VersionTuple MaxVersion; // 0 if no max version is defined.
75 // Add capabilities to AllCaps, recursing through their implicitly declared
76 // capabilities too.
77 void recursiveAddCapabilities(const CapabilityList &ToPrune);
78
79 void initAvailableCapabilitiesForOpenCL(const SPIRVSubtarget &ST);
80 void initAvailableCapabilitiesForVulkan(const SPIRVSubtarget &ST);
81
82public:
84 void clear() {
85 MinimalCaps.clear();
86 AllCaps.clear();
87 AvailableCaps.clear();
88 AllExtensions.clear();
89 MinVersion = VersionTuple();
90 MaxVersion = VersionTuple();
91 }
92 const CapabilityList &getMinimalCapabilities() const { return MinimalCaps; }
94 return AllExtensions;
95 }
96 // Add a list of capabilities, ensuring AllCaps captures all the implicitly
97 // declared capabilities, and MinimalCaps has the minimal set of required
98 // capabilities (so all implicitly declared ones are removed).
99 void addCapabilities(const CapabilityList &ToAdd);
100 void addCapability(Capability::Capability ToAdd) { addCapabilities({ToAdd}); }
101 void addExtensions(const ExtensionList &ToAdd) {
102 AllExtensions.insert(ToAdd.begin(), ToAdd.end());
103 }
104 void addExtension(Extension::Extension ToAdd) { AllExtensions.insert(ToAdd); }
105 // Add the given requirements to the lists. If constraints conflict, or these
106 // requirements cannot be satisfied, then abort the compilation.
107 void addRequirements(const Requirements &Req);
108 // Get requirement and add it to the list.
109 void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category,
110 uint32_t i, const SPIRVSubtarget &ST);
111 // Check if all the requirements can be satisfied for the given subtarget, and
112 // if not abort compilation.
113 void checkSatisfiable(const SPIRVSubtarget &ST) const;
115 // Add the given capabilities to available and all their implicitly defined
116 // capabilities too.
117 void addAvailableCaps(const CapabilityList &ToAdd);
118 bool isCapabilityAvailable(Capability::Capability Cap) const {
119 return AvailableCaps.contains(Cap);
120 }
121
122 // Remove capability ToRemove, but only if IfPresent is present.
123 void removeCapabilityIf(const Capability::Capability ToRemove,
124 const Capability::Capability IfPresent);
125};
126
128// Maps a local register to the corresponding global alias.
129using LocalToGlobalRegTable = std::map<Register, Register>;
131 std::map<const MachineFunction *, LocalToGlobalRegTable>;
132
133// The struct contains results of the module analysis and methods
134// to access them.
137 MemoryModel::MemoryModel Mem;
138 AddressingModel::AddressingModel Addr;
139 SourceLanguage::SourceLanguage SrcLang;
142 // Maps ExtInstSet to corresponding ID register.
144 // Contains the list of all global OpVariables in the module.
146 // Maps functions to corresponding function ID registers.
148 // The set contains machine instructions which are necessary
149 // for correct MIR but will not be emitted in function bodies.
151 // The table contains global aliases of local registers for each machine
152 // function. The aliases are used to substitute local registers during
153 // code emission.
155 // The counter holds the maximum ID we have in the module.
156 unsigned MaxID;
157 // The array contains lists of MIs for each module section.
159 // The table maps MBB number to SPIR-V unique ID register.
161
163 assert(F && "Function is null");
164 auto FuncPtrRegPair = FuncMap.find(F);
165 return FuncPtrRegPair == FuncMap.end() ? Register(0)
166 : FuncPtrRegPair->second;
167 }
168 Register getExtInstSetReg(unsigned SetNum) { return ExtInstSetMap[SetNum]; }
169 InstrList &getMSInstrs(unsigned MSType) { return MS[MSType]; }
172 return InstrsToDelete.contains(MI);
173 }
175 Register AliasReg) {
176 RegisterAliasTable[MF][Reg] = AliasReg;
177 }
179 auto RI = RegisterAliasTable[MF].find(Reg);
180 if (RI == RegisterAliasTable[MF].end()) {
181 return Register(0);
182 }
183 return RegisterAliasTable[MF][Reg];
184 }
186 return RegisterAliasTable.find(MF) != RegisterAliasTable.end() &&
187 RegisterAliasTable[MF].find(Reg) != RegisterAliasTable[MF].end();
188 }
189 unsigned getNextID() { return MaxID++; }
191 auto Key = std::make_pair(MBB.getParent(), MBB.getNumber());
192 return BBNumToRegMap.contains(Key);
193 }
194 // Convert MBB's number to corresponding ID register.
196 auto Key = std::make_pair(MBB.getParent(), MBB.getNumber());
197 auto It = BBNumToRegMap.find(Key);
198 if (It != BBNumToRegMap.end())
199 return It->second;
201 BBNumToRegMap[Key] = NewReg;
202 return NewReg;
203 }
204};
205} // namespace SPIRV
206
208 static char ID;
209
210public:
212
213 bool runOnModule(Module &M) override;
214 void getAnalysisUsage(AnalysisUsage &AU) const override;
216
217private:
218 void setBaseInfo(const Module &M);
219 void collectGlobalEntities(
220 const std::vector<SPIRV::DTSortableEntry *> &DepsGraph,
222 std::function<bool(const SPIRV::DTSortableEntry *)> Pred,
223 bool UsePreOrder);
224 void processDefInstrs(const Module &M);
225 void collectFuncNames(MachineInstr &MI, const Function *F);
226 void processOtherInstrs(const Module &M);
227 void numberRegistersGlobally(const Module &M);
228 void collectFuncPtrs();
229 void collectFuncPtrs(MachineInstr *MI);
230
231 const SPIRVSubtarget *ST;
233 const SPIRVInstrInfo *TII;
235};
236} // namespace llvm
237#endif // LLVM_LIB_TARGET_SPIRV_SPIRVMODULEANALYSIS_H
ReachingDefAnalysis InstSet & ToRemove
MachineBasicBlock & MBB
basic Basic Alias true
This file defines the DenseMap class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
unsigned Reg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
spirv structurize SPIRV
This file defines the SmallSet class.
This file defines the SmallVector class.
Represent the analysis usage information of a pass.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:278
Representation of each machine instruction.
Definition: MachineInstr.h:69
This class contains meta information specific to a module.
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:251
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition: Register.h:84
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:132
void clear()
Definition: SmallSet.h:204
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:181
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:23
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:29
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:213
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:193
std::map< const MachineFunction *, LocalToGlobalRegTable > RegisterAliasMapTy
std::map< Register, Register > LocalToGlobalRegTable
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
static struct SPIRV::ModuleAnalysisInfo MAI
bool runOnModule(Module &M) override
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Register getRegisterAlias(const MachineFunction *MF, Register Reg)
SmallVector< MachineInstr *, 4 > GlobalVarList
Register getExtInstSetReg(unsigned SetNum)
bool hasMBBRegister(const MachineBasicBlock &MBB)
DenseMap< const Function *, Register > FuncMap
void setRegisterAlias(const MachineFunction *MF, Register Reg, Register AliasReg)
bool hasRegisterAlias(const MachineFunction *MF, Register Reg)
Register getOrCreateMBBRegister(const MachineBasicBlock &MBB)
InstrList & getMSInstrs(unsigned MSType)
bool getSkipEmission(const MachineInstr *MI)
InstrList MS[NUM_MODULE_SECTIONS]
AddressingModel::AddressingModel Addr
void setSkipEmission(MachineInstr *MI)
SourceLanguage::SourceLanguage SrcLang
DenseMap< std::pair< const MachineFunction *, int >, Register > BBNumToRegMap
Register getFuncReg(const Function *F)
DenseSet< MachineInstr * > InstrsToDelete
DenseMap< unsigned, Register > ExtInstSetMap
void checkSatisfiable(const SPIRVSubtarget &ST) const
void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category, uint32_t i, const SPIRVSubtarget &ST)
void addRequirements(const Requirements &Req)
bool isCapabilityAvailable(Capability::Capability Cap) const
void removeCapabilityIf(const Capability::Capability ToRemove, const Capability::Capability IfPresent)
void addExtensions(const ExtensionList &ToAdd)
void addAvailableCaps(const CapabilityList &ToAdd)
void addExtension(Extension::Extension ToAdd)
void initAvailableCapabilities(const SPIRVSubtarget &ST)
void addCapability(Capability::Capability ToAdd)
void addCapabilities(const CapabilityList &ToAdd)
const CapabilityList & getMinimalCapabilities() const
const SmallSet< Extension::Extension, 4 > & getExtensions() const
Requirements(bool IsSatisfiable=false, std::optional< Capability::Capability > Cap={}, ExtensionList Exts={}, VersionTuple MinVer=VersionTuple(), VersionTuple MaxVer=VersionTuple())
const std::optional< Capability::Capability > Cap
Requirements(Capability::Capability Cap)