|
| 1 | +:extension_name: SPV_INTEL_loop_dependence_annotations |
| 2 | +:llvm_capability_name: AccessGroupAnnotationINTEL |
| 3 | +:sycl_capability_name: DependencyAnnotationINTEL |
| 4 | +:instruction_name: OpAccessGroupDeclINTEL |
| 5 | +:aggregator_name: OpAccessGroupListINTEL |
| 6 | +:decoration_name: AccessGroupINTEL |
| 7 | +:mem_op_name: AccessGroupMaskINTEL |
| 8 | +:da_loop_control: DependencyAccessesINTEL |
| 9 | +:pa_loop_control: ParallelAccessesINTEL |
| 10 | + |
| 11 | += {extension_name} |
| 12 | + |
| 13 | +== Name Strings |
| 14 | + |
| 15 | +{extension_name} |
| 16 | + |
| 17 | +== Contact |
| 18 | + |
| 19 | +To report problems with this extension, please open a new issue at: |
| 20 | + |
| 21 | +https://github.com/KhronosGroup/SPIRV-Registry |
| 22 | + |
| 23 | +== Contributors |
| 24 | + |
| 25 | +* Adel Ejjeh, Intel |
| 26 | +* Joe Garvey, Intel |
| 27 | +* Mark P Mendell, Intel |
| 28 | + |
| 29 | +== Notice |
| 30 | + |
| 31 | +Copyright (c) 2024 Intel Corporation. All rights reserved. |
| 32 | + |
| 33 | +== Status |
| 34 | + |
| 35 | +* Working Draft |
| 36 | + |
| 37 | +This is a preview extension specification, intended to provide early access to a feature for review and community feedback. When the feature matures, this specification may be released as a formal extension. |
| 38 | + |
| 39 | +Because the interfaces defined by this specification are not final and are subject to change they are not intended to be used by shipping software products. If you are interested in using this feature in your software product, please let us know! |
| 40 | + |
| 41 | +== Version |
| 42 | + |
| 43 | +[width="40%",cols="25,25"] |
| 44 | +|======================================== |
| 45 | +| Last Modified Date | {docdate} |
| 46 | +| Revision | 2 |
| 47 | +|======================================== |
| 48 | + |
| 49 | +== Dependencies |
| 50 | + |
| 51 | +This extension is written against the SPIR-V Specification, Version 1.6 Revision |
| 52 | +3. |
| 53 | + |
| 54 | +This extension requires SPIR-V 1.0. |
| 55 | + |
| 56 | +== Overview |
| 57 | + |
| 58 | +This extension adds the ability to specify an access group for memory operations |
| 59 | +and function calls, and then use these access groups to identify which memory |
| 60 | +operations have no loop-carried dependencies. The extension was added to |
| 61 | +incorporate support for the community LLVM metadata: `llvm.access.group` and |
| 62 | +`llvm.loop.parallel_accesses`, as well as Intel-specific metadata: |
| 63 | +`llvm.loop.no_depends` and `llvm.loop.no_depends_safelen`. The extension tracks |
| 64 | +access groups using literals, and introduces a new instruction for aggregating |
| 65 | +access groups into a list (*{aggregator_name}*), a decoration |
| 66 | +(*{decoration_name}*) and memory operand (*{mem_op_name}*) to assign access |
| 67 | +groups to operations, and two loop controls that indicate that operations with |
| 68 | +the specified access groups don't have loop-carried data dependencies |
| 69 | +(*{da_loop_control}*) and don't have loop-carried data and memory ordering |
| 70 | +dependencies (*{pa_loop_control}*). We split the new additions into two |
| 71 | +capabilities, one that is sufficient to support community LLVM |
| 72 | +(*{llvm_capability_name}*), and one that adds the support for the Intel-specific |
| 73 | +LLVM-extensions (*{sycl_capability_name}*). |
| 74 | + |
| 75 | +== Extension Name |
| 76 | + |
| 77 | +To use this extension within a SPIR-V module, the following |
| 78 | +*OpExtension* must be present in the module: |
| 79 | + |
| 80 | +[subs="attributes"] |
| 81 | +---- |
| 82 | +OpExtension "{extension_name}" |
| 83 | +---- |
| 84 | + |
| 85 | +== Modifications to the SPIR-V Specification, Version 1.6 |
| 86 | + |
| 87 | +=== Capabilities |
| 88 | + |
| 89 | +Modify Section 3.31, "Capability", adding these rows to the Capability table: |
| 90 | + |
| 91 | +-- |
| 92 | +[cols="^.^2,16,15",options="header"] |
| 93 | +|==== |
| 94 | +2+^.^| Capability | Implicitly Declares |
| 95 | +| 6200 | *{llvm_capability_name}* + |
| 96 | +Enables specifying access groups on operations and identifying which operations |
| 97 | +don't have loop-carried data and memory-ordering dependences. |
| 98 | +| |
| 99 | +| 6201 | *{sycl_capability_name}* + |
| 100 | +Enables identifying which operations |
| 101 | +don't have loop-carried data (only) dependences. |
| 102 | +|*{llvm_capability_name}* |
| 103 | +|==== |
| 104 | +-- |
| 105 | + |
| 106 | +=== Instructions |
| 107 | + |
| 108 | +Add to Section 3.49.3, "Annotation Instructions": |
| 109 | + |
| 110 | +// [cols="1,2,2",width="100%"] |
| 111 | +// |===== |
| 112 | +// 2+|*{instruction_name}* + |
| 113 | +// + |
| 114 | +// This instruction declares an access group. + |
| 115 | + |
| 116 | +// _Result_ is used by *{aggregator_name}*, *{decoration_name}*, and |
| 117 | +// *{mem_op_name}*. |
| 118 | + |
| 119 | +// 1+|Capability: + |
| 120 | +// *{llvm_capability_name}* |
| 121 | +// 1+| 2 | 6450 |
| 122 | +// | _Result <id>_ |
| 123 | +// |===== |
| 124 | + |
| 125 | +[cols="1,2,3,3",width="100%"] |
| 126 | +|===== |
| 127 | +3+|*{aggregator_name}* + |
| 128 | + + |
| 129 | +This instruction declares an access group list. + |
| 130 | + |
| 131 | +_Result_ is used by *{da_loop_control}* and *{pa_loop_control}*. + |
| 132 | + |
| 133 | +Operands are one or more access groups (literals). |
| 134 | +1+|Capability: + |
| 135 | +*{llvm_capability_name}* |
| 136 | +1+| 3+variable | 6202 |
| 137 | +| _Result <id>_ |
| 138 | +| _literal_, _literal_, ... + |
| 139 | +_Access Group 1_, _Access Group 2_, ... |
| 140 | +|===== |
| 141 | + |
| 142 | +Add to Section 3.49.18, Atomic Instructions: |
| 143 | + |
| 144 | +[cols="1,1,2,2,2,3,2",width="100%"] |
| 145 | +|===== |
| 146 | +5+|*OpAtomicStoreRetINTEL* + |
| 147 | + + |
| 148 | +A variant of *OpAtomicStore* that returns a _Result_ to allow decorations. This |
| 149 | +is needed to be able to decorate an atomic store with *{decoration_name}*. + |
| 150 | + |
| 151 | +The _Result_ can only be used in decoration instructions and nothing else. |
| 152 | + |
| 153 | +2+|Capability: + |
| 154 | +*{llvm_capability_name}* |
| 155 | +1+| 6 | 6203 |
| 156 | +| _Result <id>_ |
| 157 | +| _<id>_ + |
| 158 | +_Pointer_ |
| 159 | +| _Scope <id>_ + |
| 160 | +_Memory_ |
| 161 | +| _Memory Semantics <id>_ + |
| 162 | +_Semantics_ |
| 163 | +|_<id>_ + |
| 164 | +_Value_ |
| 165 | +|===== |
| 166 | + |
| 167 | +[cols="1,1,2,2,2,3",width="100%"] |
| 168 | +|===== |
| 169 | +5+|*OpAtomicFlagClearRetINTEL* + |
| 170 | + + |
| 171 | +A variant of *OpAtomicFlagClear* that returns a _Result_ to allow decorations. This |
| 172 | +is needed to be able to decorate an atomic flag clear with *{decoration_name}*. + |
| 173 | + |
| 174 | +The _Result_ can only be used in decoration instructions and nothing else. |
| 175 | + |
| 176 | +1+|Capability: + |
| 177 | +*{llvm_capability_name}* |
| 178 | +1+| 5 | 6204 |
| 179 | +| _Result <id>_ |
| 180 | +| _<id>_ + |
| 181 | +_Pointer_ |
| 182 | +| _Scope <id>_ + |
| 183 | +_Memory_ |
| 184 | +| _Memory Semantics <id>_ + |
| 185 | +_Semantics_ |
| 186 | +|===== |
| 187 | + |
| 188 | + |
| 189 | + |
| 190 | +=== Validation Rules |
| 191 | + |
| 192 | +Add a validation rule to section 2.16.1, "Universal Validation Rules": |
| 193 | + |
| 194 | +* The _Result_ of *OpAtomicStoreRetINTEL* and *OpAtomicFlagClearRetINTEL* can only be used |
| 195 | +in decoration instructions. |
| 196 | + |
| 197 | +Additionally, we need to verify whether any changes to the existing validation |
| 198 | +rules will be necessary to accommodate the modified instructions, and if adding |
| 199 | +instructions whose returned ID cannot be used as operands to other instructions |
| 200 | +may break any fundamental assumptions in the validator. |
| 201 | + |
| 202 | +=== Decorations |
| 203 | + |
| 204 | +Modify Section 3.20, Decoration, adding these rows to the Decoration table: |
| 205 | + |
| 206 | +-- |
| 207 | +[cols="^4,20,10,10",options="header",subs="attributes"] |
| 208 | +|==== |
| 209 | +2+^.^| Decoration | Extra Operands | Enabling Capabilities |
| 210 | +| 6205 | *{decoration_name}* + |
| 211 | +Can only be applied to *OpFunctionCall* and _Atomic_ instructions. Indicates the |
| 212 | +list of access groups that the decorated instruction belongs to. Operand is one |
| 213 | +or more literals that correspond to the access groups. |
| 214 | +| _literal_, _literal_, ... + |
| 215 | +_Access Group 1_, _Access Group 2_, ... | *{llvm_capability_name}* |
| 216 | +|==== |
| 217 | +-- |
| 218 | + |
| 219 | + |
| 220 | + |
| 221 | +=== Memory Operands |
| 222 | + |
| 223 | +Modify Section 3.26, "Memory Operands", adding these rows to the Memory Operand table: |
| 224 | + |
| 225 | +-- |
| 226 | +[cols="^.^2,16,5",options="header"] |
| 227 | +|==== |
| 228 | +2+^.^| Memory Operands | Enabling Capabilities |
| 229 | +| 0x40000 | *{mem_op_name}* + |
| 230 | +Followed by a number _N_ that indicates how many access groups this operation |
| 231 | +belongs to, and _N_ literals that correspond to the access groups. Indicates |
| 232 | +that this memory operation belongs to the specified access group(s). |
| 233 | +| *{llvm_capability_name}* |
| 234 | +|==== |
| 235 | +-- |
| 236 | + |
| 237 | +=== Loop Control |
| 238 | + |
| 239 | +Modify Section 3.23, "Loop Control", adding these rows to the Loop Control table: |
| 240 | + |
| 241 | +-- |
| 242 | +[cols="^.^2,16,5",options="header"] |
| 243 | +|==== |
| 244 | +2+^.^| Loop Control | Enabling Capabilities |
| 245 | +| 0x4000000 | *{pa_loop_control}* + |
| 246 | +Followed by a number _N_ >= 1 that indicates how many operands will follow, and |
| 247 | +_N_ _<id>_'s that are the result of *{aggregator_name}*. Indicates that for each |
| 248 | +list of access groups pointed to by an _<id>_, all operations with those access |
| 249 | +groups do not have any loop-carried data or memory-ordering dependencies carried by this loop. |
| 250 | +| *{llvm_capability_name}* |
| 251 | +| 0x8000000 | *{da_loop_control}* + |
| 252 | +Followed by a number _N_ >= 1 that indicates how many operands will follow, and |
| 253 | +_N_ pairs {_<id>_, _S_}. _<id>_ is a list of access groups coming from |
| 254 | +*{aggregator_name}*. _S_ is a literal >=0 indicating that the loop-carried |
| 255 | +dependence distance between any operations that belong to the specified access |
| 256 | +group(s) in _<id>_ is guaranteed to be greater than _S_. This means that there |
| 257 | +is no dependence with distance < _S_, but there could be a dependence with |
| 258 | +distance >= _S_. _S_=0 means that there are no loop-carried data dependencies |
| 259 | +carried by this loop between the operations. |
| 260 | +| *{sycl_capability_name}* |
| 261 | +|==== |
| 262 | +-- |
| 263 | + |
| 264 | +== Revision History |
| 265 | + |
| 266 | +[cols="5,15,15,70"] |
| 267 | +[grid="rows"] |
| 268 | +[options="header"] |
| 269 | +|======================================== |
| 270 | +|Rev|Date|Author|Changes |
| 271 | +|1|2024-02-28|Adel Ejjeh|*Initial revision* |
| 272 | +|2|2024-03-04|Adel Ejjeh|*Make AGs literals, update tokens* |
| 273 | +|3|2024-05-14|Adel Ejjeh|*Update instruction names and Validation section* |
| 274 | +|======================================== |
0 commit comments