summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h')
-rw-r--r--llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h99
1 files changed, 87 insertions, 12 deletions
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
index 9bcdf6e9ae2a..a8b659ce3957 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h
@@ -15,13 +15,15 @@
#define LLVM_LIB_TARGET_SPIRV_SPIRVMODULEANALYSIS_H
#include "MCTargetDesc/SPIRVBaseInfo.h"
-#include "SPIRVDuplicatesTracker.h"
-#include "SPIRVSubtarget.h"
+#include "SPIRVGlobalRegistry.h"
+#include "SPIRVUtils.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
namespace llvm {
+class SPIRVSubtarget;
class MachineFunction;
class MachineModuleInfo;
@@ -39,6 +41,77 @@ enum ModuleSectionType {
NUM_MODULE_SECTIONS // Total number of sections requiring basic blocks.
};
+struct Requirements {
+ const bool IsSatisfiable;
+ const std::optional<Capability::Capability> Cap;
+ const ExtensionList Exts;
+ const unsigned MinVer; // 0 if no min version is required.
+ const unsigned MaxVer; // 0 if no max version is required.
+
+ Requirements(bool IsSatisfiable = false,
+ std::optional<Capability::Capability> Cap = {},
+ ExtensionList Exts = {}, unsigned MinVer = 0,
+ unsigned MaxVer = 0)
+ : IsSatisfiable(IsSatisfiable), Cap(Cap), Exts(Exts), MinVer(MinVer),
+ MaxVer(MaxVer) {}
+ Requirements(Capability::Capability Cap) : Requirements(true, {Cap}) {}
+};
+
+struct RequirementHandler {
+private:
+ CapabilityList MinimalCaps;
+ SmallSet<Capability::Capability, 8> AllCaps;
+ SmallSet<Extension::Extension, 4> AllExtensions;
+ unsigned MinVersion; // 0 if no min version is defined.
+ unsigned MaxVersion; // 0 if no max version is defined.
+ DenseSet<unsigned> AvailableCaps;
+ // Remove a list of capabilities from dedupedCaps and add them to AllCaps,
+ // recursing through their implicitly declared capabilities too.
+ void pruneCapabilities(const CapabilityList &ToPrune);
+
+public:
+ RequirementHandler() : MinVersion(0), MaxVersion(0) {}
+ void clear() {
+ MinimalCaps.clear();
+ AllCaps.clear();
+ AvailableCaps.clear();
+ AllExtensions.clear();
+ MinVersion = 0;
+ MaxVersion = 0;
+ }
+ unsigned getMinVersion() const { return MinVersion; }
+ unsigned getMaxVersion() const { return MaxVersion; }
+ const CapabilityList &getMinimalCapabilities() const { return MinimalCaps; }
+ const SmallSet<Extension::Extension, 4> &getExtensions() const {
+ return AllExtensions;
+ }
+ // Add a list of capabilities, ensuring AllCaps captures all the implicitly
+ // declared capabilities, and MinimalCaps has the minimal set of required
+ // capabilities (so all implicitly declared ones are removed).
+ void addCapabilities(const CapabilityList &ToAdd);
+ void addCapability(Capability::Capability ToAdd) { addCapabilities({ToAdd}); }
+ void addExtensions(const ExtensionList &ToAdd) {
+ AllExtensions.insert(ToAdd.begin(), ToAdd.end());
+ }
+ void addExtension(Extension::Extension ToAdd) { AllExtensions.insert(ToAdd); }
+ // Add the given requirements to the lists. If constraints conflict, or these
+ // requirements cannot be satisfied, then abort the compilation.
+ void addRequirements(const Requirements &Req);
+ // Get requirement and add it to the list.
+ void getAndAddRequirements(SPIRV::OperandCategory::OperandCategory Category,
+ uint32_t i, const SPIRVSubtarget &ST);
+ // Check if all the requirements can be satisfied for the given subtarget, and
+ // if not abort compilation.
+ void checkSatisfiable(const SPIRVSubtarget &ST) const;
+ void initAvailableCapabilities(const SPIRVSubtarget &ST);
+ // Add the given capabilities to available and all their implicitly defined
+ // capabilities too.
+ void addAvailableCaps(const CapabilityList &ToAdd);
+ bool isCapabilityAvailable(Capability::Capability Cap) const {
+ return AvailableCaps.contains(Cap);
+ }
+};
+
using InstrList = SmallVector<MachineInstr *>;
// Maps a local register to the corresponding global alias.
using LocalToGlobalRegTable = std::map<Register, Register>;
@@ -48,17 +121,18 @@ using RegisterAliasMapTy =
// The struct contains results of the module analysis and methods
// to access them.
struct ModuleAnalysisInfo {
- SPIRV::MemoryModel Mem;
- SPIRV::AddressingModel Addr;
- SPIRV::SourceLanguage SrcLang;
+ RequirementHandler Reqs;
+ MemoryModel::MemoryModel Mem;
+ AddressingModel::AddressingModel Addr;
+ SourceLanguage::SourceLanguage SrcLang;
unsigned SrcLangVersion;
StringSet<> SrcExt;
// Maps ExtInstSet to corresponding ID register.
DenseMap<unsigned, Register> ExtInstSetMap;
// Contains the list of all global OpVariables in the module.
SmallVector<MachineInstr *, 4> GlobalVarList;
- // Maps function names to coresponding function ID registers.
- StringMap<Register> FuncNameMap;
+ // Maps functions to corresponding function ID registers.
+ DenseMap<const Function *, Register> FuncMap;
// The set contains machine instructions which are necessary
// for correct MIR but will not be emitted in function bodies.
DenseSet<MachineInstr *> InstrsToDelete;
@@ -76,10 +150,11 @@ struct ModuleAnalysisInfo {
// The table maps MBB number to SPIR-V unique ID register.
DenseMap<int, Register> BBNumToRegMap;
- Register getFuncReg(std::string FuncName) {
- auto FuncReg = FuncNameMap.find(FuncName);
- assert(FuncReg != FuncNameMap.end() && "Cannot find function Id");
- return FuncReg->second;
+ Register getFuncReg(const Function *F) {
+ assert(F && "Function is null");
+ auto FuncPtrRegPair = FuncMap.find(F);
+ assert(FuncPtrRegPair != FuncMap.end() && "Cannot find function ID");
+ return FuncPtrRegPair->second;
}
Register getExtInstSetReg(unsigned SetNum) { return ExtInstSetMap[SetNum]; }
InstrList &getMSInstrs(unsigned MSType) { return MS[MSType]; }
@@ -136,7 +211,7 @@ private:
std::function<bool(const SPIRV::DTSortableEntry *)> Pred,
bool UsePreOrder);
void processDefInstrs(const Module &M);
- void collectFuncNames(MachineInstr &MI, const Function &F);
+ void collectFuncNames(MachineInstr &MI, const Function *F);
void processOtherInstrs(const Module &M);
void numberRegistersGlobally(const Module &M);