1 # Copyright (C) 2014-2015 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 #!deps/python32/python.exe
29 header
= r
"""/****************************************************************************
30 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
32 * Permission is hereby granted, free of charge, to any person obtaining a
33 * copy of this software and associated documentation files (the "Software"),
34 * to deal in the Software without restriction, including without limitation
35 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
36 * and/or sell copies of the Software, and to permit persons to whom the
37 * Software is furnished to do so, subject to the following conditions:
39 * The above copyright notice and this permission notice (including the next
40 * paragraph) shall be included in all copies or substantial portions of the
43 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
46 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
48 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
53 * @brief auto-generated file
57 ******************************************************************************/
63 def gen_file_header(filename
):
65 headerStr
= header
% filename
66 return headerStr
.splitlines()
70 'SHUFFLE_VECTOR': 'VSHUFFLE',
71 'INSERT_ELEMENT': 'VINSERT',
72 'EXTRACT_ELEMENT': 'VEXTRACT',
75 'MEM_MOVE': 'MEMMOVE',
78 'BIT_CAST': 'BITCAST',
87 ["VGATHERPS", "x86_avx2_gather_d_ps_256", ["src", "pBase", "indices", "mask", "scale"]],
88 ["VGATHERDD", "x86_avx2_gather_d_d_256", ["src", "pBase", "indices", "mask", "scale"]],
89 ["VSQRTPS", "x86_avx_sqrt_ps_256", ["a"]],
90 ["VRSQRTPS", "x86_avx_rsqrt_ps_256", ["a"]],
91 ["VRCPPS", "x86_avx_rcp_ps_256", ["a"]],
92 ["VMINPS", "x86_avx_min_ps_256", ["a", "b"]],
93 ["VMAXPS", "x86_avx_max_ps_256", ["a", "b"]],
94 ["VPMINSD", "x86_avx2_pmins_d", ["a", "b"]],
95 ["VPMAXSD", "x86_avx2_pmaxs_d", ["a", "b"]],
96 ["VROUND", "x86_avx_round_ps_256", ["a", "rounding"]],
97 ["VCMPPS", "x86_avx_cmp_ps_256", ["a", "b", "cmpop"]],
98 ["VBLENDVPS", "x86_avx_blendv_ps_256", ["a", "b", "mask"]],
99 ["BEXTR_32", "x86_bmi_bextr_32", ["src", "control"]],
100 ["VMASKLOADD", "x86_avx2_maskload_d_256", ["src", "mask"]],
101 ["VMASKMOVPS", "x86_avx_maskload_ps_256", ["src", "mask"]],
102 ["VPSHUFB", "x86_avx2_pshuf_b", ["a", "b"]],
103 ["VPMOVSXBD", "x86_avx2_pmovsxbd", ["a"]], # sign extend packed 8bit components
104 ["VPMOVSXWD", "x86_avx2_pmovsxwd", ["a"]], # sign extend packed 16bit components
105 ["VPERMD", "x86_avx2_permd", ["idx", "a"]],
106 ["VPERMPS", "x86_avx2_permps", ["idx", "a"]],
107 ["VCVTPH2PS", "x86_vcvtph2ps_256", ["a"]],
108 ["VCVTPS2PH", "x86_vcvtps2ph_256", ["a", "round"]],
109 ["VHSUBPS", "x86_avx_hsub_ps_256", ["a", "b"]],
110 ["VPTESTC", "x86_avx_ptestc_256", ["a", "b"]],
111 ["VPTESTZ", "x86_avx_ptestz_256", ["a", "b"]],
112 ["VFMADDPS", "x86_fma_vfmadd_ps_256", ["a", "b", "c"]],
113 ["VCVTTPS2DQ", "x86_avx_cvtt_ps2dq_256", ["a"]],
114 ["VMOVMSKPS", "x86_avx_movmsk_ps_256", ["a"]],
115 ["INTERRUPT", "x86_int", ["a"]],
118 def convert_uppercamel(name
):
119 s1
= re
.sub('(.)([A-Z][a-z]+)', r
'\1_\2', name
)
120 return re
.sub('([a-z0-9])([A-Z])', r
'\1_\2', s1
).upper()
123 Given an input file (e.g. IRBuilder.h) generates function dictionary.
125 def parse_ir_builder(input_file
):
129 lines
= input_file
.readlines()
132 while idx
< len(lines
) - 1:
133 line
= lines
[idx
].rstrip()
136 #match = re.search(r"\*Create", line)
137 match
= re
.search(r
"[\*\s]Create(\w*)\(", line
)
138 if match
is not None:
139 #print("Line: %s" % match.group(1))
141 if re
.search(r
"^\s*Create", line
) is not None:
142 func_sig
= lines
[idx
-2].rstrip() + line
147 while not end_of_args
:
148 end_paren
= re
.search(r
"\)", line
)
149 if end_paren
is not None:
152 line
= lines
[idx
].rstrip()
156 delfunc
= re
.search(r
"LLVM_DELETED_FUNCTION|= delete;", func_sig
)
159 func
= re
.search(r
"(.*?)\*[\n\s]*(Create\w*)\((.*?)\)", func_sig
)
162 return_type
= func
.group(1).lstrip() + '*'
163 func_name
= func
.group(2)
164 arguments
= func
.group(3)
167 func_args_nodefs
= ''
169 num_args
= arguments
.count(',')
173 args
= arguments
.split(',')
179 func_args_nodefs
+= ', '
181 func_args_nodefs
+= arg
.split(' =')[0]
183 split_args
= arg
.split('=')
184 arg_name
= split_args
[0].rsplit(None, 1)[-1]
186 #print("Before ArgName = %s" % arg_name)
188 reg_arg
= re
.search(r
"[\&\*]*(\w*)", arg_name
)
190 #print("Arg Name = %s" % reg_arg.group(1))
191 arg_names
+= [reg_arg
.group(1)]
197 # The following functions need to be ignored.
198 if func_name
== 'CreateInsertNUWNSWBinOp':
201 if func_name
== 'CreateMaskedIntrinsic':
204 # Convert CamelCase to CAMEL_CASE
205 func_mod
= re
.search(r
"Create(\w*)", func_name
)
207 func_mod
= func_mod
.group(1)
208 func_mod
= convert_uppercamel(func_mod
)
209 if func_mod
[0:2] == 'F_' or func_mod
[0:2] == 'I_':
210 func_mod
= func_mod
[0] + func_mod
[2:]
212 # Substitute alias based on CAMEL_CASE name.
213 func_alias
= inst_aliases
.get(func_mod
)
215 func_alias
= func_mod
217 if func_name
== 'CreateCall' or func_name
== 'CreateGEP':
218 arglist
= re
.search(r
'ArrayRef', func_args
)
220 func_alias
= func_alias
+ 'A'
226 "return": return_type
,
228 "args_nodefs": func_args_nodefs
,
229 "arg_names": arg_names
235 Auto-generates macros for LLVM IR
237 def generate_gen_h(functions
, output_file
):
238 output_lines
= gen_file_header(os
.path
.basename(output_file
.name
))
243 '//////////////////////////////////////////////////////////////////////////',
244 '/// Auto-generated Builder IR declarations',
245 '//////////////////////////////////////////////////////////////////////////',
248 for func
in functions
:
253 '%s%s(%s);' % (func
['return'], name
, func
['args'])
256 output_file
.write('\n'.join(output_lines
) + '\n')
259 Auto-generates macros for LLVM IR
261 def generate_gen_cpp(functions
, output_file
):
262 output_lines
= gen_file_header(os
.path
.basename(output_file
.name
))
265 '#include \"builder.h\"',
269 for func
in functions
:
274 args
= func
['arg_names']
284 '//////////////////////////////////////////////////////////////////////////',
285 '%sBuilder::%s(%s)' % (func
['return'], name
, func
['args_nodefs']),
287 ' return IRB()->%s(%s);' % (func
['name'], func_args
),
292 output_file
.write('\n'.join(output_lines
) + '\n')
295 Auto-generates macros for LLVM IR
297 def generate_x86_h(output_file
):
298 output_lines
= gen_file_header(os
.path
.basename(output_file
.name
))
303 '//////////////////////////////////////////////////////////////////////////',
304 '/// Auto-generated x86 intrinsics',
305 '//////////////////////////////////////////////////////////////////////////',
308 for inst
in intrinsics
:
309 #print("Inst: %s, x86: %s numArgs: %d" % (inst[0], inst[1], len(inst[2])))
316 args
+= ("Value* %s" % arg
)
320 'Value *%s(%s);' % (inst
[0], args
)
323 output_file
.write('\n'.join(output_lines
) + '\n')
326 Auto-generates macros for LLVM IR
328 def generate_x86_cpp(output_file
):
329 output_lines
= gen_file_header(os
.path
.basename(output_file
.name
))
332 '#include \"builder.h\"',
336 for inst
in intrinsics
:
337 #print("Inst: %s, x86: %s numArgs: %d" % (inst[0], inst[1], len(inst[2])))
346 args
+= ("Value* %s" % arg
)
351 '//////////////////////////////////////////////////////////////////////////',
352 'Value *Builder::%s(%s)' % (inst
[0], args
),
354 ' Function *func = Intrinsic::getDeclaration(JM()->mpCurrentModule, Intrinsic::%s);' % inst
[1],
355 ' return CALL(func, std::initializer_list<Value*>{%s});' % pass_args
,
360 output_file
.write('\n'.join(output_lines
) + '\n')
363 Function which is invoked when this script is started from a command line.
364 Will present and consume a set of arguments which will tell this script how
370 parser
= argparse
.ArgumentParser()
371 parser
.add_argument("--input", "-i", type=argparse
.FileType('r'), help="Path to IRBuilder.h", required
=False)
372 parser
.add_argument("--output", "-o", type=argparse
.FileType('w'), help="Path to output file", required
=True)
373 parser
.add_argument("--gen_h", "-gen_h", help="Generate builder_gen.h", action
="store_true", default
=False)
374 parser
.add_argument("--gen_cpp", "-gen_cpp", help="Generate builder_gen.cpp", action
="store_true", default
=False)
375 parser
.add_argument("--gen_x86_h", "-gen_x86_h", help="Generate x86 intrinsics. No input is needed.", action
="store_true", default
=False)
376 parser
.add_argument("--gen_x86_cpp", "-gen_x86_cpp", help="Generate x86 intrinsics. No input is needed.", action
="store_true", default
=False)
377 args
= parser
.parse_args()
380 functions
= parse_ir_builder(args
.input)
383 generate_gen_h(functions
, args
.output
)
386 generate_gen_cpp(functions
, args
.output
)
389 generate_x86_h(args
.output
)
392 generate_x86_cpp(args
.output
)
395 print("Need to specify --input for --gen_h!")
398 print("Need to specify --input for --gen_cpp!")
400 if __name__
== '__main__':