[Mesa-dev] [PATCH 3/9] glsl: Refactor the python test case generator
Dylan Baker
baker.dylan.c at gmail.com
Tue Aug 12 15:51:37 PDT 2014
On Tuesday, July 29, 2014 12:36:33 PM Petri Latvala wrote:
> Move the IR sexp builder helpers and test script creation parts of
> tests/lower_jumps/create_test_cases.py into tests/test_case_generator.py
>
> No functional changes.
>
> Signed-off-by: Petri Latvala <petri.latvala at intel.com>
> ---
> src/glsl/tests/lower_jumps/create_test_cases.py | 336 +++---------------------
> src/glsl/tests/test_case_generator.py | 293 +++++++++++++++++++++
> 2 files changed, 334 insertions(+), 295 deletions(-)
> create mode 100644 src/glsl/tests/test_case_generator.py
>
> diff --git a/src/glsl/tests/lower_jumps/create_test_cases.py b/src/glsl/tests/lower_jumps/create_test_cases.py
> index 3be1079..9783627 100644
> --- a/src/glsl/tests/lower_jumps/create_test_cases.py
> +++ b/src/glsl/tests/lower_jumps/create_test_cases.py
> @@ -27,278 +27,9 @@ import re
> import subprocess
> import sys
>
> -sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) # For access to sexps.py, which is in parent dir
> +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) # For access to sexps.py and test_case_generator.py, which are in parent dir
> from sexps import *
> -
> -def make_test_case(f_name, ret_type, body):
> - """Create a simple optimization test case consisting of a single
> - function with the given name, return type, and body.
> -
> - Global declarations are automatically created for any undeclared
> - variables that are referenced by the function. All undeclared
> - variables are assumed to be floats.
> - """
> - check_sexp(body)
> - declarations = {}
> - def make_declarations(sexp, already_declared = ()):
> - if isinstance(sexp, list):
> - if len(sexp) == 2 and sexp[0] == 'var_ref':
> - if sexp[1] not in already_declared:
> - declarations[sexp[1]] = [
> - 'declare', ['in'], 'float', sexp[1]]
> - elif len(sexp) == 4 and sexp[0] == 'assign':
> - assert sexp[2][0] == 'var_ref'
> - if sexp[2][1] not in already_declared:
> - declarations[sexp[2][1]] = [
> - 'declare', ['out'], 'float', sexp[2][1]]
> - make_declarations(sexp[3], already_declared)
> - else:
> - already_declared = set(already_declared)
> - for s in sexp:
> - if isinstance(s, list) and len(s) >= 4 and \
> - s[0] == 'declare':
> - already_declared.add(s[3])
> - else:
> - make_declarations(s, already_declared)
> - make_declarations(body)
> - return declarations.values() + \
> - [['function', f_name, ['signature', ret_type, ['parameters'], body]]]
> -
> -
> -# The following functions can be used to build expressions.
> -
> -def const_float(value):
> - """Create an expression representing the given floating point value."""
> - return ['constant', 'float', ['{0:.6f}'.format(value)]]
> -
> -def const_bool(value):
> - """Create an expression representing the given boolean value.
> -
> - If value is not a boolean, it is converted to a boolean. So, for
> - instance, const_bool(1) is equivalent to const_bool(True).
> - """
> - return ['constant', 'bool', ['{0}'.format(1 if value else 0)]]
> -
> -def gt_zero(var_name):
> - """Create Construct the expression var_name > 0"""
> - return ['expression', 'bool', '>', ['var_ref', var_name], const_float(0)]
> -
> -
> -# The following functions can be used to build complex control flow
> -# statements. All of these functions return statement lists (even
> -# those which only create a single statement), so that statements can
> -# be sequenced together using the '+' operator.
> -
> -def return_(value = None):
> - """Create a return statement."""
> - if value is not None:
> - return [['return', value]]
> - else:
> - return [['return']]
> -
> -def break_():
> - """Create a break statement."""
> - return ['break']
> -
> -def continue_():
> - """Create a continue statement."""
> - return ['continue']
> -
> -def simple_if(var_name, then_statements, else_statements = None):
> - """Create a statement of the form
> -
> - if (var_name > 0.0) {
> - <then_statements>
> - } else {
> - <else_statements>
> - }
> -
> - else_statements may be omitted.
> - """
> - if else_statements is None:
> - else_statements = []
> - check_sexp(then_statements)
> - check_sexp(else_statements)
> - return [['if', gt_zero(var_name), then_statements, else_statements]]
> -
> -def loop(statements):
> - """Create a loop containing the given statements as its loop
> - body.
> - """
> - check_sexp(statements)
> - return [['loop', statements]]
> -
> -def declare_temp(var_type, var_name):
> - """Create a declaration of the form
> -
> - (declare (temporary) <var_type> <var_name)
> - """
> - return [['declare', ['temporary'], var_type, var_name]]
> -
> -def assign_x(var_name, value):
> - """Create a statement that assigns <value> to the variable
> - <var_name>. The assignment uses the mask (x).
> - """
> - check_sexp(value)
> - return [['assign', ['x'], ['var_ref', var_name], value]]
> -
> -def complex_if(var_prefix, statements):
> - """Create a statement of the form
> -
> - if (<var_prefix>a > 0.0) {
> - if (<var_prefix>b > 0.0) {
> - <statements>
> - }
> - }
> -
> - This is useful in testing jump lowering, because if <statements>
> - ends in a jump, lower_jumps.cpp won't try to combine this
> - construct with the code that follows it, as it might do for a
> - simple if.
> -
> - All variables used in the if statement are prefixed with
> - var_prefix. This can be used to ensure uniqueness.
> - """
> - check_sexp(statements)
> - return simple_if(var_prefix + 'a', simple_if(var_prefix + 'b', statements))
> -
> -def declare_execute_flag():
> - """Create the statements that lower_jumps.cpp uses to declare and
> - initialize the temporary boolean execute_flag.
> - """
> - return declare_temp('bool', 'execute_flag') + \
> - assign_x('execute_flag', const_bool(True))
> -
> -def declare_return_flag():
> - """Create the statements that lower_jumps.cpp uses to declare and
> - initialize the temporary boolean return_flag.
> - """
> - return declare_temp('bool', 'return_flag') + \
> - assign_x('return_flag', const_bool(False))
> -
> -def declare_return_value():
> - """Create the statements that lower_jumps.cpp uses to declare and
> - initialize the temporary variable return_value. Assume that
> - return_value is a float.
> - """
> - return declare_temp('float', 'return_value')
> -
> -def declare_break_flag():
> - """Create the statements that lower_jumps.cpp uses to declare and
> - initialize the temporary boolean break_flag.
> - """
> - return declare_temp('bool', 'break_flag') + \
> - assign_x('break_flag', const_bool(False))
> -
> -def lowered_return_simple(value = None):
> - """Create the statements that lower_jumps.cpp lowers a return
> - statement to, in situations where it does not need to clear the
> - execute flag.
> - """
> - if value:
> - result = assign_x('return_value', value)
> - else:
> - result = []
> - return result + assign_x('return_flag', const_bool(True))
> -
> -def lowered_return(value = None):
> - """Create the statements that lower_jumps.cpp lowers a return
> - statement to, in situations where it needs to clear the execute
> - flag.
> - """
> - return lowered_return_simple(value) + \
> - assign_x('execute_flag', const_bool(False))
> -
> -def lowered_continue():
> - """Create the statement that lower_jumps.cpp lowers a continue
> - statement to.
> - """
> - return assign_x('execute_flag', const_bool(False))
> -
> -def lowered_break_simple():
> - """Create the statement that lower_jumps.cpp lowers a break
> - statement to, in situations where it does not need to clear the
> - execute flag.
> - """
> - return assign_x('break_flag', const_bool(True))
> -
> -def lowered_break():
> - """Create the statement that lower_jumps.cpp lowers a break
> - statement to, in situations where it needs to clear the execute
> - flag.
> - """
> - return lowered_break_simple() + assign_x('execute_flag', const_bool(False))
> -
> -def if_execute_flag(statements):
> - """Wrap statements in an if test so that they will only execute if
> - execute_flag is True.
> - """
> - check_sexp(statements)
> - return [['if', ['var_ref', 'execute_flag'], statements, []]]
> -
> -def if_not_return_flag(statements):
> - """Wrap statements in an if test so that they will only execute if
> - return_flag is False.
> - """
> - check_sexp(statements)
> - return [['if', ['var_ref', 'return_flag'], [], statements]]
> -
> -def final_return():
> - """Create the return statement that lower_jumps.cpp places at the
> - end of a function when lowering returns.
> - """
> - return [['return', ['var_ref', 'return_value']]]
> -
> -def final_break():
> - """Create the conditional break statement that lower_jumps.cpp
> - places at the end of a function when lowering breaks.
> - """
> - return [['if', ['var_ref', 'break_flag'], break_(), []]]
> -
> -def bash_quote(*args):
> - """Quote the arguments appropriately so that bash will understand
> - each argument as a single word.
> - """
> - def quote_word(word):
> - for c in word:
> - if not (c.isalpha() or c.isdigit() or c in '@%_-+=:,./'):
> - break
> - else:
> - if not word:
> - return "''"
> - return word
> - return "'{0}'".format(word.replace("'", "'\"'\"'"))
> - return ' '.join(quote_word(word) for word in args)
> -
> -def create_test_case(doc_string, input_sexp, expected_sexp, test_name,
> - pull_out_jumps=False, lower_sub_return=False,
> - lower_main_return=False, lower_continue=False,
> - lower_break=False):
> - """Create a test case that verifies that do_lower_jumps transforms
> - the given code in the expected way.
> - """
> - doc_lines = [line.strip() for line in doc_string.splitlines()]
> - doc_string = ''.join('# {0}\n'.format(line) for line in doc_lines if line != '')
> - check_sexp(input_sexp)
> - check_sexp(expected_sexp)
> - input_str = sexp_to_string(sort_decls(input_sexp))
> - expected_output = sexp_to_string(sort_decls(expected_sexp))
> -
> - optimization = (
> - 'do_lower_jumps({0:d}, {1:d}, {2:d}, {3:d}, {4:d})'.format(
> - pull_out_jumps, lower_sub_return, lower_main_return,
> - lower_continue, lower_break))
> - args = ['../../glsl_test', 'optpass', '--quiet', '--input-ir', optimization]
> - test_file = '{0}.opt_test'.format(test_name)
> - with open(test_file, 'w') as f:
> - f.write('#!/usr/bin/env bash\n#\n# This file was generated by create_test_cases.py.\n#\n')
> - f.write(doc_string)
> - f.write('{0} <<EOF\n'.format(bash_quote(*args)))
> - f.write('{0}\nEOF\n'.format(input_str))
> - os.chmod(test_file, 0774)
> - expected_file = '{0}.opt_test.expected'.format(test_name)
> - with open(expected_file, 'w') as f:
> - f.write('{0}\n'.format(expected_output))
> +from test_case_generator import *
>
> def test_lower_returns_main():
> doc_string = """Test that do_lower_jumps respects the lower_main_return
> @@ -314,9 +45,9 @@ def test_lower_returns_main():
> complex_if('', lowered_return())
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_main_true',
> - lower_main_return=True)
> + create_opt_string(lower_main_return=True))
> create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_main_false',
> - lower_main_return=False)
> + create_opt_string(lower_main_return=False))
>
> def test_lower_returns_sub():
> doc_string = """Test that do_lower_jumps respects the lower_sub_return flag
> @@ -331,9 +62,9 @@ def test_lower_returns_sub():
> complex_if('', lowered_return())
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_sub_true',
> - lower_sub_return=True)
> + create_opt_string(lower_sub_return=True))
> create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_sub_false',
> - lower_sub_return=False)
> + create_opt_string(lower_sub_return=False))
>
> def test_lower_returns_1():
> doc_string = """Test that a void return at the end of a function is
> @@ -347,7 +78,7 @@ def test_lower_returns_1():
> assign_x('a', const_float(1))
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_1',
> - lower_main_return=True)
> + create_opt_string(lower_main_return=True))
>
> def test_lower_returns_2():
> doc_string = """Test that lowering is not performed on a non-void return at
> @@ -358,7 +89,7 @@ def test_lower_returns_2():
> return_(const_float(1))
> ))
> create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_2',
> - lower_sub_return=True)
> + create_opt_string(lower_sub_return=True))
>
> def test_lower_returns_3():
> doc_string = """Test lowering of returns when there is one nested inside a
> @@ -381,7 +112,7 @@ def test_lower_returns_3():
> final_return()
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_3',
> - lower_sub_return=True)
> + create_opt_string(lower_sub_return=True))
>
> def test_lower_returns_4():
> doc_string = """Test that returns are properly lowered when they occur in
> @@ -400,7 +131,7 @@ def test_lower_returns_4():
> final_return()
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_4',
> - lower_sub_return=True)
> + create_opt_string(lower_sub_return=True))
>
> def test_lower_unified_returns():
> doc_string = """If both branches of an if statement end in a return, and
> @@ -423,7 +154,7 @@ def test_lower_unified_returns():
> lowered_return())))
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_unified_returns',
> - lower_main_return=True, pull_out_jumps=True)
> + create_opt_string(lower_main_return=True, pull_out_jumps=True))
>
> def test_lower_pulled_out_jump():
> doc_string = """If one branch of an if ends in a jump, and control cannot
> @@ -455,7 +186,7 @@ def test_lower_pulled_out_jump():
> if_not_return_flag(assign_x('d', const_float(1))))
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_pulled_out_jump',
> - lower_main_return=True, pull_out_jumps=True)
> + create_opt_string(lower_main_return=True, pull_out_jumps=True))
>
> def test_lower_breaks_1():
> doc_string = """If a loop contains an unconditional break at the bottom of
> @@ -465,7 +196,8 @@ def test_lower_breaks_1():
> break_())
> ))
> expected_sexp = input_sexp
> - create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_1', lower_break=True)
> + create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_1',
> + create_opt_string(lower_break=True))
>
> def test_lower_breaks_2():
> doc_string = """If a loop contains a conditional break at the bottom of it,
> @@ -476,7 +208,8 @@ def test_lower_breaks_2():
> simple_if('b', break_()))
> ))
> expected_sexp = input_sexp
> - create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_2', lower_break=True)
> + create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_2',
> + create_opt_string(lower_break=True))
>
> def test_lower_breaks_3():
> doc_string = """If a loop contains a conditional break at the bottom of it,
> @@ -489,7 +222,8 @@ def test_lower_breaks_3():
> break_())))
> ))
> expected_sexp = input_sexp
> - create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_3', lower_break=True)
> + create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_3',
> + create_opt_string(lower_break=True))
>
> def test_lower_breaks_4():
> doc_string = """If a loop contains a conditional break at the bottom of it,
> @@ -500,7 +234,8 @@ def test_lower_breaks_4():
> simple_if('b', [], break_()))
> ))
> expected_sexp = input_sexp
> - create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_4', lower_break=True)
> + create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_4',
> + create_opt_string(lower_break=True))
>
> def test_lower_breaks_5():
> doc_string = """If a loop contains a conditional break at the bottom of it,
> @@ -513,7 +248,8 @@ def test_lower_breaks_5():
> break_())))
> ))
> expected_sexp = input_sexp
> - create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_5', lower_break=True)
> + create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_5',
> + create_opt_string(lower_break=True))
>
> def test_lower_breaks_6():
> doc_string = """If a loop contains conditional breaks and continues, and
> @@ -538,7 +274,7 @@ def test_lower_breaks_6():
> final_break())
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_6',
> - lower_break=True, lower_continue=True)
> + create_opt_string(lower_break=True, lower_continue=True))
>
> def test_lower_guarded_conditional_break():
> doc_string = """Normally a conditional break at the end of a loop isn't
> @@ -558,7 +294,7 @@ def test_lower_guarded_conditional_break():
> final_break())
> ))
> create_test_case(doc_string, input_sexp, expected_sexp, 'lower_guarded_conditional_break',
> - lower_break=True, lower_continue=True)
> + create_opt_string(lower_break=True, lower_continue=True))
>
> def test_remove_continue_at_end_of_loop():
> doc_string = """Test that a redundant continue-statement at the end of a
> @@ -571,7 +307,8 @@ def test_remove_continue_at_end_of_loop():
> expected_sexp = make_test_case('main', 'void', (
> loop(assign_x('a', const_float(1)))
> ))
> - create_test_case(doc_string, input_sexp, expected_sexp, 'remove_continue_at_end_of_loop')
> + create_test_case(doc_string, input_sexp, expected_sexp, 'remove_continue_at_end_of_loop',
> + create_opt_string())
>
> def test_lower_return_void_at_end_of_loop():
> doc_string = """Test that a return of void at the end of a loop is properly
> @@ -589,11 +326,12 @@ def test_lower_return_void_at_end_of_loop():
> break_()) +
> if_not_return_flag(assign_x('b', const_float(2)))
> ))
> - create_test_case(doc_string, input_sexp, input_sexp, 'return_void_at_end_of_loop_lower_nothing')
> + create_test_case(doc_string, input_sexp, input_sexp, 'return_void_at_end_of_loop_lower_nothing',
> + create_opt_string())
> create_test_case(doc_string, input_sexp, expected_sexp, 'return_void_at_end_of_loop_lower_return',
> - lower_main_return=True)
> + create_opt_string(lower_main_return=True))
> create_test_case(doc_string, input_sexp, expected_sexp, 'return_void_at_end_of_loop_lower_return_and_break',
> - lower_main_return=True, lower_break=True)
> + create_opt_string(lower_main_return=True, lower_break=True))
>
> def test_lower_return_non_void_at_end_of_loop():
> doc_string = """Test that a non-void return at the end of a loop is
> @@ -616,11 +354,19 @@ def test_lower_return_non_void_at_end_of_loop():
> lowered_return(const_float(4))) +
> final_return()
> ))
> - create_test_case(doc_string, input_sexp, input_sexp, 'return_non_void_at_end_of_loop_lower_nothing')
> + create_test_case(doc_string, input_sexp, input_sexp, 'return_non_void_at_end_of_loop_lower_nothing',
> + create_opt_string())
> create_test_case(doc_string, input_sexp, expected_sexp, 'return_non_void_at_end_of_loop_lower_return',
> - lower_sub_return=True)
> + create_opt_string(lower_sub_return=True))
> create_test_case(doc_string, input_sexp, expected_sexp, 'return_non_void_at_end_of_loop_lower_return_and_break',
> - lower_sub_return=True, lower_break=True)
> + create_opt_string(lower_sub_return=True, lower_break=True))
> +
> +def create_opt_string(pull_out_jumps=False, lower_sub_return=False,
> + lower_main_return=False, lower_continue=False,
> + lower_break=False):
> + return ('do_lower_jumps({0:d}, {1:d}, {2:d}, {3:d}, {4:d})'.format(
> + pull_out_jumps, lower_sub_return, lower_main_return,
> + lower_continue, lower_break))
>
> if __name__ == '__main__':
> test_lower_returns_main()
> diff --git a/src/glsl/tests/test_case_generator.py b/src/glsl/tests/test_case_generator.py
> new file mode 100644
> index 0000000..d6754fc8
> --- /dev/null
> +++ b/src/glsl/tests/test_case_generator.py
> @@ -0,0 +1,293 @@
> +# coding=utf-8
> +#
> +# Copyright © 2011 Intel Corporation
2014?
> +#
> +# 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.
> +
> +import os
> +import os.path
> +import re
> +import subprocess
> +import sys
> +
> +from sexps import *
> +
> +def make_test_case(f_name, ret_type, body):
> + """Create a simple optimization test case consisting of a single
> + function with the given name, return type, and body.
> +
> + Global declarations are automatically created for any undeclared
> + variables that are referenced by the function. All undeclared
> + variables are assumed to be floats.
> + """
> + check_sexp(body)
> + declarations = {}
> + def make_declarations(sexp, already_declared = ()):
> + if isinstance(sexp, list):
> + if len(sexp) == 2 and sexp[0] == 'var_ref':
> + if sexp[1] not in already_declared:
> + declarations[sexp[1]] = [
> + 'declare', ['in'], 'float', sexp[1]]
> + elif len(sexp) == 4 and sexp[0] == 'assign':
> + assert sexp[2][0] == 'var_ref'
> + if sexp[2][1] not in already_declared:
> + declarations[sexp[2][1]] = [
> + 'declare', ['out'], 'float', sexp[2][1]]
> + make_declarations(sexp[3], already_declared)
> + else:
> + already_declared = set(already_declared)
> + for s in sexp:
> + if isinstance(s, list) and len(s) >= 4 and \
> + s[0] == 'declare':
> + already_declared.add(s[3])
> + else:
> + make_declarations(s, already_declared)
> + make_declarations(body)
> + return declarations.values() + \
> + [['function', f_name, ['signature', ret_type, ['parameters'], body]]]
> +
> +
> +# The following functions can be used to build expressions.
> +
> +def const_float(value):
> + """Create an expression representing the given floating point value."""
> + return ['constant', 'float', ['{0:.6f}'.format(value)]]
> +
> +def const_bool(value):
> + """Create an expression representing the given boolean value.
> +
> + If value is not a boolean, it is converted to a boolean. So, for
> + instance, const_bool(1) is equivalent to const_bool(True).
> + """
> + return ['constant', 'bool', ['{0}'.format(1 if value else 0)]]
> +
> +def gt_zero(var_name):
> + """Create Construct the expression var_name > 0"""
> + return ['expression', 'bool', '>', ['var_ref', var_name], const_float(0)]
> +
> +
> +# The following functions can be used to build complex control flow
> +# statements. All of these functions return statement lists (even
> +# those which only create a single statement), so that statements can
> +# be sequenced together using the '+' operator.
> +
> +def return_(value = None):
> + """Create a return statement."""
> + if value is not None:
> + return [['return', value]]
> + else:
> + return [['return']]
> +
> +def break_():
> + """Create a break statement."""
> + return ['break']
> +
> +def continue_():
> + """Create a continue statement."""
> + return ['continue']
> +
> +def simple_if(var_name, then_statements, else_statements = None):
> + """Create a statement of the form
> +
> + if (var_name > 0.0) {
> + <then_statements>
> + } else {
> + <else_statements>
> + }
> +
> + else_statements may be omitted.
> + """
> + if else_statements is None:
> + else_statements = []
> + check_sexp(then_statements)
> + check_sexp(else_statements)
> + return [['if', gt_zero(var_name), then_statements, else_statements]]
> +
> +def loop(statements):
> + """Create a loop containing the given statements as its loop
> + body.
> + """
> + check_sexp(statements)
> + return [['loop', statements]]
This whole file is incredibly hard to read, could you make some
formating changes?
Block docstrings should be formatted like follows:
"""My docstring
This is a description of the function or class
"""
do_something()
Note the extra blank space, this improves readability a lot
> +
> +def declare_temp(var_type, var_name):
> + """Create a declaration of the form
> +
> + (declare (temporary) <var_type> <var_name)
> + """
> + return [['declare', ['temporary'], var_type, var_name]]
> +
> +def assign_x(var_name, value):
> + """Create a statement that assigns <value> to the variable
> + <var_name>. The assignment uses the mask (x).
> + """
> + check_sexp(value)
> + return [['assign', ['x'], ['var_ref', var_name], value]]
> +
> +def complex_if(var_prefix, statements):
> + """Create a statement of the form
> +
> + if (<var_prefix>a > 0.0) {
> + if (<var_prefix>b > 0.0) {
> + <statements>
> + }
> + }
> +
> + This is useful in testing jump lowering, because if <statements>
> + ends in a jump, lower_jumps.cpp won't try to combine this
> + construct with the code that follows it, as it might do for a
> + simple if.
> +
> + All variables used in the if statement are prefixed with
> + var_prefix. This can be used to ensure uniqueness.
> + """
> + check_sexp(statements)
> + return simple_if(var_prefix + 'a', simple_if(var_prefix + 'b', statements))
> +
> +def declare_execute_flag():
> + """Create the statements that lower_jumps.cpp uses to declare and
> + initialize the temporary boolean execute_flag.
> + """
> + return declare_temp('bool', 'execute_flag') + \
> + assign_x('execute_flag', const_bool(True))
> +
> +def declare_return_flag():
> + """Create the statements that lower_jumps.cpp uses to declare and
> + initialize the temporary boolean return_flag.
> + """
> + return declare_temp('bool', 'return_flag') + \
> + assign_x('return_flag', const_bool(False))
> +
> +def declare_return_value():
> + """Create the statements that lower_jumps.cpp uses to declare and
> + initialize the temporary variable return_value. Assume that
> + return_value is a float.
> + """
> + return declare_temp('float', 'return_value')
> +
> +def declare_break_flag():
> + """Create the statements that lower_jumps.cpp uses to declare and
> + initialize the temporary boolean break_flag.
> + """
> + return declare_temp('bool', 'break_flag') + \
> + assign_x('break_flag', const_bool(False))
> +
> +def lowered_return_simple(value = None):
> + """Create the statements that lower_jumps.cpp lowers a return
> + statement to, in situations where it does not need to clear the
> + execute flag.
> + """
> + if value:
> + result = assign_x('return_value', value)
> + else:
> + result = []
> + return result + assign_x('return_flag', const_bool(True))
> +
> +def lowered_return(value = None):
> + """Create the statements that lower_jumps.cpp lowers a return
> + statement to, in situations where it needs to clear the execute
> + flag.
> + """
> + return lowered_return_simple(value) + \
> + assign_x('execute_flag', const_bool(False))
> +
> +def lowered_continue():
> + """Create the statement that lower_jumps.cpp lowers a continue
> + statement to.
> + """
> + return assign_x('execute_flag', const_bool(False))
> +
> +def lowered_break_simple():
> + """Create the statement that lower_jumps.cpp lowers a break
> + statement to, in situations where it does not need to clear the
> + execute flag.
> + """
> + return assign_x('break_flag', const_bool(True))
> +
> +def lowered_break():
> + """Create the statement that lower_jumps.cpp lowers a break
> + statement to, in situations where it needs to clear the execute
> + flag.
> + """
> + return lowered_break_simple() + assign_x('execute_flag', const_bool(False))
> +
> +def if_execute_flag(statements):
> + """Wrap statements in an if test so that they will only execute if
> + execute_flag is True.
> + """
> + check_sexp(statements)
> + return [['if', ['var_ref', 'execute_flag'], statements, []]]
> +
> +def if_not_return_flag(statements):
> + """Wrap statements in an if test so that they will only execute if
> + return_flag is False.
> + """
> + check_sexp(statements)
> + return [['if', ['var_ref', 'return_flag'], [], statements]]
> +
> +def final_return():
> + """Create the return statement that lower_jumps.cpp places at the
> + end of a function when lowering returns.
> + """
> + return [['return', ['var_ref', 'return_value']]]
> +
> +def final_break():
> + """Create the conditional break statement that lower_jumps.cpp
> + places at the end of a function when lowering breaks.
> + """
> + return [['if', ['var_ref', 'break_flag'], break_(), []]]
> +
> +def bash_quote(*args):
> + """Quote the arguments appropriately so that bash will understand
> + each argument as a single word.
> + """
> + def quote_word(word):
What exactly are you looking to do here? You might have a look at
shlex.split(), I think it will do what you want. something like:
shlex.split(''.join(args)).
> + for c in word:
> + if not (c.isalpha() or c.isdigit() or c in '@%_-+=:,./'):
> + break
> + else:
> + if not word:
> + return "''"
> + return word
> + return "'{0}'".format(word.replace("'", "'\"'\"'"))
feel free to ad a blank line here, it makes this much easier to read
> + return ' '.join(quote_word(word) for word in args)
> +
> +def create_test_case(doc_string, input_sexp, expected_sexp, test_name, optimization):
> + """Create a test case that verifies that the given optimization pass transforms
> + the given code in the expected way.
> + """
> + doc_lines = [line.strip() for line in doc_string.splitlines()]
> + doc_string = ''.join('# {0}\n'.format(line) for line in doc_lines if line != '')
> + check_sexp(input_sexp)
> + check_sexp(expected_sexp)
> + input_str = sexp_to_string(sort_decls(input_sexp))
> + expected_output = sexp_to_string(sort_decls(expected_sexp))
> +
> + args = ['../../glsl_test', 'optpass', '--quiet', '--input-ir', optimization]
> + test_file = '{0}.opt_test'.format(test_name)
> + with open(test_file, 'w') as f:
> + f.write('#!/usr/bin/env bash\n#\n# This file was automatically generated.\n#\n')
> + f.write(doc_string)
> + f.write('{0} <<EOF\n'.format(bash_quote(*args)))
> + f.write('{0}\nEOF\n'.format(input_str))
> + os.chmod(test_file, 0774)
> + expected_file = '{0}.opt_test.expected'.format(test_name)
> + with open(expected_file, 'w') as f:
> + f.write('{0}\n'.format(expected_output))
> --
> 2.0.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140812/8cc9f105/attachment-0001.sig>
More information about the mesa-dev
mailing list