[Mesa-dev] [PATCH 40/45] swr/rast: minimize codegen redundant work
George Kyriazis
george.kyriazis at intel.com
Fri Apr 13 19:02:20 UTC 2018
Move filtering of redundant codegen operations into gen scripts themselves
---
.../drivers/swr/rasterizer/codegen/gen_archrast.py | 111 +++++++++--------
.../drivers/swr/rasterizer/codegen/gen_backends.py | 97 +++++++++------
.../drivers/swr/rasterizer/codegen/gen_common.py | 131 +++++++++++++++++++--
.../drivers/swr/rasterizer/codegen/gen_knobs.py | 53 ++++++---
.../swr/rasterizer/codegen/gen_llvm_ir_macros.py | 42 +++++--
.../swr/rasterizer/codegen/gen_llvm_types.py | 29 ++++-
6 files changed, 335 insertions(+), 128 deletions(-)
diff --git a/src/gallium/drivers/swr/rasterizer/codegen/gen_archrast.py b/src/gallium/drivers/swr/rasterizer/codegen/gen_archrast.py
index aa09f22..c5842aa 100644
--- a/src/gallium/drivers/swr/rasterizer/codegen/gen_archrast.py
+++ b/src/gallium/drivers/swr/rasterizer/codegen/gen_archrast.py
@@ -24,7 +24,7 @@ from __future__ import print_function
import os
import sys
import re
-from gen_common import ArgumentParser, MakoTemplateWriter
+from gen_common import *
def parse_event_fields(lines, idx, event_dict):
field_names = []
@@ -144,6 +144,10 @@ def main():
print('Error: Could not find private proto file %s' % proto_private_filename, file=sys.stderr)
return 1
+ final_output_dir = output_dir
+ MakeDir(final_output_dir)
+ output_dir = MakeTmpDir('_codegen')
+
protos = {}
protos['events'] = {} # event dictionary containing events with their fields
protos['event_names'] = [] # needed to keep events in order parsed. dict is not ordered.
@@ -153,53 +157,64 @@ def main():
parse_protos(protos, proto_filename)
parse_protos(protos, proto_private_filename)
- # Generate event header
- if args.gen_event_hpp:
- curdir = os.path.dirname(os.path.abspath(__file__))
- template_file = os.sep.join([curdir, 'templates', 'gen_ar_event.hpp'])
- output_fullpath = os.sep.join([output_dir, output_filename])
-
- MakoTemplateWriter.to_file(template_file, output_fullpath,
- cmdline=sys.argv,
- filename=output_filename,
- protos=protos)
-
- # Generate event implementation
- if args.gen_event_cpp:
- curdir = os.path.dirname(os.path.abspath(__file__))
- template_file = os.sep.join([curdir, 'templates', 'gen_ar_event.cpp'])
- output_fullpath = os.sep.join([output_dir, output_filename])
-
- MakoTemplateWriter.to_file(template_file, output_fullpath,
- cmdline=sys.argv,
- filename=output_filename,
- protos=protos)
-
- # Generate event handler header
- if args.gen_eventhandler_hpp:
- curdir = os.path.dirname(os.path.abspath(__file__))
- template_file = os.sep.join([curdir, 'templates', 'gen_ar_eventhandler.hpp'])
- output_fullpath = os.sep.join([output_dir, output_filename])
-
- MakoTemplateWriter.to_file(template_file, output_fullpath,
- cmdline=sys.argv,
- filename=output_filename,
- event_header='gen_ar_event.hpp',
- protos=protos)
-
- # Generate event handler header
- if args.gen_eventhandlerfile_hpp:
- curdir = os.path.dirname(os.path.abspath(__file__))
- template_file = os.sep.join([curdir, 'templates', 'gen_ar_eventhandlerfile.hpp'])
- output_fullpath = os.sep.join([output_dir, output_filename])
-
- MakoTemplateWriter.to_file(template_file, output_fullpath,
- cmdline=sys.argv,
- filename=output_filename,
- event_header='gen_ar_eventhandler.hpp',
- protos=protos)
-
- return 0
+ rval = 0
+
+ try:
+ # Generate event header
+ if args.gen_event_hpp:
+ curdir = os.path.dirname(os.path.abspath(__file__))
+ template_file = os.sep.join([curdir, 'templates', 'gen_ar_event.hpp'])
+ output_fullpath = os.sep.join([output_dir, output_filename])
+
+ MakoTemplateWriter.to_file(template_file, output_fullpath,
+ cmdline=sys.argv,
+ filename=output_filename,
+ protos=protos)
+
+ # Generate event implementation
+ if args.gen_event_cpp:
+ curdir = os.path.dirname(os.path.abspath(__file__))
+ template_file = os.sep.join([curdir, 'templates', 'gen_ar_event.cpp'])
+ output_fullpath = os.sep.join([output_dir, output_filename])
+
+ MakoTemplateWriter.to_file(template_file, output_fullpath,
+ cmdline=sys.argv,
+ filename=output_filename,
+ protos=protos)
+
+ # Generate event handler header
+ if args.gen_eventhandler_hpp:
+ curdir = os.path.dirname(os.path.abspath(__file__))
+ template_file = os.sep.join([curdir, 'templates', 'gen_ar_eventhandler.hpp'])
+ output_fullpath = os.sep.join([output_dir, output_filename])
+
+ MakoTemplateWriter.to_file(template_file, output_fullpath,
+ cmdline=sys.argv,
+ filename=output_filename,
+ event_header='gen_ar_event.hpp',
+ protos=protos)
+
+ # Generate event handler header
+ if args.gen_eventhandlerfile_hpp:
+ curdir = os.path.dirname(os.path.abspath(__file__))
+ template_file = os.sep.join([curdir, 'templates', 'gen_ar_eventhandlerfile.hpp'])
+ output_fullpath = os.sep.join([output_dir, output_filename])
+
+ MakoTemplateWriter.to_file(template_file, output_fullpath,
+ cmdline=sys.argv,
+ filename=output_filename,
+ event_header='gen_ar_eventhandler.hpp',
+ protos=protos)
+
+ rval = CopyDirFilesIfDifferent(output_dir, final_output_dir)
+
+ except:
+ rval = 1
+
+ finally:
+ DeleteDirTree(output_dir)
+
+ return rval
if __name__ == '__main__':
sys.exit(main())
diff --git a/src/gallium/drivers/swr/rasterizer/codegen/gen_backends.py b/src/gallium/drivers/swr/rasterizer/codegen/gen_backends.py
index 414a04e..2931ce8 100644
--- a/src/gallium/drivers/swr/rasterizer/codegen/gen_backends.py
+++ b/src/gallium/drivers/swr/rasterizer/codegen/gen_backends.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2017 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2017-2018 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'),
@@ -26,7 +26,7 @@ from __future__ import print_function
import itertools
import os
import sys
-from gen_common import ArgumentParser, MakoTemplateWriter
+from gen_common import *
def main(args=sys.argv[1:]):
@@ -100,46 +100,67 @@ def main(args=sys.argv[1:]):
linesPerFile = (len(output_list) + numFiles - 1) // numFiles
chunkedList = [output_list[x:x+linesPerFile] for x in range(0, len(output_list), linesPerFile)]
+ tmp_output_dir = MakeTmpDir('_codegen')
+
+ if not os.path.exists(args.outdir):
+ try:
+ os.makedirs(args.outdir)
+ except OSError as err:
+ if err.errno != errno.EEXIST:
+ print('ERROR: Could not create directory:', args.outdir, file=sys.stderr)
+ return 1
+
+ rval = 0
+
# generate .cpp files
- if args.cpp:
- baseCppName = os.path.join(args.outdir, backend.outFileName)
- templateCpp = os.path.join(thisDir, 'templates', backend.template)
+ try:
+ if args.cpp:
+ baseCppName = os.path.join(tmp_output_dir, backend.outFileName)
+ templateCpp = os.path.join(thisDir, 'templates', backend.template)
+
+ for fileNum in range(numFiles):
+ filename = baseCppName % str(fileNum)
+ MakoTemplateWriter.to_file(
+ templateCpp,
+ baseCppName % str(fileNum),
+ cmdline=sys.argv,
+ fileNum=fileNum,
+ funcList=chunkedList[fileNum])
+
+ if args.hpp:
+ baseHppName = os.path.join(tmp_output_dir, backend.outHeaderName)
+ templateHpp = os.path.join(thisDir, 'templates', backend.hpp_template)
- for fileNum in range(numFiles):
- filename = baseCppName % str(fileNum)
MakoTemplateWriter.to_file(
- templateCpp,
- baseCppName % str(fileNum),
+ templateHpp,
+ baseHppName,
cmdline=sys.argv,
- fileNum=fileNum,
- funcList=chunkedList[fileNum])
-
- if args.hpp:
- baseHppName = os.path.join(args.outdir, backend.outHeaderName)
- templateHpp = os.path.join(thisDir, 'templates', backend.hpp_template)
-
- MakoTemplateWriter.to_file(
- templateHpp,
- baseHppName,
- cmdline=sys.argv,
- numFiles=numFiles,
- filename=backend.outHeaderName,
- tableName=backend.tableName)
-
- # generate gen_backend.cmake file
- if args.cmake:
- templateCmake = os.path.join(thisDir, 'templates', 'gen_backend.cmake')
- cmakeFile = os.path.join(args.outdir, backend.cmakeFileName)
-
- MakoTemplateWriter.to_file(
- templateCmake,
- cmakeFile,
- cmdline=sys.argv,
- srcVar=backend.cmakeSrcVar,
- numFiles=numFiles,
- baseCppName='${RASTY_GEN_SRC_DIR}/backends/' + os.path.basename(baseCppName))
-
- return 0
+ numFiles=numFiles,
+ filename=backend.outHeaderName,
+ tableName=backend.tableName)
+
+ # generate gen_backend.cmake file
+ if args.cmake:
+ templateCmake = os.path.join(thisDir, 'templates', 'gen_backend.cmake')
+ cmakeFile = os.path.join(tmp_output_dir, backend.cmakeFileName)
+
+ MakoTemplateWriter.to_file(
+ templateCmake,
+ cmakeFile,
+ cmdline=sys.argv,
+ srcVar=backend.cmakeSrcVar,
+ numFiles=numFiles,
+ baseCppName='${RASTY_GEN_SRC_DIR}/backends/' + os.path.basename(baseCppName))
+
+ rval = CopyDirFilesIfDifferent(tmp_output_dir, args.outdir)
+
+ except:
+ rval = 1
+
+ finally:
+ DeleteDirTree(tmp_output_dir)
+
+ return rval
if __name__ == '__main__':
sys.exit(main())
diff --git a/src/gallium/drivers/swr/rasterizer/codegen/gen_common.py b/src/gallium/drivers/swr/rasterizer/codegen/gen_common.py
index 7f53ec6..44a0cc8 100644
--- a/src/gallium/drivers/swr/rasterizer/codegen/gen_common.py
+++ b/src/gallium/drivers/swr/rasterizer/codegen/gen_common.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2014-2018 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"),
@@ -25,9 +25,128 @@ import os
import errno
import sys
import argparse
+import tempfile
+import filecmp
+import shutil
from mako.template import Template
from mako.exceptions import RichTraceback
+#==============================================================================
+def MakeTmpDir(suffix=''):
+ '''
+ Create temporary directory for use in codegen scripts.
+ '''
+ return tempfile.mkdtemp(suffix)
+
+#==============================================================================
+def MakeDir(dir_path):
+ '''
+ Create a directory if it doesn't exist
+
+ returns 0 on success, non-zero on failure
+ '''
+ dir_path = os.path.abspath(dir_path)
+
+ if not os.path.exists(dir_path):
+ try:
+ os.makedirs(dir_path)
+ except OSError as err:
+ if err.errno != errno.EEXIST:
+ return 1
+ else:
+ if not os.path.isdir(dir_path):
+ return 1
+
+ return 0
+
+#==============================================================================
+def DeleteDirTree(dir_path):
+ '''
+ Delete directory tree.
+
+ returns 0 on success, non-zero on failure
+ '''
+ rval = 0
+ try:
+ shutil.rmtree(dir_path, False)
+ except:
+ rval = 1
+ return rval
+
+#==============================================================================
+def CopyFileIfDifferent(src, dst, verbose = False):
+ '''
+ Copy <src> file to <dst> file if the <dst>
+ file either doesn't contain the file or the file
+ contents are different.
+
+ returns 0 on success, non-zero on failure
+ '''
+
+ assert os.path.isfile(src)
+ assert (False == os.path.exists(dst) or os.path.isfile(dst))
+
+ need_copy = not os.path.exists(dst)
+ if not need_copy:
+ need_copy = not filecmp.cmp(src, dst)
+
+ if need_copy:
+ try:
+ shutil.copy2(src, dst)
+ except:
+ print('ERROR: Could not copy %s to %s' % (src, dst), file=sys.stderr)
+ return 1
+
+ if verbose:
+ print(src, '-->', dst)
+
+ return 0
+
+#==============================================================================
+def CopyDirFilesIfDifferent(src, dst, recurse = True, verbose = False, orig_dst = None):
+ '''
+ Copy files <src> directory to <dst> directory if the <dst>
+ directory either doesn't contain the file or the file
+ contents are different.
+
+ Optionally recurses into subdirectories
+
+ returns 0 on success, non-zero on failure
+ '''
+
+ assert os.path.isdir(src)
+ assert os.path.isdir(dst)
+
+ src = os.path.abspath(src)
+ dst = os.path.abspath(dst)
+
+ if not orig_dst:
+ orig_dst = dst
+
+ for f in os.listdir(src):
+ src_path = os.path.join(src, f)
+ dst_path = os.path.join(dst, f)
+
+ # prevent recursion
+ if src_path == orig_dst:
+ continue
+
+ if os.path.isdir(src_path):
+ if recurse:
+ if MakeDir(dst_path):
+ print('ERROR: Could not create directory:', dst_path, file=sys.stderr)
+ return 1
+
+ if verbose:
+ print('mkdir', dst_path)
+ rval = CopyDirFilesIfDifferent(src_path, dst_path, recurse, verbose, orig_dst)
+ else:
+ rval = CopyFileIfDifferent(src_path, dst_path, verbose)
+
+ if rval:
+ return rval
+
+ return 0
#==============================================================================
class MakoTemplateWriter:
@@ -57,20 +176,18 @@ class MakoTemplateWriter:
print('File %s, line %s, in %s' % (filename, lineno, function))
print(line, '\n')
print('%s: %s' % (str(traceback.error.__class__.__name__), traceback.error))
+ raise
@staticmethod
def to_file(template_filename, output_filename, **kwargs):
'''
Write template data to a file
'''
- if not os.path.exists(os.path.dirname(output_filename)):
- try:
- os.makedirs(os.path.dirname(output_filename))
- except OSError as err:
- if err.errno != errno.EEXIST:
- raise
+ if MakeDir(os.path.dirname(output_filename)):
+ return 1
with open(output_filename, 'w') as outfile:
print(MakoTemplateWriter.to_string(template_filename, **kwargs), file=outfile)
+ return 0
#==============================================================================
diff --git a/src/gallium/drivers/swr/rasterizer/codegen/gen_knobs.py b/src/gallium/drivers/swr/rasterizer/codegen/gen_knobs.py
index 33f62a2..7733f86 100644
--- a/src/gallium/drivers/swr/rasterizer/codegen/gen_knobs.py
+++ b/src/gallium/drivers/swr/rasterizer/codegen/gen_knobs.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2014-2018 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"),
@@ -24,7 +24,7 @@ from __future__ import print_function
import os
import sys
import knob_defs
-from gen_common import MakoTemplateWriter, ArgumentParser
+from gen_common import *
def main(args=sys.argv[1:]):
@@ -40,22 +40,39 @@ def main(args=sys.argv[1:]):
template_cpp = os.path.join(cur_dir, 'templates', 'gen_knobs.cpp')
template_h = os.path.join(cur_dir, 'templates', 'gen_knobs.h')
- if args.gen_h:
- MakoTemplateWriter.to_file(
- template_h,
- args.output,
- cmdline=sys.argv,
- filename='gen_knobs',
- knobs=knob_defs.KNOBS)
-
- if args.gen_cpp:
- MakoTemplateWriter.to_file(
- template_cpp,
- args.output,
- cmdline=sys.argv,
- filename='gen_knobs',
- knobs=knob_defs.KNOBS,
- includes=['core/knobs_init.h', 'common/os.h', 'sstream', 'iomanip'])
+ output_filename = os.path.basename(args.output)
+ output_dir = MakeTmpDir('_codegen')
+
+ output_file = os.path.join(output_dir, output_filename)
+
+ rval = 0
+
+ try:
+ if args.gen_h:
+ MakoTemplateWriter.to_file(
+ template_h,
+ output_file,
+ cmdline=sys.argv,
+ filename='gen_knobs',
+ knobs=knob_defs.KNOBS)
+
+ if args.gen_cpp:
+ MakoTemplateWriter.to_file(
+ template_cpp,
+ output_file,
+ cmdline=sys.argv,
+ filename='gen_knobs',
+ knobs=knob_defs.KNOBS,
+ includes=['core/knobs_init.h', 'common/os.h', 'sstream', 'iomanip'])
+
+ rval = CopyFileIfDifferent(output_file, args.output)
+
+ except:
+ rval = 1
+
+ finally:
+ # ignore errors from delete of tmp directory
+ DeleteDirTree(output_dir)
return 0
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 4a7d2e9..9c1e9e0 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-2017 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2014-2018 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"),
@@ -21,7 +21,7 @@
from __future__ import print_function
import os, sys, re
-from gen_common import MakoTemplateWriter, ArgumentParser
+from gen_common import *
from argparse import FileType
inst_aliases = {
@@ -312,21 +312,37 @@ def main():
if not os.path.exists(args.output):
os.makedirs(args.output)
- if args.input:
- functions = parse_ir_builder(args.input)
+ final_output_dir = args.output
+ args.output = MakeTmpDir('_codegen')
- if args.gen_h:
- generate_gen_h(functions, args.output)
+ rval = 0
+ try:
+ if args.input:
+ functions = parse_ir_builder(args.input)
- elif args.gen_h:
- print('Need to specify --input for --gen_h!')
+ if args.gen_h:
+ generate_gen_h(functions, args.output)
- if args.gen_meta_h:
- generate_meta_h(args.output)
+ elif args.gen_h:
+ print('Need to specify --input for --gen_h!')
- if args.gen_intrin_h:
- generate_intrin_h(args.output)
+ if args.gen_meta_h:
+ generate_meta_h(args.output)
+
+ if args.gen_intrin_h:
+ generate_intrin_h(args.output)
+
+ rval = CopyDirFilesIfDifferent(args.output, final_output_dir)
+
+ except:
+ print('ERROR: Could not generate llvm_ir_macros', file=sys.stderr)
+ rval = 1
+
+ finally:
+ DeleteDirTree(args.output)
+
+ return rval
if __name__ == '__main__':
- main()
+ sys.exit(main())
# END OF FILE
diff --git a/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_types.py b/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_types.py
index d8863c0..8650220 100644
--- a/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_types.py
+++ b/src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_types.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2017 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2014-2018 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"),
@@ -21,7 +21,7 @@
from __future__ import print_function
import os, sys, re
-from gen_common import MakoTemplateWriter, ArgumentParser
+from gen_common import *
from argparse import FileType
'''
@@ -333,8 +333,29 @@ def main():
help='Path to output file', required=True)
args = parser.parse_args()
- gen_llvm_types(args.input, args.output)
+ final_output_dir = os.path.dirname(args.output)
+ if MakeDir(final_output_dir):
+ return 1
+
+ final_output_file = args.output
+
+ tmp_dir = MakeTmpDir('_codegen')
+ args.output = os.path.join(tmp_dir, os.path.basename(args.output))
+
+ rval = 0
+ try:
+ gen_llvm_types(args.input, args.output)
+
+ rval = CopyFileIfDifferent(args.output, final_output_file)
+ except:
+ print('ERROR: Could not generate llvm types', file=sys.stderr)
+ rval = 1
+
+ finally:
+ DeleteDirTree(tmp_dir)
+
+ return rval
if __name__ == '__main__':
- main()
+ sys.exit(main())
# END OF FILE
--
2.7.4
More information about the mesa-dev
mailing list