diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2020-12-11 08:50:43 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-11 08:50:43 -0800 |
| commit | 992778e25c444932921ce92fe7934893b2aca35f (patch) | |
| tree | 4351c61079da5586c5f469dc8c989364c7a2bd4e /build | |
| parent | 4337338ed2d9525b4638f32c6b91ef61b69e41cd (diff) | |
Add first steps toward a "capability" system (#1636)
* Add first steps toward a "capability" system
We already have cases in the stdlib where we mark declarations as being specific to certain targets, e.g.:
```
// My ordinary function to add two numbers.
// Works everywhere.
//
void myFunc(int a, int b) { return a + b; }
// On the "coolgpu" target, we can use a secret intrinsic
// that adds numbers even faster!
//
__specialized_for_target(coolgpu)
void myFunc(int a, int b) { return __secretIntrinsic(a, b); }
```
The existing logic for dealing with these modifiers (`__specialized_for_target` and `__target_intrinsic`) was almost entirely string-based. We would turn the chosen compilation target into a string, and then use that to try and search for the "best" definition of a function at a few steps:
* During IR linking, we always pick one definition of an `[import]`ed function, and that definition will be the one with the "best" target-specialization modifier (if any)
* During final code generation, we always look up the "best" target-intrinsic modifier, and use it as the template for the code we output.
This change preserves the basic flow there, but replaces the ad hoc string-based logic with something a bit more principled, in terms of a new `CapabilitySet` type.
A `CapabilitySet` represents a set of zero or more atomic features (here represented as `CapabilityAtom`s). What a `CapabilitySet` means depends on how and where it is used:
* A compilation target implies a `CapabilitySet` where the contents of the set are the features the target *supports*.
* A `CapabilitySet` attached to a declaration (or a modifier on that declaration) describes a set of feature that declaration *requires*.
The current implementation of `CapabilitySet` is wasteful and inefficient, but that is something we can iterate on over time.
In practice, most of the current code only ever uses capability sets that are either empty (because they represent a function with no specific requirements) or singleton (because they represent asingle atomic capability like "is a GLSL target," "is an HLSL target," etc.).
The main goal here was to put in the skeleton of a new system, including some of the features it might need down the line, and then to leave changes that eventually use the greater flexibility for later. Eventually, the capability system should encompass:
* Differences between shader model versions, GLSL versions, SPIR-V versions, etc. (currently tracked with other modifiers)
* Optional extensions, and functions that are made available only with certain extensions (currently tracked with other modifiers)
* Front-end checking that the call graph of a program doesn't violate any capability-requirements (e.g., having a GLSL+HLSL portable function call a GLSL-only subroutine)
* Hypothetically we can also try to fold stage-specific (vertex-only, fragment-only, etc.) functions into this system, but doing so would require more linker cleverness if we allow overloading on stages (since we might have to clone a caller if it calls through to a callee with multiple stage-specific versions)
One important complication that the system has to deal with just because of the "do what I mean" nature of the current compiler is that somethings a current Slang user might compile for target X and specify version N, but then use a function that actually requires version N+1 of that target. Currently the Slang compiler silently "upgrades" the version(s) used by user code in these cases, because it is often what users want in cross-compilation scenarios.
Dealing with the "silent upgrade" situation requires us to be a little careful and sometimes pick a "best" capability set that doesn't appear to be supported on our target. Refining that system and potentially getting rid of the "do what I mean" behavior over time could be a goal for future changes.
* fixup: handle case where value is incompatible during linking
Diffstat (limited to 'build')
| -rw-r--r-- | build/visual-studio/slang/slang.vcxproj | 3 | ||||
| -rw-r--r-- | build/visual-studio/slang/slang.vcxproj.filters | 9 |
2 files changed, 12 insertions, 0 deletions
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj index 9eca53310..88c4b59e2 100644 --- a/build/visual-studio/slang/slang.vcxproj +++ b/build/visual-studio/slang/slang.vcxproj @@ -199,6 +199,8 @@ <ClInclude Include="..\..\..\source\slang\slang-ast-support-types.h" /> <ClInclude Include="..\..\..\source\slang\slang-ast-type.h" /> <ClInclude Include="..\..\..\source\slang\slang-ast-val.h" /> + <ClInclude Include="..\..\..\source\slang\slang-capability-defs.h" /> + <ClInclude Include="..\..\..\source\slang\slang-capability.h" /> <ClInclude Include="..\..\..\source\slang\slang-check-impl.h" /> <ClInclude Include="..\..\..\source\slang\slang-check.h" /> <ClInclude Include="..\..\..\source\slang\slang-compiler.h" /> @@ -315,6 +317,7 @@ <ClCompile Include="..\..\..\source\slang\slang-ast-substitutions.cpp" /> <ClCompile Include="..\..\..\source\slang\slang-ast-type.cpp" /> <ClCompile Include="..\..\..\source\slang\slang-ast-val.cpp" /> + <ClCompile Include="..\..\..\source\slang\slang-capability.cpp" /> <ClCompile Include="..\..\..\source\slang\slang-check-conformance.cpp" /> <ClCompile Include="..\..\..\source\slang\slang-check-constraint.cpp" /> <ClCompile Include="..\..\..\source\slang\slang-check-conversion.cpp" /> diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters index 426467529..60b3f0d65 100644 --- a/build/visual-studio/slang/slang.vcxproj.filters +++ b/build/visual-studio/slang/slang.vcxproj.filters @@ -48,6 +48,12 @@ <ClInclude Include="..\..\..\source\slang\slang-ast-val.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="..\..\..\source\slang\slang-capability-defs.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\..\source\slang\slang-capability.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="..\..\..\source\slang\slang-check-impl.h"> <Filter>Header Files</Filter> </ClInclude> @@ -392,6 +398,9 @@ <ClCompile Include="..\..\..\source\slang\slang-ast-val.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\..\source\slang\slang-capability.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\..\..\source\slang\slang-check-conformance.cpp"> <Filter>Source Files</Filter> </ClCompile> |
