Skip to content

Commit 2acccd1

Browse files
aratajewigcbot
authored andcommitted
SPIR-V extensions and capabilities support - per-device infrastructure
TableGen backend extended to emit a standalone C++ header exposing per-device SPIR-V extension and capability support (query functions + data). Neo ↔ IGC interface updated: now passes a YAML blob enumerating supported SPIR-V extensions/capabilities per device instead of a single global set. Added (disabled-by-default) validation in dllInterfaceCompute to reject SPIR-V modules containing any unsupported extension on the target device. Markdown documentation generation enhanced: now lists platform support for each extension and capability. Current .td extension/capability lists and platform support tags are provisional/incomplete; validation remains off until lists are finalized.
1 parent e6ac6be commit 2acccd1

16 files changed

+1024
-253
lines changed

IGC/AdaptorOCL/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ set_target_properties("${IGC_BUILD__PROJ__AdaptorOCL}" PROPERTIES FOLDER "Librar
128128

129129
add_dependencies("${IGC_BUILD__PROJ__AdaptorOCL}" "${IGC_BUILD__PROJ__GenISAIntrinsics}")
130130
if(USE_SPIRV_EXTENSIONS_YAML_GENERATOR)
131-
add_dependencies(${IGC_BUILD__PROJ__AdaptorOCL} IGCCSPIRVExtensionsYaml)
131+
add_dependencies(${IGC_BUILD__PROJ__AdaptorOCL} SPIRVExtensionsSupportGen)
132132
endif()
133133
set_property(TARGET "${IGC_BUILD__PROJ__AdaptorOCL}" PROPERTY PROJECT_LABEL "${IGC_BUILD__PROJ_LABEL__AdaptorOCL}")
134134

IGC/AdaptorOCL/Utils/YamlAndDocsTblgen/CMakeLists.txt renamed to IGC/AdaptorOCL/Utils/IGCCSPIRVSupportTblGen/CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@
88

99
include(TableGen)
1010

11-
add_tablegen(igcc-yaml-docs-tblgen IGCC_YAML_DOCS_TBLGEN
12-
IGCCOptionsAndCapabilitiesEmitter.cpp
11+
add_tablegen(igcc-spirv-support-tblgen IGCC_YAML_DOCS_TBLGEN
12+
IGCCSPIRVSupportTblGen.cpp
1313
)
1414

1515
set(LLVM_LINK_COMPONENTS
1616
Support
1717
TableGen
1818
)
1919

20-
llvm_update_compile_flags(igcc-yaml-docs-tblgen)
20+
llvm_update_compile_flags(igcc-spirv-support-tblgen)
2121

2222
# Always link static TableGen explicitly — never rely on libLLVM.so here
2323
# TableGen is never part of libLLVM.so (ref: llvm-project/llvm/tools/llvm-shlib/CMakeLists.txt)
24-
target_link_libraries(igcc-yaml-docs-tblgen PRIVATE
24+
target_link_libraries(igcc-spirv-support-tblgen PRIVATE
2525
LLVMSupport
2626
LLVMTableGen
2727
)
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*========================== begin_copyright_notice ============================
2+
3+
Copyright (C) 2025 Intel Corporation
4+
5+
SPDX-License-Identifier: MIT
6+
7+
============================= end_copyright_notice ===========================*/
8+
9+
/*==============================================================================
10+
* Platform support types and helpers for IGCCSPIRVSupportTblGen
11+
*============================================================================*/
12+
#pragma once
13+
14+
#include "llvm/ADT/StringRef.h"
15+
#include "llvm/ADT/SmallVector.h"
16+
#include "llvm/TableGen/Record.h"
17+
#include "llvm/TableGen/Error.h"
18+
19+
namespace IGCCSPIRVPlatformSupport {
20+
// Selective LLVM symbols imported to avoid polluting including translation units.
21+
using llvm::PrintFatalError;
22+
using llvm::Record;
23+
using llvm::RecordKeeper;
24+
using llvm::SmallVector;
25+
using llvm::StringRef;
26+
27+
// Classification of platform support descriptors.
28+
enum class PlatformSupportKind {
29+
All,
30+
NotSupported,
31+
InheritFromExtension,
32+
CoreChildOf,
33+
ExactPlatform,
34+
InGroup,
35+
AnyOf,
36+
Unknown
37+
};
38+
39+
// Capability entry for an extension.
40+
struct CapabilityEntry {
41+
StringRef Name;
42+
const Record *Root; // original capability record
43+
const Record *EffectivePlatform; // resolved support (extension or capability)
44+
};
45+
46+
struct ExtensionEntry {
47+
StringRef Name;
48+
StringRef SpecURL;
49+
const Record *Root; // original extension record
50+
const Record *Platforms; // extension support record (raw)
51+
bool IsInheritFromCapabilitiesMode; // true if extSupport == InheritFromCapabilities (aggregated capability mode)
52+
SmallVector<CapabilityEntry, 8> Capabilities;
53+
};
54+
55+
// Container alias for list of extensions
56+
using SPIRVExtensions = SmallVector<ExtensionEntry, 64>;
57+
58+
inline PlatformSupportKind classifyPlatformSupport(const Record *R) {
59+
StringRef Name = R->getName();
60+
if (Name == "AllPlatformSupport")
61+
return PlatformSupportKind::All;
62+
if (Name == "NotSupported")
63+
return PlatformSupportKind::NotSupported;
64+
if (Name == "InheritFromExtension")
65+
return PlatformSupportKind::InheritFromExtension;
66+
if (R->isSubClassOf("isCoreChildOf"))
67+
return PlatformSupportKind::CoreChildOf;
68+
if (R->isSubClassOf("ExactPlatform"))
69+
return PlatformSupportKind::ExactPlatform;
70+
if (R->isSubClassOf("isInGroup"))
71+
return PlatformSupportKind::InGroup;
72+
if (R->isSubClassOf("AnyOf"))
73+
return PlatformSupportKind::AnyOf;
74+
return PlatformSupportKind::Unknown;
75+
}
76+
77+
static void validateExtensionPlatformSupport(const Record *Ext) {
78+
const Record *ExtSupport = Ext->getValueAsDef("ExtSupport");
79+
const StringRef ExtSupportName = ExtSupport->getName();
80+
const StringRef ExtName = Ext->getValueAsString("ExtName");
81+
const bool IsAggregateMode = (ExtSupportName == "InheritFromCapabilities");
82+
83+
if (ExtSupportName == "InheritFromExtension") {
84+
PrintFatalError(
85+
Ext->getLoc(),
86+
"Extension '" + ExtName.str() +
87+
"' cannot use InheritFromExtension; specify explicit platform support or InheritFromCapabilities.");
88+
}
89+
90+
auto Caps = Ext->getValueAsListOfDefs("ExtCapabilities");
91+
for (const Record *Cap : Caps) {
92+
const Record *CapSupport = Cap->getValueAsDef("Support");
93+
const StringRef CapSupportName = CapSupport->getName();
94+
const StringRef CapName = Cap->getValueAsString("Name");
95+
96+
if (CapSupportName == "InheritFromCapabilities") {
97+
PrintFatalError(Cap->getLoc(), "Capability '" + CapName + "' in extension '" + ExtName +
98+
"' cannot use InheritFromCapabilities.");
99+
}
100+
if (IsAggregateMode) {
101+
if (CapSupportName == "InheritFromExtension") {
102+
PrintFatalError(Cap->getLoc(), "Capability '" + CapName + "' in extension '" + ExtName +
103+
"' must specify explicit platform support.");
104+
}
105+
} else {
106+
if (CapSupportName != "InheritFromExtension") {
107+
PrintFatalError(Cap->getLoc(),
108+
"Capability '" + CapName + "' in extension '" + ExtName +
109+
"' sets explicit Support; set extension platform support to InheritFromCapabilities.");
110+
}
111+
}
112+
}
113+
}
114+
115+
static SPIRVExtensions collectSPIRVExtensionSupport(const RecordKeeper &Records) {
116+
SPIRVExtensions Result;
117+
auto AllExtensions = Records.getAllDerivedDefinitions("SPIRVExtension");
118+
Result.reserve(AllExtensions.size());
119+
for (const Record *Ext : AllExtensions) {
120+
validateExtensionPlatformSupport(Ext);
121+
ExtensionEntry Entry;
122+
Entry.Name = Ext->getValueAsString("ExtName");
123+
Entry.SpecURL = Ext->getValueAsString("ExtSpecURL");
124+
Entry.Root = Ext;
125+
Entry.Platforms = Ext->getValueAsDef("ExtSupport");
126+
Entry.IsInheritFromCapabilitiesMode = Entry.Platforms->getName() == "InheritFromCapabilities";
127+
auto Caps = Ext->getValueAsListOfDefs("ExtCapabilities");
128+
for (const Record *Cap : Caps) {
129+
CapabilityEntry CapEntry;
130+
CapEntry.Name = Cap->getValueAsString("Name");
131+
CapEntry.Root = Cap;
132+
const Record *CapSupport = Cap->getValueAsDef("Support");
133+
if (CapSupport->getName() == "InheritFromExtension" && Entry.Platforms->getName() != "InheritFromCapabilities") {
134+
CapEntry.EffectivePlatform = Entry.Platforms;
135+
} else {
136+
CapEntry.EffectivePlatform = CapSupport; // explicit capability support or InheritFromCapabilities mode
137+
}
138+
Entry.Capabilities.push_back(CapEntry);
139+
}
140+
Result.push_back(std::move(Entry));
141+
}
142+
return Result;
143+
}
144+
145+
} // namespace IGCCSPIRVPlatformSupport

0 commit comments

Comments
 (0)