|
| 1 | +======================================= |
| 2 | +SPIR-V versions and extensions handling |
| 3 | +======================================= |
| 4 | + |
| 5 | +.. contents:: |
| 6 | + :local: |
| 7 | + |
| 8 | +Overview |
| 9 | +======== |
| 10 | + |
| 11 | +This document describes how the translator makes decisions about using |
| 12 | +instructions from different version of the SPIR-V core and extension |
| 13 | +specifications. |
| 14 | + |
| 15 | +Being able to control the resulting SPIR-V version is important: the target |
| 16 | +consumer might be quite old, without support for new SPIR-V versions and there |
| 17 | +must be the possibility to control which version of the SPIR-V specification |
| 18 | +that will be used during translation. |
| 19 | + |
| 20 | +SPIR-V extensions is another thing which must be controllable. Extensions |
| 21 | +can update and re-define semantics and validation rules for existing SPIR-V |
| 22 | +entries and it is important to ensure that the translator is able to generate |
| 23 | +valid SPIR-V according to the core spec, without uses of any extensions if such |
| 24 | +SPIR-V was requested by user. |
| 25 | + |
| 26 | +For example, without such infrastructure it is impossible to disable use of |
| 27 | +``SPV_KHR_no_integer_wrap_decoration`` - it will be always generated if |
| 28 | +corresponding LLVM IR counterparts are encountered in input module. |
| 29 | + |
| 30 | +It is worth mentioning that SPIR-V versions and extensions the handling of |
| 31 | +SPIR-V versions and extension is mostly important for the SPIR-V generation |
| 32 | +step. On the consumer side it is the responsibility of the consumer to analyze |
| 33 | +the incoming SPIR-V file and reject it if it contains something that is not |
| 34 | +supported by the consumer. |
| 35 | + |
| 36 | +However, translator simplifies this step for downstream users by checking |
| 37 | +version and extensions in SPIR-V module during ``readSpirv``/``readSpirvModule`` |
| 38 | +phases. |
| 39 | + |
| 40 | +SPIR-V Versions |
| 41 | +=============== |
| 42 | + |
| 43 | +SPIR-V Generation step |
| 44 | +---------------------- |
| 45 | + |
| 46 | +By default translator selects version of generated SPIR-V file based on features |
| 47 | +used in this file. For example, if it contains ``dereferencable`` LLVM IR |
| 48 | +attribute, ``MaxByteOffset`` decoration will be generated and resulting SPIR-V |
| 49 | +version will be raised to 1.1. |
| 50 | + |
| 51 | +.. note:: |
| 52 | + There is no documentation about which exact features from newest |
| 53 | + SPIR-V spec versions will be used by the translator. If you are interested |
| 54 | + when or why a particular SPIR-V instruction is generated, please check this |
| 55 | + in the source code. Consider this as an implementation detail and if you |
| 56 | + disagree with something, you can always open an issue or submit pull request |
| 57 | + - contributions are welcome! |
| 58 | + |
| 59 | +There is one option to control the behavior of the translator with respect to |
| 60 | +the version of the SPIR-V file which is being generated/consumed. |
| 61 | + |
| 62 | +* ``--spirv-max-version=`` - instructs the translator to generate SPIR-V file |
| 63 | + corresponding to any spec version which is less than or equal to the |
| 64 | + specified one. Behavior of the translator is the same as by default with only |
| 65 | + one exception: resulting SPIR-V version cannot be raised higher than |
| 66 | + specified by this option. |
| 67 | + |
| 68 | +Allowed values are ``1.0`` and ``1.1``. |
| 69 | + |
| 70 | +.. warning:: |
| 71 | + These two options are mutually exclusive and cannot be specified at the |
| 72 | + same time. |
| 73 | + |
| 74 | +If the translator encounters something that cannot be represented by set of |
| 75 | +allowed SPIR-V versions (which might contain only one version), it does one of |
| 76 | +the following things: |
| 77 | + |
| 78 | +* ignores LLVM IR entity in the input file. |
| 79 | + |
| 80 | + For example, ``dereferencable`` LLVM IR attribute can be ignored if it is not |
| 81 | + allowed to generate SPIR-V 1.1 and higher. |
| 82 | + |
| 83 | +* tries to represent LLVM IR entity with allowed instructions. |
| 84 | + |
| 85 | + For example, ``OpPtrEqual`` can be used if SPIR-V 1.4 is not allowed and can |
| 86 | + be emulated via ``OpConvertPtrToU`` + ``OpIEqual`` sequence. |
| 87 | + |
| 88 | +* emits error if LLVM IR entity cannot be ignored and cannot be emulated using |
| 89 | + available instructions. |
| 90 | + |
| 91 | + For example, if global constructors/destructors |
| 92 | + (represented by @llvm.global_ctors/@llvm.global_dtors) are present in a module |
| 93 | + then the translator should emit error if it cannot use SPIR-V 1.1 and higher |
| 94 | + where ``Initializer`` and ``Finalizer`` execution modes are described. |
| 95 | + |
| 96 | +SPIR-V Consumption step |
| 97 | +----------------------- |
| 98 | + |
| 99 | +By default, translator consumes SPIR-V of any version which is supported. |
| 100 | + |
| 101 | +This behavior, however, can be controlled via the same switches described in |
| 102 | +the previous section. |
| 103 | + |
| 104 | +If one of the switches present and translator encountered SPIR-V file |
| 105 | +corresponding to a spec version which is not included into set of allowed |
| 106 | +SPIR-V versions, translator emits error. |
| 107 | + |
| 108 | +SPIR-V Extensions |
| 109 | +================= |
| 110 | + |
| 111 | +SPIR-V Generation step |
| 112 | +---------------------- |
| 113 | + |
| 114 | +By default, translator doesn't use any extensions. If it required to enable |
| 115 | +certain extension, the following command line option can be used: |
| 116 | + |
| 117 | +* ``--spirv-ext=`` - allows to control list of allowed/disallowed extensions. |
| 118 | + |
| 119 | +Valid value for this option is comma-separated list of extension names prefixed |
| 120 | +with ``+`` or ``-`` - plus means allow to use extension, minus means disallow |
| 121 | +to use extension. There is one more special value which can be used as extension |
| 122 | +name in this option: ``all`` - it affects all extension which are known to the |
| 123 | +translator. |
| 124 | + |
| 125 | +If ``--spirv-ext`` contains name of extension which is not know for the |
| 126 | +translator, it will emit error. |
| 127 | + |
| 128 | +Examples: |
| 129 | + |
| 130 | +* ``--spirv-ext=+SPV_KHR_no_integer_wrap_decoration,+SPV_INTEL_subgroups`` |
| 131 | +* ``--spirv-ext=+all,-SPV_INTEL_fpga_loop_controls`` |
| 132 | + |
| 133 | +.. warning:: |
| 134 | + Extension name cannot be allowed and disallowed at the same time: for inputs |
| 135 | + like ``--spirv-ext=+SPV_INTEL_subgroups,-SPV_INTEL_subgroups`` translator |
| 136 | + will emit error about invalid arguments. |
| 137 | + |
| 138 | +.. note:: |
| 139 | + Since by default during SPIR-V generation all extensions are disabled, this |
| 140 | + means that ``-all,`` is implicitly added at the beggining of the |
| 141 | + ``-spirv-ext`` value. |
| 142 | + |
| 143 | +If the translator encounters something that cannot be represented by set of |
| 144 | +allowed SPIR-V extensions (which might be empty), it does one of the following |
| 145 | +things: |
| 146 | + |
| 147 | +* ignores LLVM IR entity in the input file. |
| 148 | + |
| 149 | + For example, ``nsw``/``nuw`` LLVM IR attributes can be ignored if it is not |
| 150 | + allowed to generate SPIR-V 1.4 and ``SPV_KHR_no_integer_wrap_decoration`` |
| 151 | + extension is disallowed. |
| 152 | + |
| 153 | +* tries to represent LLVM IR entity with allowed instructions. |
| 154 | + |
| 155 | + Translator could translate calls to a new built-in functions defined by some |
| 156 | + extensions as usual call instructions without using special SPIR-V |
| 157 | + instructions. |
| 158 | + |
| 159 | + However, this could result in a strange SPIR-V and most likely will lead to |
| 160 | + errors during consumption. Having that, translator should emit errors if it |
| 161 | + encounters a call to a built-in function from an extension which must be |
| 162 | + represented as a special SPIR-V instruction from extension which wasn't |
| 163 | + allowed to be used. I.e. if translator knows that this certain LLVM IR entity |
| 164 | + belongs to an extension functionality and this extension is disallowed, it |
| 165 | + should emit error rather than emulating it. |
| 166 | + |
| 167 | +* emits error if LLVM IR entity cannot be ignored and cannot be emulated using |
| 168 | + available instructions. |
| 169 | + |
| 170 | + For example, new built-in types defined by |
| 171 | + ``cl_intel_device_side_avc_motion_estimation`` cannot be represented in SPIR-V |
| 172 | + if ``SPV_INTEL_device_side_avc_motion_estimation`` is disallowed. |
| 173 | + |
| 174 | +SPIR-V Consumption step |
| 175 | +----------------------- |
| 176 | + |
| 177 | +By default, translator consumes SPIR-V regardless of list extensions which are |
| 178 | +used by the input file, i.e. all extensions are allowed by default during |
| 179 | +consumption step. |
| 180 | + |
| 181 | +.. note:: |
| 182 | + This is opposite to the generation step and this is done on purpose: to not |
| 183 | + broke workflows of existing users of the translator. |
| 184 | + |
| 185 | +.. note:: |
| 186 | + Since by default during SPIR-V consumption all extensions are enabled, this |
| 187 | + means that ``+all,`` is implicitly added at the beggining of the |
| 188 | + ``-spirv-ext`` value. |
| 189 | + |
| 190 | +This behavior, however, can be controlled via the same switches described in |
| 191 | +the previous section. |
| 192 | + |
| 193 | +If ``--spirv-ext`` switch presents, translator will emit error if it finds out |
| 194 | +that input SPIR-V file uses disallowed extension. |
| 195 | + |
| 196 | +.. note:: |
| 197 | + If the translator encounters unknown extension in the input SPIR-V file, it |
| 198 | + will emit error regardless of ``-spirv-ext`` option value. |
| 199 | + |
| 200 | +If one of the switches present and translator encountered SPIR-V file |
| 201 | +corresponding to a spec version which is not included into set of allowed |
| 202 | +SPIR-V versions, translator emits error. |
| 203 | + |
| 204 | +How to control translator behavior when using it as library |
| 205 | +=========================================================== |
| 206 | + |
| 207 | +When using translator as library it can be controlled via bunch of alternative |
| 208 | +APIs that have additional argument: ``TranslatorOpts`` object which |
| 209 | +encapsulates information about available SPIR-V versions and extensions. |
| 210 | + |
| 211 | +List of new APIs is: ``readSpirvModule``, ``writeSpirv`` and ``readSpirv``. |
| 212 | + |
| 213 | +.. note:: |
| 214 | + See ``LLVMSPIRVOpts.h`` for more details. |
| 215 | + |
| 216 | +How to get ``TranslatorOpts`` object |
| 217 | +------------------------------------ |
| 218 | + |
| 219 | +1. Default constructor. Equal to: |
| 220 | + |
| 221 | + ``--spirv-max-version=MaxKnownVersion --spirv-ext=-all`` |
| 222 | + |
| 223 | + .. note:: |
| 224 | + There is method ``TranslatorOpts::enableAllExtensions()`` that allows you |
| 225 | + to quickly enable all known extensions if it is needed. |
| 226 | + |
| 227 | +2. Constructor which accepts all parameters |
| 228 | + |
| 229 | + Consumes both max SPIR-V version and optional map with extensions status |
| 230 | + (i.e. which one is allowed and which one is disallowed) |
| 231 | + |
| 232 | +Extensions status map |
| 233 | +^^^^^^^^^^^^^^^^^^^^^ |
| 234 | + |
| 235 | +This map is defined as ``std::map<ExtensionID, bool>`` and it is intended to |
| 236 | +show which extension is allowed to be used (``true`` as value) and which is not |
| 237 | +(``false`` as value). |
| 238 | + |
| 239 | +.. note:: |
| 240 | + If certain ``ExtensionID`` value is missed in the map, it automatically means |
| 241 | + that extension is not allowed to be used. |
| 242 | + |
| 243 | + This implies that by default, all extensions are disallowed. |
0 commit comments