Skip to content

Commit c25df9c

Browse files
Mike Kinsnerbader
authored andcommitted
Initial GitHub revision of Intel SPIR-V function pointer (work-in-progress) extension (#353)
1 parent 688c301 commit c25df9c

File tree

1 file changed

+339
-0
lines changed

1 file changed

+339
-0
lines changed
Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
= SPV_INTEL_function_pointers
2+
3+
== Name Strings
4+
5+
SPV_INTEL_function_pointers
6+
7+
== Contact
8+
9+
To report problems or to provide input on this extension, please open a new issue at:
10+
11+
https://github.com/intel/llvm/issues
12+
13+
== Contributors
14+
15+
- Alexey Sachkov, Intel
16+
- Mariusz Merecki, Intel
17+
- Ben Ashbaugh, Intel
18+
- Pawel Jurek, Intel
19+
- Thomas Raoux, Intel
20+
21+
== Notice
22+
23+
Copyright (c) 2019 Intel Corporation. All rights reserved.
24+
25+
== Status
26+
27+
Working Draft
28+
29+
This is a preview extension specification, intended to provide early access to a feature for review and community feedback.
30+
When the feature matures, this specification may be released as a formal extension.
31+
32+
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.
33+
If you are interested in using this feature in your software product, please let us know!
34+
35+
== Version
36+
37+
[width="40%",cols="25,25"]
38+
|==================================
39+
| Last Modified Date | {docdate}
40+
| Revision | G
41+
|==================================
42+
43+
== Dependencies
44+
45+
This extension is written against the SPIR-V Specification, Version 1.4
46+
Revision 1, Unified.
47+
48+
This extension requires SPIR-V 1.0.
49+
50+
== Overview
51+
52+
The goal of this extension is to allow translation of function pointers into
53+
SPIR-V.
54+
55+
This extensions brings two "levels" of function pointers support added under
56+
corresponding capabilities:
57+
58+
- Two new instructions added to support "address of" operator and indirect
59+
function call under *FunctionPointersINTEL* capability
60+
- One new decoration added under *IndirectReferencesINTEL* to support functions
61+
which are not referenced directly in the module. The idea is to extract
62+
pointer to a function from the module and pass it as argument into one of
63+
entry points where it will be used.
64+
See *cl_intel_function_pointers* extension specification for more details.
65+
66+
== Extension Name
67+
68+
To use this extension within a SPIR-V module, the appropriate *OpExtension*
69+
must be present in the module:
70+
71+
----
72+
OpExtension "SPV_INTEL_function_pointers"
73+
----
74+
75+
== New Capabilities
76+
77+
This extension introduces new capabilities:
78+
79+
----
80+
FunctionPointersINTEL
81+
IndirectReferencesINTEL
82+
----
83+
84+
== New Instructions
85+
86+
Instructions added under the *FunctionPointersINTEL* capability:
87+
88+
----
89+
OpFunctionPointerINTEL
90+
OpFunctionPointerCallINTEL
91+
----
92+
93+
== New Decorations
94+
95+
Decorations added under the *IndirectlyReferencableINTEL* capability:
96+
97+
----
98+
ReferencedIndirectlyINTEL
99+
----
100+
101+
== New Storage Classes
102+
103+
Storage Classes added under the *FunctionPointersINTEL* capability:
104+
105+
----
106+
CodeSectionINTEL
107+
----
108+
109+
110+
== Token Number Assignments
111+
112+
[width="40%"]
113+
[cols="70%,30%"]
114+
[grid="rows"]
115+
|====
116+
|OpFunctionPointerINTEL | 5600
117+
|OpFunctionPointerCallINTEL | 5601
118+
|ReferencedIndirectlyINTEL | 5602
119+
|FunctionPointersINTEL | 5603
120+
|IndirectReferencesINTEL | 5604
121+
|CodeSectionINTEL | 5605
122+
|====
123+
124+
== Modifications to the SPIR-V Specification, Version 1.4
125+
126+
=== Terms
127+
128+
[red]*TODO* Should we update _Opaque Type_ definition with function pointers
129+
which points to functions taking Opaque types as arguments or returning them?
130+
131+
Modify Section 2.2.2, Types, add the following at the end of the section: ::
132+
133+
[[FunctionPointer]]'Function Pointer': A pointer that results from the following
134+
instruction:
135+
136+
- *OpFunctionPointerINTEL*
137+
138+
Additionally, any *OpSelect*, *OpPhi*, *OpFunctionCall*, *OpPtrAccessChain*,
139+
*OpLoad*, *OpAccessChain*, *OpInBoundAccessChain*, or *OpCopyObject* thas takes
140+
a function pointer as an operand also produces a function pointer. An
141+
*OpFunctionParameter* of pointer type is function pointer if any
142+
*OpFunctionCall* to the function statically passes a function pointer as the
143+
value of the parameter. *OpConstantNull* returns function pointer if 'Result
144+
type' is function pointer.
145+
146+
Modify Section 2.9, Function Calling, add the following after the first sentence: ::
147+
148+
Functions can be called indirectly using function pointers: to do so, use
149+
*OpFunctionPointerCallINTEL* with an operand that is the _<id>_ obtained using
150+
*OpFunctionPointerINTEL* of the *OpFunction* to call, and the _<id>s_ of the
151+
arguments to pass. All arguments are passed by value into the called function.
152+
This includes pointers, through which a callee object could be modified.
153+
154+
=== Storage Classes
155+
156+
Modify Section 3.7, Storage Class, adding to the end of the list of storage classes: ::
157+
158+
[cols="1,4,4",options="header",width="100%"]
159+
|====
160+
2+| Storage Class| <<Capability,Enabling Capabilities>> |
161+
5605 | *CodeSectionINTEL* +
162+
This storage represents function pointers. Visible across all functions of
163+
all invocations of all work groups.
164+
| *FunctionPointersINTEL*
165+
|====
166+
167+
=== Decorations
168+
169+
Modify Section 3.20, Decorations, adding to the end of the list of decorations: ::
170+
171+
[cols="1,6,1,1,6",options="header",width = "100%"]
172+
|====
173+
2+^.^| Decoration 2+<.^| Extra Operands
174+
| <<Capability,Enabling Capabilities>> |
175+
5602 | *ReferencedIndirectlyINTEL* +
176+
This mark means that function might not have direct uses within the module,
177+
but it's address can be obtained and passed into an Entry Point for further
178+
usage via *OpFunctionPointerCallINTEL*. This function must not be optimized
179+
out based on call graph/reachability analysis 2+||
180+
*IndirectReferencesINTEL*|
181+
|====
182+
183+
=== Capabilities
184+
185+
Modify Section 3.31, Capabilities, adding to the end of the list of capabilities: ::
186+
187+
188+
[cols="1,10,8,8",options="header",width = "80%"]
189+
|====
190+
2+^.^| Capability | Implicitly Declares | Enabled by Extension
191+
192+
| 5603
193+
| *FunctionPointersINTEL*
194+
| *Addresses* | *SPV_INTEL_function_pointers*
195+
| 5604
196+
| *IndirectReferencesINTEL*
197+
| *Addresses* | *SPV_INTEL_function_pointers*
198+
199+
|====
200+
201+
202+
=== Instructions
203+
204+
Modify Section 3.32.6, Type-Declaration Instructions, change the third sentence in the description of *OpTypeFunction* instruction to say: ::
205+
206+
*OpTypeFunction* can be used as operand of *OpTypePointer* to declare function
207+
pointer type. *OpFunction* and *OpTypePointer* are only valid uses of
208+
*OpTypeFunction*.
209+
210+
Modify Section 3.32.9, Function Instructions, adding to the end of the list of instructions: ::
211+
212+
[cols="2*1,3*3",width="100%"]
213+
|=====
214+
4+|[[OpFunctionPointerINTEL]]*OpFunctionPointerINTEL* +
215+
+
216+
Obtains address of the specified function. +
217+
+
218+
Result value can be used immediately in *OpFunctionPointerCallINTEL* or stored
219+
somewhere for further usage in *OpFunctionPointerCallINTEL*. +
220+
+
221+
_Result Type_ must be an *OpTypePointer*. Its _Type_ operand must be the same
222+
*OpTypeFunction* which was used as _Function Type_ operand of the _Function_
223+
operand. Its _Storage Class_ operand must be *CodeSectionINTEL*
224+
| <<Capability,Capability>>: +
225+
*FunctionPointersINTEL*
226+
| 4 | 5600 | '<id>' 'Result Type' | '<id> Result ' | '<id>' 'Function'
227+
|=====
228+
229+
[cols="2*1,4*3",width="100%"]
230+
|=====
231+
5+|[[OpFunctionPointerCallINTEL]]*OpFunctionPointerCallINTEL* +
232+
+
233+
Call a function via function pointer. +
234+
+
235+
_Result Type_ is the type of the return value of the function. +
236+
+
237+
_Function Pointer_ is <<FunctionPointer, Function Pointer>>. +
238+
+
239+
_Argument N_ is the object to copy to parameter _N_. +
240+
+
241+
*Note:* _Result Type_ must match the _Return Type_ of the *OpTypeFunction* which
242+
was used as _Type_ operand of _Function Pointer_ argument and the calling
243+
argument types must match the formal parameter types.
244+
| <<Capability,Capability>>: +
245+
*FunctionPointersINTEL*
246+
| 4 + variable | 5601
247+
| '<id>' 'Result Type' | <<ResultId,'Result <id>' >> | '<id>' +
248+
'Function Pointer' |
249+
'<id>, <id>, ..., <id>' 'Argument 0', 'Argument 1', ..., 'Argument N'
250+
|=====
251+
252+
== Validation Rules
253+
254+
It is legal to use <<FunctionPointer, Function Pointer>> as 'Result Type' of
255+
*OpFunctionArgument*, *OpUndef* and *OpConstantNULL*.
256+
257+
It is legal to use <<FunctionPointer, Function Pointer>> as 'Return Type' of
258+
*OpTypeFunction*.
259+
260+
It is legal to use <<FunctionPointer, Function Pointer>> as 'Pointer'
261+
argument of *OpConvertPtrToU* and as 'Result Type' of *OpConvertUToPtr*.
262+
263+
It is illegal to use <<FunctionPointer, Function Pointer>> as 'Pointer'
264+
argument of *OpPtrCastToGeneric*.
265+
266+
It is illegal to use <<FunctionPointer, Function Pointer>> as 'Pointer' argument
267+
of *OpLoad* and *OpStore* instructions.
268+
269+
It is illegal to use <<FunctionPointer, Function Pointer>> as 'Pointer' and
270+
'Source' arguments of *OpCopyMemory*, *OpCopyMemorySized* instructions.
271+
272+
It is legal to compare <<FunctionPointer, Function Pointers>> between each other
273+
using *OpPtrEqual* or *OpPtrNotEqual*. However, it is illegal to use
274+
<<FunctionPointer, Function Pointer>> as any argument of *OpPtrDiff*
275+
instruction.
276+
277+
== Issues
278+
279+
. It is unclear which <<Storage_Class,Storage Class>> should function pointers
280+
point to? Do we need new one or *CrossWorkgroup* is enough? How to represent
281+
new storage class/address space in LLVM IR if we need such? How to represent
282+
new storage class/address space in source language?
283+
+
284+
--
285+
*RESOLVED*
286+
287+
Based on cl_intel_function_pointers specification, it is not guaranteed that
288+
`sizeof(void(*)(void) == sizeof(void *)` - to allow consumers use this fact, we
289+
cannot say that function pointer belongs to the same storage class as data
290+
pointers. That is why new storage class was invented.
291+
New storage class can be represented in LLVM IR as-is: any function pointer
292+
implicitly belongs to corresponding storage class in SPIR-V.
293+
Question about source language is out of scope of this spec.
294+
--
295+
296+
. Should we add new *ReferencedIndirectlyINTEL* declaration or we should modify
297+
reserve bit in *FunctionControl* mask? Do we need any special declaration/
298+
function control bit at all? Can we use existing *Linkage Type* functionality?
299+
+
300+
--
301+
*UNRESOLVED*
302+
--
303+
304+
. Do we need to support *OpPtrDiff* for function pointers? Looks like it cannot
305+
be used for ones out of the box and we don't have much use-cases for it.
306+
+
307+
--
308+
*UNRESOLVED*
309+
--
310+
311+
//. Issue.
312+
//+
313+
//--
314+
//*RESOLVED*: Resolution.
315+
//--
316+
317+
== Revision History
318+
319+
[cols="5,15,15,70"]
320+
[grid="rows"]
321+
[options="header"]
322+
|========================================
323+
|Rev|Date|Author|Changes
324+
|A|2019-02-05|Alexey Sachkov|*Initial revision*
325+
|B|2019-02-27|Alexey Sachkov|Updated description of
326+
*OpFunctionPointerCallINTEL*: added information about type-checking. Added
327+
*ReferencedIndirectly* decoration
328+
|C|2019-01-03|Alexey Sachkov|Added missed `INTEL` suffix
329+
|D|2019-06-03|Alexey Sachkov|Added *FunctionPointersINTEL* and
330+
*IndirectReferencesINTEL* capabilities
331+
|E|2019-06-04|Alexey Sachkov|Applied comments from Mariusz and Pawel: +
332+
- OpFunctionType -> OpTypeFunction +
333+
- Added definition of Function Pointer into Terms section +
334+
- New capabilities implicitly requires Addresses capability +
335+
- Small updates in descriptions of new instructions
336+
|F|2019-06-21|Alexey Sachkov|Added new storage class dedicated for function
337+
pointers. Updated validation rules. Misc updates.
338+
|G|2019-07-19|Ben Ashbaugh|Assigned SPIR-V enums, added preview extension disclaimer text.
339+
|========================================

0 commit comments

Comments
 (0)