diff options
Diffstat (limited to 'llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h')
| -rw-r--r-- | llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h | 99 |
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); |
