ae2f_docs
Loading...
Searching...
No Matches
count_fn.h
Go to the documentation of this file.
1/** @file count_fn.h */
2
3#include "util/entp.h"
4#include <ae2f/Keys.h>
5
6#include <clang-c/CXString.h>
7#include <clang-c/Index.h>
8
9#include <stdio.h>
10#include <assert.h>
11
12#include <util/ctx.h>
13#include <util/emitx.h>
14#include <util/is_kernel.h>
15#include <util/fn.h>
16
17#include <attr/storage_class.h>
18
19#include <ae2f/c90/StdBool.h>
20#include <spirv/unified1/spirv.h>
21
22static enum CXChildVisitResult emit_count_fn_wrdgroup_attr(CXCursor h_cur, CXCursor h_parent, CXClientData wr_data) {
23 CXString ATTR_KIND;
24 const char* NIDDLE;
25
26 ATTR_KIND = clang_getCursorSpelling(h_cur);
27 if((NIDDLE = strstr(ATTR_KIND.data, "reqd_work_group_size"))) {
28 sscanf(NIDDLE, "reqd_work_group_size ( %u , %u , %u )"
29 , ((unsigned* ae2f_restrict)wr_data)
30 , ((unsigned* ae2f_restrict)wr_data) + 1
31 , ((unsigned* ae2f_restrict)wr_data) + 2
32 );
33
34 clang_disposeString(ATTR_KIND);
35 return CXChildVisit_Break;
36 } else if ((NIDDLE = strstr(ATTR_KIND.data, "aclspv_wrkgroup_size"))) {
37 sscanf(NIDDLE, "aclspv_wrkgroup_size ( %u , %u , %u )"
38 , ((unsigned* ae2f_restrict)wr_data)
39 , ((unsigned* ae2f_restrict)wr_data) + 1
40 , ((unsigned* ae2f_restrict)wr_data) + 2
41 );
42
43 clang_disposeString(ATTR_KIND);
44 return CXChildVisit_Break;
45 }
46
47 clang_disposeString(ATTR_KIND);
48 return CXChildVisit_Recurse;
49 (void)h_parent;
50}
51
52static enum CXChildVisitResult emit_count_fn_execmodel_attr(CXCursor h_cur, CXCursor h_parent, CXClientData wr_data) {
53 CXString ATTR_KIND;
54 const char* NIDDLE;
55
56 ATTR_KIND = clang_getCursorSpelling(h_cur);
57 if((NIDDLE = strstr(ATTR_KIND.data, "aclspv_execmodel"))) {
58 sscanf(NIDDLE, "aclspv_execmodel ( %u )"
59 , ((unsigned* ae2f_restrict)wr_data)
60 );
61
62 clang_disposeString(ATTR_KIND);
63 return CXChildVisit_Break;
64 }
65
66 clang_disposeString(ATTR_KIND);
67 return CXChildVisit_Recurse;
68 (void)h_parent;
69}
70
71static enum CXChildVisitResult emit_iter_entry_point(CXCursor h_cur, CXCursor h_parent, CXClientData CTX) {
72#define CTX ((x_aclspv_ctx* ae2f_restrict)CTX)
73 unless(h_cur.kind == CXCursor_CompoundStmt && h_parent.kind == CXCursor_FunctionDecl)
74 return CXChildVisit_Recurse;
75
76 if(util_is_kernel(h_parent)) {
77 const CXString NAME = clang_getCursorSpelling(h_parent);
78 unsigned XYZ[3] = { 1, 1, 1 };
79 unsigned EXEC_MODEL = SpvExecutionModelGLCompute;
80
81 aclspv_wrdcount_t POS = CTX->m_count.m_entp;
82 aclspv_wrd_t IOCOUNT = 0;
83 CTX->m_err = ACLSPV_COMPILE_ALLOC_FAILED;
84
85 clang_visitChildren(h_parent, emit_count_fn_execmodel_attr, &EXEC_MODEL);
86
87 if(EXEC_MODEL == SpvExecutionModelGLCompute || EXEC_MODEL == SpvExecutionModelKernel)
88 clang_visitChildren(h_parent, emit_count_fn_wrdgroup_attr, XYZ);
89
90 {
91 int ARGC = clang_Cursor_getNumArguments(h_parent);
92 int ARGI = ARGC;
93
94 while(ARGI --> 0) {
95 CXCursor ARG = clang_Cursor_getArgument(h_parent, (unsigned)ARGI);
96 aclspv_wrd_t STORAGE = SpvStorageClassMax;
97 clang_visitChildren(ARG, attr_storage_class, &STORAGE);
98
99 if(STORAGE == SpvStorageClassInput || STORAGE == SpvStorageClassOutput) {
100 ++IOCOUNT;
101 }
102 }
103 }
104
105
106#define THIS_ENTRY_POINT ((util_entp_t* ae2f_restrict)CTX->m_fnlist.m_entp.m_p)[CTX->m_tmp.m_w0]
107 THIS_ENTRY_POINT.m_fn = h_parent;
108 THIS_ENTRY_POINT.m_id = CTX->m_tmp.m_w3 + CTX->m_tmp.m_w0;
109
110 if(IOCOUNT) {
111 THIS_ENTRY_POINT.m_io.m_anchour = CTX->m_id;
112 THIS_ENTRY_POINT.m_io.m_num = IOCOUNT;
113 CTX->m_id += IOCOUNT;
114 }
115
116 /** OpEntryPoint */
117 unless((CTX->m_count.m_entp = emit_opcode(
118 &CTX->m_section.m_entp
119 , CTX->m_count.m_entp
120 , SpvOpEntryPoint, 0)))
121 goto LBL_ABRT;
122 unless((CTX->m_count.m_entp = util_emit_wrd(
123 &CTX->m_section.m_entp
124 , CTX->m_count.m_entp
125 , EXEC_MODEL)))
126 goto LBL_ABRT;
127 unless((CTX->m_count.m_entp = util_emit_wrd(
128 &CTX->m_section.m_entp
129 , CTX->m_count.m_entp
130 , THIS_ENTRY_POINT.m_id)))
131 goto LBL_ABRT;
132 unless((CTX->m_count.m_entp = util_emit_str(
133 &CTX->m_section.m_entp
134 , CTX->m_count.m_entp
135 , NAME.data)))
136 goto LBL_ABRT;
137
138 if(IOCOUNT) {
139 aclspv_wrd_t IO_IDX = 0;
140 while(IO_IDX < IOCOUNT) {
141 unless((CTX->m_count.m_entp = util_emit_wrd(
142 &CTX->m_section.m_entp
143 , CTX->m_count.m_entp
144 , THIS_ENTRY_POINT.m_io.m_anchour + IO_IDX)))
145 goto LBL_ABRT;
146 ++IO_IDX;
147 }
148 }
149
151 get_wrd_of_vec(&CTX->m_section.m_entp)[POS]
152 , CTX->m_count.m_entp - POS - 1
153 );
154
155 /** OpExecMode */
156 if(EXEC_MODEL == SpvExecutionModelGLCompute || EXEC_MODEL == SpvExecutionModelKernel)
157 ae2f_expected_but_else(CTX->m_count.m_execmode = util_emitx_6(
158 &CTX->m_section.m_execmode
159 , CTX->m_count.m_execmode
160 , SpvOpExecutionMode
161 , THIS_ENTRY_POINT.m_id
162 , SpvExecutionModeLocalSize
163 , XYZ[0], XYZ[1], XYZ[2]
164 )) goto LBL_ABRT;
165
166#if !defined(NDEBUG) || !NDEBUG
167 POS = CTX->m_count.m_name;
168 unless((CTX->m_count.m_name = emit_opcode(&CTX->m_section.m_name, CTX->m_count.m_name, SpvOpName, 0))) goto LBL_ABRT;
169 unless((CTX->m_count.m_name = util_emit_wrd(&CTX->m_section.m_name, CTX->m_count.m_name
170 , THIS_ENTRY_POINT.m_id))) goto LBL_ABRT;
171 unless((CTX->m_count.m_name = util_emit_str(&CTX->m_section.m_name, CTX->m_count.m_name, NAME.data))) goto LBL_ABRT;
172 set_oprnd_count_for_opcode(get_wrd_of_vec(&CTX->m_section.m_name)[POS], CTX->m_count.m_name - POS - 1);
173#endif
174 CTX->m_err = ACLSPV_COMPILE_OK;
175 ++CTX->m_tmp.m_w0;
176
177 clang_disposeString(NAME);
178 return CXChildVisit_Continue;
180
181LBL_ABRT:
182 clang_disposeString(NAME);
183 return CXChildVisit_Break;
184 } else {
185#define THIS_FUNCTION ((util_fn_t* ae2f_restrict)CTX->m_fnlist.m_fn.m_p)[CTX->m_tmp.m_w1]
186 THIS_FUNCTION.m_fn = h_parent;
187 THIS_FUNCTION.m_id = CTX->m_id++;
188 }
189#undef CTX
190#undef THIS_ENTRY_POINT
191
192 return CXChildVisit_Continue;
193}
194
195static enum CXChildVisitResult emit_count_fn(CXCursor h_cur, CXCursor h_parent, CXClientData h_ctx) {
196#define CTX ((x_aclspv_ctx* ae2f_restrict)h_ctx)
197 assert(CTX);
198
199 unless(h_cur.kind == CXCursor_CompoundStmt && h_parent.kind == CXCursor_FunctionDecl)
200 return CXChildVisit_Recurse;
201
202 if(util_is_kernel(h_parent)) {
203 ++CTX->m_fnlist.m_num_entp;
204 } else {
205 ++CTX->m_fnlist.m_num_fn;
206 }
207
208 return CXChildVisit_Continue;
209#undef CTX
210}
#define ae2f_IS_SHARED
Definition Call.auto.h:12
#define ae2f_OFF
Definition Call.auto.h:3
#define ae2f_WhenCXX(a)
Appears when the current language is C.
Definition Cxx.h:44
#define ae2f_WhenC(a)
Appears when the current language is C++.
Definition Cxx.h:38
#define unless(a)
Invokes when condition is false.
Definition Keys.h:34
#define ae2f_extern
Suggests the existence of external variable or function, in naming of C. [non-mangling].
Definition Keys.h:25
#define ae2f_NIL
Definition Nil.h:13
#define ACLSPV_ABI_DECL
Declaration as ABI.
Definition abi.h:23
#define STATE_VAL
#define FNINFO
#define cpysz
#define cpypad
#define ae2f_assume(a)
tells the compiler that value if a is false, below this keyword is not expected to be reached.
Definition cc.h:228
#define ae2f_unexpected_but_if(a)
Definition cc.h:192
#define ae2f_ccpure
Keyword as [[pure]] on C23.
Definition cc.h:52
#define ae2f_expected_but_else(a)
Definition cc.h:201
#define ae2f_expected_if(a)
Definition cc.h:195
#define ae2f_ccconst
Keyword as [[const]] on C23..
Definition cc.h:66
#define ae2f_noexcept
marker that this function does not throw something.
Definition cc.h:133
#define ae2f_restrict
Keyword as restrict on C99.
Definition cc.h:81
#define ae2f_expected_not(a)
expectes a as false.
Definition cc.h:185
#define ae2f_unreachable()
tells the compiler that below this keyword is not expected to be reached.
Definition cc.h:213
#define ae2f_inline
inline
Definition cc.h:149
#define ae2f_expected(a)
expectes a as true.
Definition cc.h:184
#define wrd_caps
Definition conf.h:11
#define wrd_caps_count
Definition conf.h:12
#define wrd_ext
Definition conf.h:14
#define wrd_ext_count
Definition conf.h:15
#define THIS_FUNCTION
#define CTX
#define THIS_ENTRY_POINT
#define EMIT_POS
#define util_emitx_type_pointer(h_wrds, c_wrdcount, c_retid, c_storage_class, c_elm_type_id)
Definition emitx.h:134
#define ret_count
#define get_buf_from_scale(h_alloc, c_scale)
Definition scale.h:34
#define aclspv_opcode_t
integer as operation code
Definition spvty.h:27
aclspv_wrd_t aclspv_wrdcount_t
the integer type represents the number of word.
Definition spvty.h:61
#define ACLSPV_MASK_OPCODE
mask for opcode
Definition spvty.h:37
#define aclspv_wrd_t
integer as word
Definition spvty.h:16
#define ACLSPV_MASK_NOPRNDS
mask for number of operands
Definition spvty.h:42
x_aclspv_vec m_scale_vars
Definition ctx.h:62
aclspv_wrdcount_t m_num_type_uniques
Definition ctx.h:44
x_aclspv_vec m_cursors
cache for cursors for parsing one function for its use see util/cursor.h
Definition ctx.h:77
x_aclspv_vec m_constant_cache
Definition ctx.h:65
aclspv_id_t m_id
id
Definition ctx.h:50
x_aclspv_vec m_ret
word count for m_ret
Definition ctx.h:56
aclspv_wrd_t m_is_logical
when on, ignores m_is_buffer_64.
Definition ctx.h:23
aclspv_wrdcount_t m_num_cursor
number of m_cursors. for its use see util/cursor.h
Definition ctx.h:41
x_aclspv_vec m_type_uniques
cache for complex types which needs to be stored somewhere for its use see util/type_unique....
Definition ctx.h:86
aclspv_wrd_t m_nprm
Definition entp.h:13
util_bind_unified m_unified
Definition bind.h:20
#define mk_noprnds(c_num_opprm)
Definition wrdemit.h:66
#define emit_opcode(h_wrds, c_wrdcount, c_opcode, c_num_opprm_opt)
try emit opcode with num_opprm
Definition wrdemit.h:75
#define sz_to_count(c_sz)
byte size to word count
Definition wrdemit.h:24
#define get_wrd_of_vec(vec)
get word buffer from vector
Definition wrdemit.h:38
aclspv_wrdcount_t spvsz_t
Definition wrdemit.h:18
#define count_to_sz(c_count)
word count to byte size
Definition wrdemit.h:32
#define set_oprnd_count_for_opcode(cr_wrd, c_num_opprm)
Definition wrdemit.h:78
#define opcode_to_wrd(c_opcode, c_num_opprm)
Definition wrdemit.h:69