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
24 from gen_common
import MakoTemplateWriter
, ArgumentParser
25 from argparse
import FileType
28 'SHUFFLE_VECTOR': 'VSHUFFLE',
29 'INSERT_ELEMENT': 'VINSERT',
30 'EXTRACT_ELEMENT': 'VEXTRACT',
33 'MEM_MOVE': 'MEMMOVE',
36 'BIT_CAST': 'BITCAST',
45 ['VGATHERPD', 'x86_avx2_gather_d_pd_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
46 ['VGATHERPS', 'x86_avx2_gather_d_ps_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
47 ['VGATHERDD', 'x86_avx2_gather_d_d_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
48 ['VSQRTPS', 'x86_avx_sqrt_ps_256', ['a']],
49 ['VRSQRTPS', 'x86_avx_rsqrt_ps_256', ['a']],
50 ['VRCPPS', 'x86_avx_rcp_ps_256', ['a']],
51 ['VMINPS', 'x86_avx_min_ps_256', ['a', 'b']],
52 ['VMAXPS', 'x86_avx_max_ps_256', ['a', 'b']],
53 ['VROUND', 'x86_avx_round_ps_256', ['a', 'rounding']],
54 ['VCMPPS', 'x86_avx_cmp_ps_256', ['a', 'b', 'cmpop']],
55 ['VBLENDVPS', 'x86_avx_blendv_ps_256', ['a', 'b', 'mask']],
56 ['BEXTR_32', 'x86_bmi_bextr_32', ['src', 'control']],
57 ['VMASKLOADD', 'x86_avx2_maskload_d_256', ['src', 'mask']],
58 ['VMASKMOVPS', 'x86_avx_maskload_ps_256', ['src', 'mask']],
59 ['VMASKSTOREPS', 'x86_avx_maskstore_ps_256', ['src', 'mask', 'val']],
60 ['VPSHUFB', 'x86_avx2_pshuf_b', ['a', 'b']],
61 ['VPERMD', 'x86_avx2_permd', ['a', 'idx']],
62 ['VPERMPS', 'x86_avx2_permps', ['idx', 'a']],
63 ['VCVTPD2PS', 'x86_avx_cvt_pd2_ps_256', ['a']],
64 ['VCVTPH2PS', 'x86_vcvtph2ps_256', ['a']],
65 ['VCVTPS2PH', 'x86_vcvtps2ph_256', ['a', 'round']],
66 ['VHSUBPS', 'x86_avx_hsub_ps_256', ['a', 'b']],
67 ['VPTESTC', 'x86_avx_ptestc_256', ['a', 'b']],
68 ['VPTESTZ', 'x86_avx_ptestz_256', ['a', 'b']],
69 ['VFMADDPS', 'x86_fma_vfmadd_ps_256', ['a', 'b', 'c']],
70 ['VMOVMSKPS', 'x86_avx_movmsk_ps_256', ['a']],
71 ['INTERRUPT', 'x86_int', ['a']],
74 this_dir
= os
.path
.dirname(os
.path
.abspath(__file__
))
75 template
= os
.path
.join(this_dir
, 'templates', 'gen_builder.hpp')
77 def convert_uppercamel(name
):
78 s1
= re
.sub('(.)([A-Z][a-z]+)', r
'\1_\2', name
)
79 return re
.sub('([a-z0-9])([A-Z])', r
'\1_\2', s1
).upper()
82 Given an input file (e.g. IRBuilder.h) generates function dictionary.
84 def parse_ir_builder(input_file
):
88 lines
= input_file
.readlines()
91 while idx
< len(lines
) - 1:
92 line
= lines
[idx
].rstrip()
95 #match = re.search(r'\*Create', line)
96 match
= re
.search(r
'[\*\s]Create(\w*)\(', line
)
98 #print('Line: %s' % match.group(1))
100 if re
.search(r
'^\s*Create', line
) is not None:
101 func_sig
= lines
[idx
-2].rstrip() + line
106 while not end_of_args
:
107 end_paren
= re
.search(r
'\)', line
)
108 if end_paren
is not None:
111 line
= lines
[idx
].rstrip()
115 delfunc
= re
.search(r
'LLVM_DELETED_FUNCTION|= delete;', func_sig
)
118 func
= re
.search(r
'(.*?)\*[\n\s]*(Create\w*)\((.*?)\)', func_sig
)
121 return_type
= func
.group(1).strip() + '*'
122 func_name
= func
.group(2)
123 arguments
= func
.group(3)
127 args
= arguments
.split(',')
131 func_args
.append(arg
)
133 split_args
= arg
.split('=')
134 arg_name
= split_args
[0].rsplit(None, 1)[-1]
136 reg_arg
= re
.search(r
'[\&\*]*(\w*)', arg_name
)
138 arg_names
+= [reg_arg
.group(1)]
142 # The following functions need to be ignored.
143 if func_name
== 'CreateInsertNUWNSWBinOp':
146 if func_name
== 'CreateMaskedIntrinsic':
149 # Convert CamelCase to CAMEL_CASE
150 func_mod
= re
.search(r
'Create(\w*)', func_name
)
152 func_mod
= func_mod
.group(1)
153 func_mod
= convert_uppercamel(func_mod
)
154 if func_mod
[0:2] == 'F_' or func_mod
[0:2] == 'I_':
155 func_mod
= func_mod
[0] + func_mod
[2:]
157 # Substitute alias based on CAMEL_CASE name.
158 func_alias
= inst_aliases
.get(func_mod
)
160 func_alias
= func_mod
162 if func_name
== 'CreateCall' or func_name
== 'CreateGEP':
163 arglist
= re
.search(r
'ArrayRef', ', '.join(func_args
))
165 func_alias
= func_alias
+ 'A'
170 'alias' : func_alias
,
171 'return' : return_type
,
172 'args' : ', '.join(func_args
),
173 'arg_names' : arg_names
,
179 Auto-generates macros for LLVM IR
181 def generate_gen_h(functions
, output_dir
):
182 filename
= 'gen_builder.hpp'
183 output_filename
= os
.path
.join(output_dir
, filename
)
186 for func
in functions
:
187 decl
= '%s %s(%s)' % (func
['return'], func
['alias'], func
['args'])
191 'intrin' : func
['name'],
192 'args' : ', '.join(func
['arg_names']),
195 MakoTemplateWriter
.to_file(
199 comment
='Builder IR Wrappers',
201 functions
=templfuncs
,
205 Auto-generates macros for LLVM IR
207 def generate_x86_h(output_dir
):
208 filename
= 'gen_builder_x86.hpp'
209 output_filename
= os
.path
.join(output_dir
, filename
)
212 for inst
in intrinsics
:
213 #print('Inst: %s, x86: %s numArgs: %d' % (inst[0], inst[1], len(inst[2])))
214 declargs
= 'Value* ' + ', Value* '.join(inst
[2])
217 'decl' : 'Value* %s(%s)' % (inst
[0], declargs
),
218 'args' : ', '.join(inst
[2]),
222 MakoTemplateWriter
.to_file(
226 comment
='x86 intrinsics',
232 Function which is invoked when this script is started from a command line.
233 Will present and consume a set of arguments which will tell this script how
239 parser
= ArgumentParser()
240 parser
.add_argument('--input', '-i', type=FileType('r'), help='Path to IRBuilder.h', required
=False)
241 parser
.add_argument('--output-dir', '-o', action
='store', dest
='output', help='Path to output directory', required
=True)
242 parser
.add_argument('--gen_h', help='Generate builder_gen.h', action
='store_true', default
=False)
243 parser
.add_argument('--gen_x86_h', help='Generate x86 intrinsics. No input is needed.', action
='store_true', default
=False)
244 args
= parser
.parse_args()
246 if not os
.path
.exists(args
.output
):
247 os
.makedirs(args
.output
)
250 functions
= parse_ir_builder(args
.input)
253 generate_gen_h(functions
, args
.output
)
256 print('Need to specify --input for --gen_h!')
259 generate_x86_h(args
.output
)
261 if __name__
== '__main__':