"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_ir_macros.py" (16 Sep 2020, 12919 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "gen_llvm_ir_macros.py" see the Fossies "Dox" file reference documentation.

    1 # Copyright (C) 2014-2018 Intel Corporation.   All Rights Reserved.
    2 #
    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:
    9 #
   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
   12 # Software.
   13 #
   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
   20 # IN THE SOFTWARE.
   21 
   22 from __future__ import print_function
   23 import os, sys, re
   24 from gen_common import *
   25 from argparse import FileType
   26 
   27 inst_aliases = {
   28     'SHUFFLE_VECTOR': 'VSHUFFLE',
   29     'INSERT_ELEMENT': 'VINSERT',
   30     'EXTRACT_ELEMENT': 'VEXTRACT',
   31     'MEM_SET': 'MEMSET',
   32     'MEM_CPY': 'MEMCOPY',
   33     'MEM_MOVE': 'MEMMOVE',
   34     'L_SHR': 'LSHR',
   35     'A_SHR': 'ASHR',
   36     'BIT_CAST': 'BITCAST',
   37     'U_DIV': 'UDIV',
   38     'S_DIV': 'SDIV',
   39     'U_REM': 'UREM',
   40     'S_REM': 'SREM',
   41     'BIN_OP': 'BINOP',
   42 }
   43 
   44 intrinsics = [
   45     ['VGATHERPD',   ['src', 'pBase', 'indices', 'mask', 'scale'], 'src'],
   46     ['VGATHERPS',   ['src', 'pBase', 'indices', 'mask', 'scale'], 'src'],
   47     ['VGATHERDD',   ['src', 'pBase', 'indices', 'mask', 'scale'], 'src'],
   48     ['VSCATTERPS',  ['pBase', 'mask', 'indices', 'src', 'scale'], 'src'],
   49     ['VRCPPS',      ['a'], 'a'],
   50     ['VROUND',      ['a', 'rounding'], 'a'],
   51     ['BEXTR_32',    ['src', 'control'], 'src'],
   52     ['VPSHUFB',     ['a', 'b'], 'a'],
   53     ['VPERMD',      ['a', 'idx'], 'a'],
   54     ['VPERMPS',     ['idx', 'a'], 'a'],
   55     ['VCVTPD2PS',   ['a'], 'VectorType::get(mFP32Ty, VEC_GET_NUM_ELEMS)'],
   56     ['VCVTPS2PH',   ['a', 'round'], 'mSimdInt16Ty'],
   57     ['VHSUBPS',     ['a', 'b'], 'a'],
   58     ['VPTESTC',     ['a', 'b'], 'mInt32Ty'],
   59     ['VPTESTZ',     ['a', 'b'], 'mInt32Ty'],
   60     ['VPHADDD',     ['a', 'b'], 'a'],
   61     ['PDEP32',      ['a', 'b'], 'a'],
   62     ['RDTSC',       [], 'mInt64Ty'],
   63 ]
   64 
   65 llvm_intrinsics = [
   66     ['CTTZ', 'cttz', ['a', 'flag'], ['a']],
   67     ['CTLZ', 'ctlz', ['a', 'flag'], ['a']],
   68     ['VSQRTPS', 'sqrt', ['a'], ['a']],
   69     ['STACKSAVE', 'stacksave', [], []],
   70     ['STACKRESTORE', 'stackrestore', ['a'], []],
   71     ['VMINPS', 'minnum', ['a', 'b'], ['a']],
   72     ['VMAXPS', 'maxnum', ['a', 'b'], ['a']],
   73     ['VFMADDPS', 'fmuladd', ['a', 'b', 'c'], ['a']],
   74     ['DEBUGTRAP', 'debugtrap', [], []],
   75     ['POPCNT', 'ctpop', ['a'], ['a']],
   76     ['LOG2', 'log2', ['a'], ['a']],
   77     ['FABS', 'fabs', ['a'], ['a']],
   78     ['EXP2', 'exp2', ['a'], ['a']],
   79     ['COS', 'cos', ['a'], ['a']],
   80     ['SIN', 'sin', ['a'], ['a']],
   81     ['FLOOR', 'floor', ['a'], ['a']],
   82     ['POW', 'pow', ['a', 'b'], ['a']]
   83 ]
   84 
   85 this_dir = os.path.dirname(os.path.abspath(__file__))
   86 template = os.path.join(this_dir, 'templates', 'gen_builder.hpp')
   87 
   88 def convert_uppercamel(name):
   89     s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
   90     return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).upper()
   91 
   92 '''
   93     Given an input file (e.g. IRBuilder.h) generates function dictionary.
   94 '''
   95 def parse_ir_builder(input_file):
   96 
   97     functions = []
   98 
   99     lines = input_file.readlines()
  100     deprecated = None
  101 
  102     idx = 0
  103     while idx < len(lines) - 1:
  104         line = lines[idx].rstrip()
  105         idx += 1
  106 
  107         if deprecated is None:
  108             deprecated = re.search(r'LLVM_ATTRIBUTE_DEPRECATED', line)
  109 
  110         #match = re.search(r'\*Create', line)
  111         match = re.search(r'[\*\s]Create(\w*)\(', line)
  112         if match is not None:
  113             #print('Line: %s' % match.group(1))
  114 
  115             # Skip function if LLVM_ATTRIBUTE_DEPRECATED found before
  116             if deprecated is not None:
  117                 deprecated = None
  118                 continue
  119 
  120             if re.search(r'^\s*Create', line) is not None:
  121                 func_sig = lines[idx-2].rstrip() + line
  122             else:
  123                 func_sig = line
  124 
  125             end_of_args = False
  126             while not end_of_args:
  127                 end_paren = re.search(r'\)', line)
  128                 if end_paren is not None:
  129                     end_of_args = True
  130                 else:
  131                     line = lines[idx].rstrip()
  132                     func_sig += line
  133                     idx += 1
  134 
  135             delfunc = re.search(r'LLVM_DELETED_FUNCTION|= delete;', func_sig)
  136 
  137             if not delfunc:
  138                 func = re.search(r'(.*?)\*[\n\s]*(Create\w*)\((.*?)\)', func_sig)
  139                 if func is not None:
  140 
  141                     return_type = func.group(1).strip() + '*'
  142                     func_name = func.group(2)
  143                     arguments = func.group(3)
  144 
  145                     func_args = []
  146                     arg_names = []
  147                     args = arguments.split(',')
  148                     for arg in args:
  149                         arg = arg.strip()
  150                         if arg:
  151                             func_args.append(arg)
  152 
  153                             split_args = arg.split('=')
  154                             arg_name = split_args[0].rsplit(None, 1)[-1]
  155 
  156                             reg_arg = re.search(r'[\&\*]*(\w*)', arg_name)
  157                             if reg_arg:
  158                                 arg_names += [reg_arg.group(1)]
  159 
  160                     ignore = False
  161 
  162                     # The following functions need to be ignored in openswr.
  163                     # API change in llvm-5.0 breaks baked autogen files
  164                     if (
  165                         (func_name == 'CreateFence' or
  166                          func_name == 'CreateAtomicCmpXchg' or
  167                          func_name == 'CreateAtomicRMW')):
  168                         ignore = True
  169 
  170                     # The following functions need to be ignored.
  171                     if (func_name == 'CreateInsertNUWNSWBinOp' or
  172                         func_name == 'CreateMaskedIntrinsic' or
  173                         func_name == 'CreateAlignmentAssumptionHelper' or
  174                         func_name == 'CreateGEP' or
  175                         func_name == 'CreateLoad' or
  176                         func_name == 'CreateMaskedLoad' or
  177                         func_name == 'CreateStore' or
  178                         func_name == 'CreateMaskedStore' or
  179                         func_name == 'CreateFCmpHelper' or
  180                         func_name == 'CreateElementUnorderedAtomicMemCpy'):
  181                         ignore = True
  182 
  183                     # Convert CamelCase to CAMEL_CASE
  184                     func_mod = re.search(r'Create(\w*)', func_name)
  185                     if func_mod:
  186                         func_mod = func_mod.group(1)
  187                         func_mod = convert_uppercamel(func_mod)
  188                         if func_mod[0:2] == 'F_' or func_mod[0:2] == 'I_':
  189                             func_mod = func_mod[0] + func_mod[2:]
  190 
  191                     # Substitute alias based on CAMEL_CASE name.
  192                     func_alias = inst_aliases.get(func_mod)
  193                     if not func_alias:
  194                         func_alias = func_mod
  195 
  196                         if func_name == 'CreateCall' or func_name == 'CreateGEP':
  197                             arglist = re.search(r'ArrayRef', ', '.join(func_args))
  198                             if arglist:
  199                                 func_alias = func_alias + 'A'
  200 
  201                     if not ignore:
  202                         functions.append({
  203                                 'name'      : func_name,
  204                                 'alias'     : func_alias,
  205                                 'return'    : return_type,
  206                                 'args'      : ', '.join(func_args),
  207                                 'arg_names' : arg_names,
  208                             })
  209 
  210     return functions
  211 
  212 '''
  213     Auto-generates macros for LLVM IR
  214 '''
  215 def generate_gen_h(functions, output_dir):
  216     filename = 'gen_builder.hpp'
  217     output_filename = os.path.join(output_dir, filename)
  218 
  219     templfuncs = []
  220     for func in functions:
  221         decl = '%s %s(%s)' % (func['return'], func['alias'], func['args'])
  222 
  223         templfuncs.append({
  224             'decl'      : decl,
  225             'intrin'    : func['name'],
  226             'args'      : func['arg_names'],
  227         })
  228 
  229     MakoTemplateWriter.to_file(
  230         template,
  231         output_filename,
  232         cmdline=sys.argv,
  233         comment='Builder IR Wrappers',
  234         filename=filename,
  235         functions=templfuncs,
  236         isX86=False, isIntrin=False)
  237 
  238 '''
  239     Auto-generates macros for LLVM IR
  240 '''
  241 def generate_meta_h(output_dir):
  242     filename = 'gen_builder_meta.hpp'
  243     output_filename = os.path.join(output_dir, filename)
  244 
  245     functions = []
  246     for inst in intrinsics:
  247         name = inst[0]
  248         args = inst[1]
  249         ret = inst[2]
  250 
  251         #print('Inst: %s, x86: %s numArgs: %d' % (inst[0], inst[1], len(inst[2])))
  252         if len(args) != 0:
  253             declargs = 'Value* ' + ', Value* '.join(args)
  254             decl = 'Value* %s(%s, const llvm::Twine& name = "")' % (name, declargs)
  255         else:
  256             decl = 'Value* %s(const llvm::Twine& name = "")' % (name)
  257 
  258         # determine the return type of the intrinsic. It can either be:
  259         # - type of one of the input arguments
  260         # - snippet of code to set the return type
  261 
  262         if ret in args:
  263             returnTy = ret + '->getType()'
  264         else:
  265             returnTy = ret
  266 
  267         functions.append({
  268             'decl'      : decl,
  269             'name'      : name,
  270             'args'      : args,
  271             'returnType': returnTy
  272         })
  273 
  274     MakoTemplateWriter.to_file(
  275         template,
  276         output_filename,
  277         cmdline=sys.argv,
  278         comment='meta intrinsics',
  279         filename=filename,
  280         functions=functions,
  281         isX86=True, isIntrin=False)
  282 
  283 def generate_intrin_h(output_dir):
  284     filename = 'gen_builder_intrin.hpp'
  285     output_filename = os.path.join(output_dir, filename)
  286 
  287     functions = []
  288     for inst in llvm_intrinsics:
  289         #print('Inst: %s, x86: %s numArgs: %d' % (inst[0], inst[1], len(inst[2])))
  290         if len(inst[2]) != 0:
  291             declargs = 'Value* ' + ', Value* '.join(inst[2])
  292             decl = 'Value* %s(%s, const llvm::Twine& name = "")' % (inst[0], declargs)
  293         else:
  294             decl = 'Value* %s(const llvm::Twine& name = "")' % (inst[0])
  295 
  296         functions.append({
  297             'decl'      : decl,
  298             'intrin'    : inst[1],
  299             'args'      : inst[2],
  300             'types'     : inst[3],
  301         })
  302 
  303     MakoTemplateWriter.to_file(
  304         template,
  305         output_filename,
  306         cmdline=sys.argv,
  307         comment='llvm intrinsics',
  308         filename=filename,
  309         functions=functions,
  310         isX86=False, isIntrin=True)
  311 '''
  312     Function which is invoked when this script is started from a command line.
  313     Will present and consume a set of arguments which will tell this script how
  314     to behave
  315 '''
  316 def main():
  317 
  318     # Parse args...
  319     parser = ArgumentParser()
  320     parser.add_argument('--input', '-i', type=FileType('r'), help='Path to IRBuilder.h', required=False)
  321     parser.add_argument('--output-dir', '-o', action='store', dest='output', help='Path to output directory', required=True)
  322     parser.add_argument('--gen_h', help='Generate builder_gen.h', action='store_true', default=False)
  323     parser.add_argument('--gen_meta_h', help='Generate meta intrinsics. No input is needed.', action='store_true', default=False)
  324     parser.add_argument('--gen_intrin_h', help='Generate llvm intrinsics. No input is needed.', action='store_true', default=False)
  325     args = parser.parse_args()
  326 
  327     if not os.path.exists(args.output):
  328         os.makedirs(args.output)
  329 
  330     final_output_dir = args.output
  331     args.output = MakeTmpDir('_codegen')
  332 
  333     rval = 0
  334     try:
  335         if args.input:
  336             functions = parse_ir_builder(args.input)
  337 
  338             if args.gen_h:
  339                 generate_gen_h(functions, args.output)
  340 
  341         elif args.gen_h:
  342             print('Need to specify --input for --gen_h!')
  343 
  344         if args.gen_meta_h:
  345             generate_meta_h(args.output)
  346 
  347         if args.gen_intrin_h:
  348             generate_intrin_h(args.output)
  349 
  350         rval = CopyDirFilesIfDifferent(args.output, final_output_dir)
  351 
  352     except:
  353         print('ERROR: Could not generate llvm_ir_macros', file=sys.stderr)
  354         rval = 1
  355 
  356     finally:
  357         DeleteDirTree(args.output)
  358 
  359     return rval
  360 
  361 if __name__ == '__main__':
  362     sys.exit(main())
  363 # END OF FILE