1
# Copyright (C) 2014-2017 Intel Corporation. All Rights Reserved.
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the "Software"),
5 # to deal in the Software without restriction, including without limitation
6 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 # and/or sell copies of the Software, and to permit persons to whom the
8 # Software is furnished to do so, subject to the following conditions:
10 # The above copyright notice and this permission notice (including the next
11 # paragraph) shall be included in all copies or substantial portions of the
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 from __future__
import print_function
27 from mako
.template
import Template
28 from mako
.exceptions
import RichTraceback
30 def write_template_to_string(template_filename
, **kwargs
):
32 template
= Template(filename
=os
.path
.abspath(template_filename
))
33 # Split + Join fixes line-endings for whatever platform you are using
34 return '\n'.join(template
.render(**kwargs
).splitlines())
36 traceback
= RichTraceback()
37 for (filename
, lineno
, function
, line
) in traceback
.traceback
:
38 print('File %s, line %s, in %s' % (filename
, lineno
, function
))
40 print('%s: %s' % (str(traceback
.error
.__class
__.__name
__), traceback
.error
))
42 def write_template_to_file(template_filename
, output_filename
, **kwargs
):
43 output_dirname
= os
.path
.dirname(output_filename
)
44 if not os
.path
.exists(output_dirname
):
45 os
.makedirs(output_dirname
)
46 with
open(output_filename
, 'w') as outfile
:
47 print(write_template_to_string(template_filename
, **kwargs
), file=outfile
)
51 def gen_llvm_type(type, name
, is_pointer
, is_pointer_pointer
, is_array
, is_array_array
, array_count
, array_count1
, is_llvm_struct
, is_llvm_enum
, is_llvm_pfn
, output_file
):
56 if is_pointer
or is_pointer_pointer
:
57 llvm_type
= 'Type::getInt32Ty(ctx)'
59 llvm_type
= 'ArrayType::get(Type::getInt8Ty(ctx), sizeof(%s))' % type
61 llvm_type
= 'Type::getInt32Ty(ctx)'
63 llvm_type
= 'PointerType::get(Type::getInt8Ty(ctx), 0)'
65 if type == 'BYTE' or type == 'char' or type == 'uint8_t' or type == 'int8_t' or type == 'bool':
66 llvm_type
= 'Type::getInt8Ty(ctx)'
67 elif type == 'UINT64' or type == 'INT64' or type == 'uint64_t' or type == 'int64_t':
68 llvm_type
= 'Type::getInt64Ty(ctx)'
69 elif type == 'UINT16' or type == 'int16_t' or type == 'uint16_t':
70 llvm_type
= 'Type::getInt16Ty(ctx)'
71 elif type == 'UINT' or type == 'INT' or type == 'int' or type == 'BOOL' or type == 'uint32_t' or type == 'int32_t':
72 llvm_type
= 'Type::getInt32Ty(ctx)'
73 elif type == 'float' or type == 'FLOAT':
74 llvm_type
= 'Type::getFloatTy(ctx)'
75 elif type == 'double' or type == 'DOUBLE':
76 llvm_type
= 'Type::getDoubleTy(ctx)'
77 elif type == 'void' or type == 'VOID':
78 llvm_type
= 'Type::getInt32Ty(ctx)'
79 elif type == 'HANDLE':
80 llvm_type
= 'PointerType::get(Type::getInt32Ty(ctx), 0)'
81 elif type == 'simdscalar':
82 llvm_type
= 'VectorType::get(Type::getFloatTy(ctx), pJitMgr->mVWidth)'
83 elif type == 'simdscalari':
84 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), pJitMgr->mVWidth)'
85 elif type == 'SIMD8::vector_t':
86 llvm_type
= 'VectorType::get(Type::getFloatTy(ctx), 8)'
87 elif type == 'SIMD8::vectori_t':
88 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), 8)'
89 elif type == 'SIMD16::vector_t':
90 llvm_type
= 'VectorType::get(Type::getFloatTy(ctx), 16)'
91 elif type == 'SIMD16::vectori_t':
92 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), 16)'
93 elif type == 'simdvector':
94 llvm_type
= 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), pJitMgr->mVWidth), 4)'
95 elif type == 'SIMD8::attrib_t':
96 llvm_type
= 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 8), 4)'
97 elif type == 'SIMD16::attrib_t':
98 llvm_type
= 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 16), 4)'
100 llvm_type
= 'Gen_%s(pJitMgr)' % type
103 llvm_type
= 'PointerType::get(%s, 0)' % llvm_type
105 if is_pointer_pointer
:
106 llvm_type
= 'PointerType::get(%s, 0)' % llvm_type
109 llvm_type
= 'ArrayType::get(ArrayType::get(%s, %s), %s)' % (llvm_type
, array_count1
, array_count
)
111 llvm_type
= 'ArrayType::get(%s, %s)' % (llvm_type
, array_count
)
120 def gen_llvm_types(input_file
, output_file
):
122 lines
= input_file
.readlines()
126 for idx
in range(len(lines
)):
127 line
= lines
[idx
].rstrip()
129 if 'gen_llvm_types FINI' in line
:
132 match
= re
.match(r
'(\s*)struct(\s*)(\w+)', line
)
136 # Detect start of structure
137 is_fwd_decl
= re
.search(r
';', line
)
141 # Extract the command name
142 struct_name
= match
.group(3).strip()
145 'name' : struct_name
,
149 end_of_struct
= False
151 while not end_of_struct
and idx
< len(lines
)-1:
153 line
= lines
[idx
].rstrip()
155 is_llvm_typedef
= re
.search(r
'@llvm_typedef', line
)
156 if is_llvm_typedef
is not None:
157 is_llvm_typedef
= True
159 is_llvm_typedef
= False
161 ###########################################
162 # Is field a llvm struct? Tells script to treat type as array of bytes that is size of structure.
163 is_llvm_struct
= re
.search(r
'@llvm_struct', line
)
165 if is_llvm_struct
is not None:
166 is_llvm_struct
= True
168 is_llvm_struct
= False
170 ###########################################
171 # Is field a llvm enum? Tells script to treat type as an enum and replaced with uint32 type.
172 is_llvm_enum
= re
.search(r
'@llvm_enum', line
)
174 if is_llvm_enum
is not None:
179 ###########################################
180 # Is field a llvm function pointer? Tells script to treat type as an enum and replaced with uint32 type.
181 is_llvm_pfn
= re
.search(r
'@llvm_pfn', line
)
183 if is_llvm_pfn
is not None:
188 ###########################################
190 is_const
= re
.search(r
'\s+const\s+', line
)
192 if is_const
is not None:
197 ###########################################
198 # Is field a pointer?
199 is_pointer_pointer
= re
.search('\*\*', line
)
201 if is_pointer_pointer
is not None:
202 is_pointer_pointer
= True
204 is_pointer_pointer
= False
206 ###########################################
207 # Is field a pointer?
208 is_pointer
= re
.search('\*', line
)
210 if is_pointer
is not None:
215 ###########################################
216 # Is field an array of arrays?
217 # TODO: Can add this to a list.
218 is_array_array
= re
.search('\[(\w*)\]\[(\w*)\]', line
)
222 if is_array_array
is not None:
223 array_count
= is_array_array
.group(1)
224 array_count1
= is_array_array
.group(2)
225 is_array_array
= True
227 is_array_array
= False
229 ###########################################
231 is_array
= re
.search('\[(\w*)\]', line
)
233 if is_array
is not None:
234 array_count
= is_array
.group(1)
239 is_scoped
= re
.search('::', line
)
241 if is_scoped
is not None:
248 if is_const
and is_pointer
:
251 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+::)(\w+)(\s*\**\s*)(\w+)', line
)
253 type = '%s%s' % (field_match
.group(4), field_match
.group(5))
254 name
= field_match
.group(7)
256 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*\**\s*)(\w+)', line
)
258 type = field_match
.group(4)
259 name
= field_match
.group(6)
262 field_match
= re
.match(r
'(\s*)(\s+)(\w+\<*\w*\>*)(\s*\**\s*)(\w+)', line
)
265 type = field_match
.group(3)
266 name
= field_match
.group(5)
268 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*)(\w+)', line
)
271 type = field_match
.group(4)
272 name
= field_match
.group(6)
275 field_match
= re
.match(r
'\s*(\w+\<*\w*\>*)\s*::\s*(\w+\<*\w*\>*)\s+(\w+)', line
)
278 type = field_match
.group(1) + '::' + field_match
.group(2)
279 name
= field_match
.group(3)
281 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)', line
)
284 type = field_match
.group(2)
285 name
= field_match
.group(4)
287 if is_llvm_typedef
is False:
289 type_entry
['members'].append(
291 type, name
, is_pointer
, is_pointer_pointer
, is_array
, is_array_array
,
292 array_count
, array_count1
, is_llvm_struct
, is_llvm_enum
, is_llvm_pfn
, output_file
))
294 # Detect end of structure
295 end_of_struct
= re
.match(r
'(\s*)};', line
)
298 types
.append(type_entry
)
300 cur_dir
= os
.path
.dirname(os
.path
.abspath(__file__
))
301 template
= os
.path
.join(cur_dir
, 'templates', 'gen_llvm.hpp')
303 write_template_to_file(
307 filename
=os
.path
.basename(output_file
),
311 Function which is invoked when this script is started from a command line.
312 Will present and consume a set of arguments which will tell this script how
318 parser
= argparse
.ArgumentParser()
319 parser
.add_argument('--input', '-i', type=argparse
.FileType('r'),
320 help='Path to input file containing structs', required
=True)
321 parser
.add_argument('--output', '-o', action
='store',
322 help='Path to output file', required
=True)
323 args
= parser
.parse_args()
325 gen_llvm_types(args
.input, args
.output
)
327 if __name__
== '__main__':