[Mesa-dev] [PATCH 26/28] swr: [rasterizer codegen] Rewrite gen_llvm_ir_macros.py to use mako

Tim Rowley timothy.o.rowley at intel.com
Thu Mar 16 00:13:20 UTC 2017


Don't create/use cpp files, header only now.
---
 src/gallium/drivers/swr/Makefile.am                |  61 +--
 .../swr/rasterizer/codegen/gen_llvm_ir_macros.py   | 411 +++++++--------------
 .../codegen/templates/gen_builder_template.hpp     |  47 +++
 .../drivers/swr/rasterizer/jitter/builder.h        |   4 +-
 4 files changed, 198 insertions(+), 325 deletions(-)
 create mode 100644 src/gallium/drivers/swr/rasterizer/codegen/templates/gen_builder_template.hpp

diff --git a/src/gallium/drivers/swr/Makefile.am b/src/gallium/drivers/swr/Makefile.am
index e5cf6f2..f9fda31 100644
--- a/src/gallium/drivers/swr/Makefile.am
+++ b/src/gallium/drivers/swr/Makefile.am
@@ -56,8 +56,7 @@ BUILT_SOURCES = \
 	rasterizer/codegen/gen_knobs.cpp \
 	rasterizer/codegen/gen_knobs.h \
 	rasterizer/jitter/state_llvm.h \
-	rasterizer/jitter/builder_x86.h \
-	rasterizer/jitter/builder_x86.cpp \
+	rasterizer/jitter/gen_builder_x86.hpp \
 	rasterizer/archrast/gen_ar_event.h \
 	rasterizer/archrast/gen_ar_event.cpp \
 	rasterizer/archrast/gen_ar_eventhandler.h \
@@ -95,36 +94,21 @@ rasterizer/jitter/state_llvm.h: rasterizer/codegen/gen_llvm_types.py rasterizer/
 		--input $(srcdir)/rasterizer/core/state.h \
 		--output rasterizer/jitter/state_llvm.h
 
-rasterizer/jitter/builder_gen.h: rasterizer/codegen/gen_llvm_ir_macros.py
+rasterizer/jitter/gen_builder.hpp: rasterizer/codegen/gen_llvm_ir_macros.py rasterizer/codegen/templates/gen_builder_template.hpp
 	$(MKDIR_GEN)
 	$(PYTHON_GEN) \
 		$(srcdir)/rasterizer/codegen/gen_llvm_ir_macros.py \
 		--input $(LLVM_INCLUDEDIR)/llvm/IR/IRBuilder.h \
-		--output rasterizer/jitter/builder_gen.h \
+		--output rasterizer/jitter \
 		--gen_h
 
-rasterizer/jitter/builder_gen.cpp: rasterizer/codegen/gen_llvm_ir_macros.py
+rasterizer/jitter/gen_builder_x86.hpp: rasterizer/codegen/gen_llvm_ir_macros.py rasterizer/codegen/templates/gen_builder_template.hpp
 	$(MKDIR_GEN)
 	$(PYTHON_GEN) \
 		$(srcdir)/rasterizer/codegen/gen_llvm_ir_macros.py \
-		--input $(LLVM_INCLUDEDIR)/llvm/IR/IRBuilder.h \
-		--output rasterizer/jitter/builder_gen.cpp \
-		--gen_cpp
-
-rasterizer/jitter/builder_x86.h: rasterizer/codegen/gen_llvm_ir_macros.py
-	$(MKDIR_GEN)
-	$(PYTHON_GEN) \
-		$(srcdir)/rasterizer/codegen/gen_llvm_ir_macros.py \
-		--output rasterizer/jitter/builder_x86.h \
+		--output rasterizer/jitter \
 		--gen_x86_h
 
-rasterizer/jitter/builder_x86.cpp: rasterizer/codegen/gen_llvm_ir_macros.py
-	$(MKDIR_GEN)
-	$(PYTHON_GEN) \
-		$(srcdir)/rasterizer/codegen/gen_llvm_ir_macros.py \
-		--output rasterizer/jitter/builder_x86.cpp \
-		--gen_x86_cpp
-
 rasterizer/archrast/gen_ar_event.h: rasterizer/codegen/gen_archrast.py rasterizer/codegen/templates/ar_event_h.template rasterizer/archrast/events.proto
 	$(MKDIR_GEN)
 	$(PYTHON_GEN) \
@@ -188,27 +172,17 @@ COMMON_LDFLAGS = \
 
 # XXX: As we cannot use BUILT_SOURCES (the files will end up in the dist
 # tarball) just annotate the dependency directly.
-# As the single direct user of builder_gen.h is a header (builder.h) trace all
+# As the single direct user of gen_builder.hpp is a header (builder.h) trace all
 # the translusive users (one that use the latter header).
-rasterizer/jitter/blend_jit.cpp: rasterizer/jitter/builder_gen.h
-rasterizer/jitter/builder.cpp: rasterizer/jitter/builder_gen.h
-rasterizer/jitter/builder_gen.cpp: rasterizer/jitter/builder_gen.h
-rasterizer/jitter/builder_x86.cpp: rasterizer/jitter/builder_gen.h
-rasterizer/jitter/builder_misc.cpp: rasterizer/jitter/builder_gen.h
-rasterizer/jitter/fetch_jit.cpp: rasterizer/jitter/builder_gen.h
-rasterizer/jitter/streamout_jit.cpp: rasterizer/jitter/builder_gen.h
-swr_shader.cpp: rasterizer/jitter/builder_gen.h
+rasterizer/jitter/blend_jit.cpp: rasterizer/jitter/gen_builder.hpp
+rasterizer/jitter/builder.cpp: rasterizer/jitter/gen_builder.hpp
+rasterizer/jitter/builder_misc.cpp: rasterizer/jitter/gen_builder.hpp
+rasterizer/jitter/fetch_jit.cpp: rasterizer/jitter/gen_builder.hpp
+rasterizer/jitter/streamout_jit.cpp: rasterizer/jitter/gen_builder.hpp
+swr_shader.cpp: rasterizer/jitter/gen_builder.hpp
 
 CLEANFILES = \
-	rasterizer/jitter/builder_gen.h \
-	rasterizer/jitter/builder_gen.cpp
-
-# XXX: Due to the funky dependencies above, the builder_x86.cpp file gets
-# generated (copied) into builddir when building from release tarball.
-# Add a temporary workaround to remove it, until the above issue is resolved.
-distclean-local:
-	( test $(top_srcdir) != $(top_builddir) && \
-		rm $(builddir)/rasterizer/jitter/builder_x86.cpp ) || true
+	rasterizer/jitter/gen_builder.hpp
 
 lib_LTLIBRARIES = libswrAVX.la libswrAVX2.la
 
@@ -226,8 +200,7 @@ libswrAVX_la_SOURCES = \
 # on systems with other versions of LLVM eg. 3.7 or 3.6.
 # Move these back to BUILT_SOURCES once that is resolved.
 nodist_libswrAVX_la_SOURCES = \
-	rasterizer/jitter/builder_gen.h \
-	rasterizer/jitter/builder_gen.cpp
+	rasterizer/jitter/gen_builder.hpp
 
 libswrAVX_la_LIBADD = \
 	$(COMMON_LIBADD)
@@ -249,8 +222,7 @@ libswrAVX2_la_SOURCES = \
 # on systems with other versions of LLVM eg. 3.7 or 3.6.
 # Move these back to BUILT_SOURCES once that is resolved.
 nodist_libswrAVX2_la_SOURCES = \
-	rasterizer/jitter/builder_gen.h \
-	rasterizer/jitter/builder_gen.cpp
+	rasterizer/jitter/gen_builder.hpp
 
 libswrAVX2_la_LIBADD = \
 	$(COMMON_LIBADD)
@@ -291,4 +263,5 @@ EXTRA_DIST = \
 	rasterizer/codegen/templates/ar_event_cpp.template \
 	rasterizer/codegen/templates/ar_eventhandler_h.template \
 	rasterizer/codegen/templates/ar_eventhandlerfile_h.template \
-	rasterizer/codegen/templates/backend_template.cpp
+	rasterizer/codegen/templates/backend_template.cpp \
+	rasterizer/codegen/templates/gen_builder_template.hpp
diff --git a/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_ir_macros.py b/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_ir_macros.py
index 70d3576..202dada 100644
--- a/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_ir_macros.py
+++ b/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_ir_macros.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2015 Intel Corporation.   All Rights Reserved.
+# Copyright (C) 2014-2017 Intel Corporation.   All Rights Reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
@@ -19,51 +19,32 @@
 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 # IN THE SOFTWARE.
 
-#!deps/python32/python.exe
-
+from __future__ import print_function
 import os, sys, re
 import argparse
 import json as JSON
 import operator
-
-header = r"""/****************************************************************************
-* Copyright (C) 2014-2016 Intel Corporation.   All Rights Reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a
-* copy of this software and associated documentation files (the "Software"),
-* to deal in the Software without restriction, including without limitation
-* the rights to use, copy, modify, merge, publish, distribute, sublicense,
-* and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice (including the next
-* paragraph) shall be included in all copies or substantial portions of the
-* Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-* IN THE SOFTWARE.
-* 
-* @file %s
-* 
-* @brief auto-generated file
-* 
-* DO NOT EDIT
-* 
-******************************************************************************/
-
-"""
-
-"""
-"""
-def gen_file_header(filename):
-    global header
-    headerStr = header % filename
-    return headerStr.splitlines()
+from mako.template import Template
+from mako.exceptions import RichTraceback
+
+def write_template_to_string(template_filename, **kwargs):
+    try:
+        template = Template(filename=os.path.abspath(template_filename))
+        # Split + Join fixes line-endings for whatever platform you are using
+        return '\n'.join(template.render(**kwargs).splitlines())
+    except:
+        traceback = RichTraceback()
+        for (filename, lineno, function, line) in traceback.traceback:
+            print('File %s, line %s, in %s' % (filename, lineno, function))
+            print(line, '\n')
+        print('%s: %s' % (str(traceback.error.__class__.__name__), traceback.error))
+
+def write_template_to_file(template_filename, output_filename, **kwargs):
+    output_dirname = os.path.dirname(output_filename)
+    if not os.path.exists(output_dirname):
+        os.makedirs(output_dirname)
+    with open(output_filename, 'w') as outfile:
+        print(write_template_to_string(template_filename, **kwargs), file=outfile)
 
 
 inst_aliases = {
@@ -84,42 +65,45 @@ inst_aliases = {
 }
 
 intrinsics = [
-        ["VGATHERPD", "x86_avx2_gather_d_pd_256", ["src", "pBase", "indices", "mask", "scale"]],
-        ["VGATHERPS", "x86_avx2_gather_d_ps_256", ["src", "pBase", "indices", "mask", "scale"]],
-        ["VGATHERDD", "x86_avx2_gather_d_d_256", ["src", "pBase", "indices", "mask", "scale"]],
-        ["VSQRTPS", "x86_avx_sqrt_ps_256", ["a"]],
-        ["VRSQRTPS", "x86_avx_rsqrt_ps_256", ["a"]],
-        ["VRCPPS", "x86_avx_rcp_ps_256", ["a"]],
-        ["VMINPS", "x86_avx_min_ps_256", ["a", "b"]],
-        ["VMAXPS", "x86_avx_max_ps_256", ["a", "b"]],
-        ["VROUND", "x86_avx_round_ps_256", ["a", "rounding"]],
-        ["VCMPPS", "x86_avx_cmp_ps_256", ["a", "b", "cmpop"]],
-        ["VBLENDVPS", "x86_avx_blendv_ps_256", ["a", "b", "mask"]],
-        ["BEXTR_32", "x86_bmi_bextr_32", ["src", "control"]],
-        ["VMASKLOADD", "x86_avx2_maskload_d_256", ["src", "mask"]],
-        ["VMASKMOVPS", "x86_avx_maskload_ps_256", ["src", "mask"]],
-        ["VMASKSTOREPS", "x86_avx_maskstore_ps_256", ["src", "mask", "val"]],
-        ["VPSHUFB", "x86_avx2_pshuf_b", ["a", "b"]],
-        ["VPERMD", "x86_avx2_permd", ["a", "idx"]],
-        ["VPERMPS", "x86_avx2_permps", ["idx", "a"]],
-        ["VCVTPD2PS", "x86_avx_cvt_pd2_ps_256", ["a"]],
-        ["VCVTPH2PS", "x86_vcvtph2ps_256", ["a"]],
-        ["VCVTPS2PH", "x86_vcvtps2ph_256", ["a", "round"]],
-        ["VHSUBPS", "x86_avx_hsub_ps_256", ["a", "b"]],
-        ["VPTESTC", "x86_avx_ptestc_256", ["a", "b"]],
-        ["VPTESTZ", "x86_avx_ptestz_256", ["a", "b"]],
-        ["VFMADDPS", "x86_fma_vfmadd_ps_256", ["a", "b", "c"]],
-        ["VMOVMSKPS", "x86_avx_movmsk_ps_256", ["a"]],
-        ["INTERRUPT", "x86_int", ["a"]],
+        ['VGATHERPD', 'x86_avx2_gather_d_pd_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
+        ['VGATHERPS', 'x86_avx2_gather_d_ps_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
+        ['VGATHERDD', 'x86_avx2_gather_d_d_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
+        ['VSQRTPS', 'x86_avx_sqrt_ps_256', ['a']],
+        ['VRSQRTPS', 'x86_avx_rsqrt_ps_256', ['a']],
+        ['VRCPPS', 'x86_avx_rcp_ps_256', ['a']],
+        ['VMINPS', 'x86_avx_min_ps_256', ['a', 'b']],
+        ['VMAXPS', 'x86_avx_max_ps_256', ['a', 'b']],
+        ['VROUND', 'x86_avx_round_ps_256', ['a', 'rounding']],
+        ['VCMPPS', 'x86_avx_cmp_ps_256', ['a', 'b', 'cmpop']],
+        ['VBLENDVPS', 'x86_avx_blendv_ps_256', ['a', 'b', 'mask']],
+        ['BEXTR_32', 'x86_bmi_bextr_32', ['src', 'control']],
+        ['VMASKLOADD', 'x86_avx2_maskload_d_256', ['src', 'mask']],
+        ['VMASKMOVPS', 'x86_avx_maskload_ps_256', ['src', 'mask']],
+        ['VMASKSTOREPS', 'x86_avx_maskstore_ps_256', ['src', 'mask', 'val']],
+        ['VPSHUFB', 'x86_avx2_pshuf_b', ['a', 'b']],
+        ['VPERMD', 'x86_avx2_permd', ['a', 'idx']],
+        ['VPERMPS', 'x86_avx2_permps', ['idx', 'a']],
+        ['VCVTPD2PS', 'x86_avx_cvt_pd2_ps_256', ['a']],
+        ['VCVTPH2PS', 'x86_vcvtph2ps_256', ['a']],
+        ['VCVTPS2PH', 'x86_vcvtps2ph_256', ['a', 'round']],
+        ['VHSUBPS', 'x86_avx_hsub_ps_256', ['a', 'b']],
+        ['VPTESTC', 'x86_avx_ptestc_256', ['a', 'b']],
+        ['VPTESTZ', 'x86_avx_ptestz_256', ['a', 'b']],
+        ['VFMADDPS', 'x86_fma_vfmadd_ps_256', ['a', 'b', 'c']],
+        ['VMOVMSKPS', 'x86_avx_movmsk_ps_256', ['a']],
+        ['INTERRUPT', 'x86_int', ['a']],
     ]
 
+this_dir = os.path.dirname(os.path.abspath(__file__))
+template = os.path.join(this_dir, 'templates', 'gen_builder_template.hpp')
+
 def convert_uppercamel(name):
     s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
     return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).upper()
 
-"""
+'''
     Given an input file (e.g. IRBuilder.h) generates function dictionary.
-"""
+'''
 def parse_ir_builder(input_file):
 
     functions = []
@@ -131,19 +115,19 @@ def parse_ir_builder(input_file):
         line = lines[idx].rstrip()
         idx += 1
 
-        #match = re.search(r"\*Create", line)
-        match = re.search(r"[\*\s]Create(\w*)\(", line)
+        #match = re.search(r'\*Create', line)
+        match = re.search(r'[\*\s]Create(\w*)\(', line)
         if match is not None:
-            #print("Line: %s" % match.group(1))
+            #print('Line: %s' % match.group(1))
 
-            if re.search(r"^\s*Create", line) is not None:
+            if re.search(r'^\s*Create', line) is not None:
                 func_sig = lines[idx-2].rstrip() + line
             else:
                 func_sig = line
 
             end_of_args = False
             while not end_of_args:
-                end_paren = re.search(r"\)", line)
+                end_paren = re.search(r'\)', line)
                 if end_paren is not None:
                     end_of_args = True
                 else:
@@ -151,45 +135,31 @@ def parse_ir_builder(input_file):
                     func_sig += line
                     idx += 1
 
-            delfunc = re.search(r"LLVM_DELETED_FUNCTION|= delete;", func_sig)
+            delfunc = re.search(r'LLVM_DELETED_FUNCTION|= delete;', func_sig)
 
             if not delfunc:
-                func = re.search(r"(.*?)\*[\n\s]*(Create\w*)\((.*?)\)", func_sig)
+                func = re.search(r'(.*?)\*[\n\s]*(Create\w*)\((.*?)\)', func_sig)
                 if func is not None:
 
-                    return_type = func.group(1).lstrip() + '*'
+                    return_type = func.group(1).strip() + '*'
                     func_name = func.group(2)
                     arguments = func.group(3)
 
-                    func_args = ''
-                    func_args_nodefs = ''
-
-                    num_args = arguments.count(',')
-
+                    func_args = []
                     arg_names = []
-                    num_args = 0
                     args = arguments.split(',')
                     for arg in args:
-                        arg = arg.lstrip()
+                        arg = arg.strip()
                         if arg:
-                            if num_args > 0:
-                                func_args += ', '
-                                func_args_nodefs += ', '
-                            func_args += arg
-                            func_args_nodefs += arg.split(' =')[0]
+                            func_args.append(arg)
 
                             split_args = arg.split('=')
                             arg_name = split_args[0].rsplit(None, 1)[-1]
 
-                            #print("Before ArgName = %s" % arg_name)
-
-                            reg_arg = re.search(r"[\&\*]*(\w*)", arg_name)
+                            reg_arg = re.search(r'[\&\*]*(\w*)', arg_name)
                             if reg_arg:
-                                #print("Arg Name = %s" % reg_arg.group(1))
                                 arg_names += [reg_arg.group(1)]
 
-                            num_args += 1
-
                     ignore = False
 
                     # The following functions need to be ignored.
@@ -200,7 +170,7 @@ def parse_ir_builder(input_file):
                         ignore = True
 
                     # Convert CamelCase to CAMEL_CASE
-                    func_mod = re.search(r"Create(\w*)", func_name)
+                    func_mod = re.search(r'Create(\w*)', func_name)
                     if func_mod:
                         func_mod = func_mod.group(1)
                         func_mod = convert_uppercamel(func_mod)
@@ -213,218 +183,101 @@ def parse_ir_builder(input_file):
                         func_alias = func_mod
 
                         if func_name == 'CreateCall' or func_name == 'CreateGEP':
-                            arglist = re.search(r'ArrayRef', func_args)
+                            arglist = re.search(r'ArrayRef', ', '.join(func_args))
                             if arglist:
                                 func_alias = func_alias + 'A'
 
                     if not ignore:
                         functions.append({
-                                "name": func_name,
-                                "alias": func_alias,
-                                "return": return_type,
-                                "args": func_args,
-                                "args_nodefs": func_args_nodefs,
-                                "arg_names": arg_names
+                                'name'      : func_name,
+                                'alias'     : func_alias,
+                                'return'    : return_type,
+                                'args'      : ', '.join(func_args),
+                                'arg_names' : arg_names,
                             })
 
     return functions
 
-"""
+'''
     Auto-generates macros for LLVM IR
-"""
-def generate_gen_h(functions, output_file):
-    output_lines = gen_file_header(os.path.basename(output_file.name))
-
-    output_lines += [
-        '#pragma once',
-        '',
-        '//////////////////////////////////////////////////////////////////////////',
-        '/// Auto-generated Builder IR declarations',
-        '//////////////////////////////////////////////////////////////////////////',
-    ]
-
-    for func in functions:
-        name = func['name']
-        if func['alias']:
-            name = func['alias']
-        output_lines += [
-            '%s%s(%s);' % (func['return'], name, func['args'])
-        ]
-
-    output_file.write('\n'.join(output_lines) + '\n')
-
-"""
-    Auto-generates macros for LLVM IR
-"""
-def generate_gen_cpp(functions, output_file):
-    output_lines = gen_file_header(os.path.basename(output_file.name))
-
-    output_lines += [
-        '#include \"builder.h\"',
-        '',
-        'namespace SwrJit',
-        '{',
-        '    using namespace llvm;',
-        '',
-    ]
+'''
+def generate_gen_h(functions, output_dir):
+    filename = 'gen_builder.hpp'
+    output_filename = os.path.join(output_dir, filename)
 
+    templfuncs = []
     for func in functions:
-        name = func['name']
-        if func['alias']:
-            name = func['alias']
-
-        args = func['arg_names']
-        func_args = ''
-        first_arg = True
-        for arg in args:
-            if not first_arg:
-                func_args += ', '
-            func_args += arg
-            first_arg = False
-
-        output_lines += [
-            '    //////////////////////////////////////////////////////////////////////////',
-            '    %sBuilder::%s(%s)' % (func['return'], name, func['args_nodefs']),
-            '    {',
-            '       return IRB()->%s(%s);' % (func['name'], func_args),
-            '    }',
-            '',
-        ]
-    output_lines.append('}')
-    output_file.write('\n'.join(output_lines) + '\n')
-
-"""
+        decl = '%s %s(%s)' % (func['return'], func['alias'], func['args'])
+
+        templfuncs.append({
+            'decl'      : decl,
+            'intrin'    : func['name'],
+            'args'      : ', '.join(func['arg_names']),
+        })
+
+    write_template_to_file(
+        template,
+        output_filename,
+        comment='Builder IR Wrappers',
+        filename=filename,
+        functions=templfuncs,
+        isX86=False)
+
+'''
     Auto-generates macros for LLVM IR
-"""
-def generate_x86_h(output_file):
-    output_lines = gen_file_header(os.path.basename(output_file.name))
-
-    output_lines += [
-        '#pragma once',
-        '',
-        '//////////////////////////////////////////////////////////////////////////',
-        '/// Auto-generated x86 intrinsics',
-        '//////////////////////////////////////////////////////////////////////////',
-    ]
-
-    for inst in intrinsics:
-        #print("Inst: %s, x86: %s numArgs: %d" % (inst[0], inst[1], len(inst[2])))
-
-        args = ''
-        first = True
-        for arg in inst[2]:
-            if not first:
-                args += ', '
-            args += ("Value* %s" % arg)
-            first = False
-
-        output_lines += [
-            'Value *%s(%s);' % (inst[0], args)
-        ]
-
-    output_file.write('\n'.join(output_lines) + '\n')
-
-"""
-    Auto-generates macros for LLVM IR
-"""
-def generate_x86_cpp(output_file):
-    output_lines = gen_file_header(os.path.basename(output_file.name))
-
-    output_lines += [
-        '#include \"builder.h\"',
-        '',
-        'namespace SwrJit',
-        '{',
-        '    using namespace llvm;',
-        '',
-    ]
+'''
+def generate_x86_h(output_dir):
+    filename = 'gen_builder_x86.hpp'
+    output_filename = os.path.join(output_dir, filename)
 
+    functions = []
     for inst in intrinsics:
-        #print("Inst: %s, x86: %s numArgs: %d" % (inst[0], inst[1], len(inst[2])))
-
-        args = ''
-        pass_args = ''
-        first = True
-        for arg in inst[2]:
-            if not first:
-                args += ', '
-                pass_args += ', '
-            args += ("Value* %s" % arg)
-            pass_args += arg
-            first = False
-
-        output_lines += [
-            '    //////////////////////////////////////////////////////////////////////////',
-            '    Value *Builder::%s(%s)' % (inst[0], args),
-            '    {',
-            '        Function *func = Intrinsic::getDeclaration(JM()->mpCurrentModule, Intrinsic::%s);' % inst[1],
-        ]
-        if inst[0] == "VPERMD":
-            rev_args = ''
-            first = True
-            for arg in reversed(inst[2]):
-                if not first:
-                    rev_args += ', '
-                rev_args += arg
-                first = False
-
-            output_lines += [
-                '#if (HAVE_LLVM == 0x306) && (LLVM_VERSION_PATCH == 0)',
-                '        return CALL(func, std::initializer_list<Value*>{%s});' % rev_args,
-                '#else',
-            ]
-        output_lines += [
-            '        return CALL(func, std::initializer_list<Value*>{%s});' % pass_args,
-        ]
-        if inst[0] == "VPERMD":
-            output_lines += [
-                '#endif',
-            ]
-        output_lines += [
-            '    }',
-            '',
-        ]
-
-    output_lines.append('}')
-    output_file.write('\n'.join(output_lines) + '\n')
-
-"""
+        #print('Inst: %s, x86: %s numArgs: %d' % (inst[0], inst[1], len(inst[2])))
+        declargs = 'Value* ' + ', Value* '.join(inst[2])
+
+        functions.append({
+            'decl'      : 'Value* %s(%s)' % (inst[0], declargs),
+            'args'      : ', '.join(inst[2]),
+            'intrin'    : inst[1],
+        })
+
+    write_template_to_file(
+        template,
+        output_filename,
+        comment='x86 intrinsics',
+        filename=filename,
+        functions=functions,
+        isX86=True)
+
+'''
     Function which is invoked when this script is started from a command line.
     Will present and consume a set of arguments which will tell this script how
     to behave
-"""
+'''
 def main():
 
     # Parse args...
     parser = argparse.ArgumentParser()
-    parser.add_argument("--input", "-i", type=argparse.FileType('r'), help="Path to IRBuilder.h", required=False)
-    parser.add_argument("--output", "-o", type=argparse.FileType('w'), help="Path to output file", required=True)
-    parser.add_argument("--gen_h", "-gen_h", help="Generate builder_gen.h", action="store_true", default=False)
-    parser.add_argument("--gen_cpp", "-gen_cpp", help="Generate builder_gen.cpp", action="store_true", default=False)
-    parser.add_argument("--gen_x86_h", "-gen_x86_h", help="Generate x86 intrinsics. No input is needed.", action="store_true", default=False)
-    parser.add_argument("--gen_x86_cpp", "-gen_x86_cpp", help="Generate x86 intrinsics. No input is needed.", action="store_true", default=False)
+    parser.add_argument('--input', '-i', type=argparse.FileType('r'), help='Path to IRBuilder.h', required=False)
+    parser.add_argument('--output-dir', '-o', action='store', dest='output', help='Path to output directory', required=True)
+    parser.add_argument('--gen_h', help='Generate builder_gen.h', action='store_true', default=False)
+    parser.add_argument('--gen_x86_h', help='Generate x86 intrinsics. No input is needed.', action='store_true', default=False)
     args = parser.parse_args()
 
+    if not os.path.exists(args.output):
+        os.makedirs(args.output)
+
     if args.input:
         functions = parse_ir_builder(args.input)
 
         if args.gen_h:
             generate_gen_h(functions, args.output)
 
-        if args.gen_cpp:
-            generate_gen_cpp(functions, args.output)
-    else:
-        if args.gen_x86_h:
-            generate_x86_h(args.output)
-
-        if args.gen_x86_cpp:
-            generate_x86_cpp(args.output)
-
-        if args.gen_h:
-            print("Need to specify --input for --gen_h!")
+    elif args.gen_h:
+        print('Need to specify --input for --gen_h!')
 
-        if args.gen_cpp:
-            print("Need to specify --input for --gen_cpp!")
+    if args.gen_x86_h:
+        generate_x86_h(args.output)
 
 if __name__ == '__main__':
     main()
diff --git a/src/gallium/drivers/swr/rasterizer/codegen/templates/gen_builder_template.hpp b/src/gallium/drivers/swr/rasterizer/codegen/templates/gen_builder_template.hpp
new file mode 100644
index 0000000..6a56eb1
--- /dev/null
+++ b/src/gallium/drivers/swr/rasterizer/codegen/templates/gen_builder_template.hpp
@@ -0,0 +1,47 @@
+//============================================================================
+// Copyright (C) 2014-2017 Intel Corporation.   All Rights Reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice (including the next
+// paragraph) shall be included in all copies or substantial portions of the
+// Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//
+// @file ${filename}
+//
+// @brief auto-generated file
+//
+// DO NOT EDIT
+//
+//============================================================================
+#pragma once
+
+//============================================================================
+// Auto-generated ${comment}
+//============================================================================
+
+%for func in functions:
+${func['decl']}
+{
+%if isX86:
+    Function *pFunc = Intrinsic::getDeclaration(JM()->mpCurrentModule, Intrinsic::${func['intrin']});
+    return CALL(pFunc, std::initializer_list<Value*>{${func['args']}});
+%else:
+    return IRB()->${func['intrin']}(${func['args']});
+%endif
+}
+
+%endfor
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/builder.h b/src/gallium/drivers/swr/rasterizer/jitter/builder.h
index 6627b33..703f332 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/builder.h
+++ b/src/gallium/drivers/swr/rasterizer/jitter/builder.h
@@ -70,8 +70,8 @@ namespace SwrJit
         Type*                mSimdVectorTy;
         Type*                mSimdVectorTRTy;
 
-#include "builder_gen.h"
-#include "builder_x86.h"
+#include "gen_builder.hpp"
+#include "gen_builder_x86.hpp"
 #include "builder_misc.h"
 #include "builder_math.h"
     };
-- 
2.7.4



More information about the mesa-dev mailing list