summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/glsl/tests/lower_jump_cases.py (renamed from src/compiler/glsl/tests/lower_jumps/create_test_cases.py)268
-rw-r--r--src/compiler/glsl/tests/lower_jumps/.gitignore3
-rwxr-xr-xsrc/compiler/glsl/tests/optimization-test.sh87
-rwxr-xr-xsrc/compiler/glsl/tests/optimization_test.py95
4 files changed, 215 insertions, 238 deletions
diff --git a/src/compiler/glsl/tests/lower_jumps/create_test_cases.py b/src/compiler/glsl/tests/lower_jump_cases.py
index 88a74a3c4ad..b50ab734798 100644
--- a/src/compiler/glsl/tests/lower_jumps/create_test_cases.py
+++ b/src/compiler/glsl/tests/lower_jump_cases.py
@@ -1,6 +1,6 @@
# coding=utf-8
#
-# Copyright © 2011 Intel Corporation
+# Copyright © 2011, 2018 Intel Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
@@ -21,18 +21,8 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
-import argparse
-import os
-import os.path
-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
from sexps import *
-runner = ":"
-outdir = "."
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.
@@ -280,40 +270,27 @@ def bash_quote(*args):
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,
+def create_test_case(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))
-
+ expected_output = sexp_to_string(sort_decls(expected_sexp)) # XXX: don't stringify this
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 = [runner, 'optpass', '--quiet', '--input-ir', optimization]
- test_file = os.path.join(outdir, '{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 = os.path.join(outdir, '{0}.opt_test.expected'.format(test_name))
- with open(expected_file, 'w') as f:
- f.write('{0}\n'.format(expected_output))
+
+ return (test_name, optimization, input_str, expected_output)
def test_lower_returns_main():
- doc_string = """Test that do_lower_jumps respects the lower_main_return
- flag in deciding whether to lower returns in the main
- function.
+ """Test that do_lower_jumps respects the lower_main_return flag in deciding
+ whether to lower returns in the main function.
"""
input_sexp = make_test_case('main', 'void', (
complex_if('', return_())
@@ -323,14 +300,16 @@ def test_lower_returns_main():
declare_return_flag() +
complex_if('', lowered_return())
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_main_true',
- lower_main_return=True)
- create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_main_false',
- lower_main_return=False)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_returns_main_true',
+ lower_main_return=True)
+ yield create_test_case(
+ input_sexp, input_sexp, 'lower_returns_main_false',
+ lower_main_return=False)
def test_lower_returns_sub():
- doc_string = """Test that do_lower_jumps respects the lower_sub_return flag
- in deciding whether to lower returns in subroutines.
+ """Test that do_lower_jumps respects the lower_sub_return flag in deciding
+ whether to lower returns in subroutines.
"""
input_sexp = make_test_case('sub', 'void', (
complex_if('', return_())
@@ -340,15 +319,15 @@ def test_lower_returns_sub():
declare_return_flag() +
complex_if('', lowered_return())
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_sub_true',
- lower_sub_return=True)
- create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_sub_false',
- lower_sub_return=False)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_returns_sub_true',
+ lower_sub_return=True)
+ yield create_test_case(
+ input_sexp, input_sexp, 'lower_returns_sub_false',
+ lower_sub_return=False)
def test_lower_returns_1():
- doc_string = """Test that a void return at the end of a function is
- eliminated.
- """
+ """Test that a void return at the end of a function is eliminated."""
input_sexp = make_test_case('main', 'void', (
assign_x('a', const_float(1)) +
return_()
@@ -356,27 +335,26 @@ def test_lower_returns_1():
expected_sexp = make_test_case('main', 'void', (
assign_x('a', const_float(1))
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_1',
- lower_main_return=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_returns_1', lower_main_return=True)
def test_lower_returns_2():
- doc_string = """Test that lowering is not performed on a non-void return at
- the end of subroutine.
+ """Test that lowering is not performed on a non-void return at the end of
+ subroutine.
"""
input_sexp = make_test_case('sub', 'float', (
assign_x('a', const_float(1)) +
return_(const_float(1))
))
- create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_2',
- lower_sub_return=True)
+ yield create_test_case(
+ input_sexp, input_sexp, 'lower_returns_2', lower_sub_return=True)
def test_lower_returns_3():
- doc_string = """Test lowering of returns when there is one nested inside a
- complex structure of ifs, and one at the end of a function.
+ """Test lowering of returns when there is one nested inside a complex
+ structure of ifs, and one at the end of a function.
- In this case, the latter return needs to be lowered because it
- will not be at the end of the function once the final return
- is inserted.
+ In this case, the latter return needs to be lowered because it will not be
+ at the end of the function once the final return is inserted.
"""
input_sexp = make_test_case('sub', 'float', (
complex_if('', return_(const_float(1))) +
@@ -390,12 +368,12 @@ def test_lower_returns_3():
if_execute_flag(lowered_return(const_float(2))) +
final_return()
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_3',
- lower_sub_return=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_returns_3', lower_sub_return=True)
def test_lower_returns_4():
- doc_string = """Test that returns are properly lowered when they occur in
- both branches of an if-statement.
+ """Test that returns are properly lowered when they occur in both branches
+ of an if-statement.
"""
input_sexp = make_test_case('sub', 'float', (
simple_if('a', return_(const_float(1)),
@@ -409,17 +387,16 @@ def test_lower_returns_4():
lowered_return(const_float(2))) +
final_return()
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_4',
- lower_sub_return=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_returns_4', lower_sub_return=True)
def test_lower_unified_returns():
- doc_string = """If both branches of an if statement end in a return, and
- pull_out_jumps is True, then those returns should be lifted
- outside the if and then properly lowered.
+ """If both branches of an if statement end in a return, and pull_out_jumps
+ is True, then those returns should be lifted outside the if and then
+ properly lowered.
- Verify that this lowering occurs during the same pass as the
- lowering of other returns by checking that extra temporary
- variables aren't generated.
+ Verify that this lowering occurs during the same pass as the lowering of
+ other returns by checking that extra temporary variables aren't generated.
"""
input_sexp = make_test_case('main', 'void', (
complex_if('a', return_()) +
@@ -432,8 +409,9 @@ def test_lower_unified_returns():
if_execute_flag(simple_if('b', (simple_if('c', [], []) +
lowered_return())))
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_unified_returns',
- lower_main_return=True, pull_out_jumps=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_unified_returns',
+ 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
@@ -467,34 +445,38 @@ def test_lower_pulled_out_jump():
assign_x('execute_flag', const_bool(0)),
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)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_pulled_out_jump',
+ 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
- it, it should not be lowered."""
+ """If a loop contains an unconditional break at the bottom of it, it should
+ not be lowered.
+ """
input_sexp = make_test_case('main', 'void', (
loop(assign_x('a', const_float(1)) +
break_())
))
expected_sexp = input_sexp
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_1', lower_break=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_breaks_1', lower_break=True)
def test_lower_breaks_2():
- doc_string = """If a loop contains a conditional break at the bottom of it,
- it should not be lowered if it is in the then-clause.
+ """If a loop contains a conditional break at the bottom of it, it should
+ not be lowered if it is in the then-clause.
"""
input_sexp = make_test_case('main', 'void', (
loop(assign_x('a', const_float(1)) +
simple_if('b', break_()))
))
expected_sexp = input_sexp
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_2', lower_break=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_breaks_2', lower_break=True)
def test_lower_breaks_3():
- doc_string = """If a loop contains a conditional break at the bottom of it,
- it should not be lowered if it is in the then-clause, even if
- there are statements preceding the break.
+ """If a loop contains a conditional break at the bottom of it, it should
+ not be lowered if it is in the then-clause, even if there are statements
+ preceding the break.
"""
input_sexp = make_test_case('main', 'void', (
loop(assign_x('a', const_float(1)) +
@@ -502,23 +484,25 @@ 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)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_breaks_3', lower_break=True)
def test_lower_breaks_4():
- doc_string = """If a loop contains a conditional break at the bottom of it,
- it should not be lowered if it is in the else-clause.
+ """If a loop contains a conditional break at the bottom of it, it should
+ not be lowered if it is in the else-clause.
"""
input_sexp = make_test_case('main', 'void', (
loop(assign_x('a', const_float(1)) +
simple_if('b', [], break_()))
))
expected_sexp = input_sexp
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_4', lower_break=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_breaks_4', lower_break=True)
def test_lower_breaks_5():
- doc_string = """If a loop contains a conditional break at the bottom of it,
- it should not be lowered if it is in the else-clause, even if
- there are statements preceding the break.
+ """If a loop contains a conditional break at the bottom of it, it should
+ not be lowered if it is in the else-clause, even if there are statements
+ preceding the break.
"""
input_sexp = make_test_case('main', 'void', (
loop(assign_x('a', const_float(1)) +
@@ -526,13 +510,14 @@ 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)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_breaks_5', lower_break=True)
def test_lower_breaks_6():
- doc_string = """If a loop contains conditional breaks and continues, and
- ends in an unconditional break, then the unconditional break
- needs to be lowered, because it will no longer be at the end
- of the loop after the final break is added.
+ """If a loop contains conditional breaks and continues, and ends in an
+ unconditional break, then the unconditional break needs to be lowered,
+ because it will no longer be at the end of the loop after the final break
+ is added.
"""
input_sexp = make_test_case('main', 'void', (
loop(simple_if('a', (complex_if('b', continue_()) +
@@ -550,14 +535,14 @@ def test_lower_breaks_6():
if_execute_flag(lowered_break_simple()) +
final_break())
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_6',
- lower_break=True, lower_continue=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_breaks_6', 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
- lowered, however if the conditional break gets placed inside
- an if(execute_flag) because of earlier lowering of continues,
- then the break needs to be lowered.
+ """Normally a conditional break at the end of a loop isn't lowered, however
+ if the conditional break gets placed inside an if(execute_flag) because of
+ earlier lowering of continues, then the break needs to be lowered.
"""
input_sexp = make_test_case('main', 'void', (
loop(complex_if('a', continue_()) +
@@ -570,12 +555,13 @@ def test_lower_guarded_conditional_break():
if_execute_flag(simple_if('b', lowered_break())) +
final_break())
))
- create_test_case(doc_string, input_sexp, expected_sexp, 'lower_guarded_conditional_break',
- lower_break=True, lower_continue=True)
+ yield create_test_case(
+ input_sexp, expected_sexp, 'lower_guarded_conditional_break',
+ 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
- loop is removed.
+ """Test that a redundant continue-statement at the end of a loop is
+ removed.
"""
input_sexp = make_test_case('main', 'void', (
loop(assign_x('a', const_float(1)) +
@@ -584,12 +570,10 @@ 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')
+ yield create_test_case(input_sexp, expected_sexp, 'remove_continue_at_end_of_loop')
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
- lowered.
- """
+ """Test that a return of void at the end of a loop is properly lowered."""
input_sexp = make_test_case('main', 'void', (
loop(assign_x('a', const_float(1)) +
return_()) +
@@ -605,16 +589,18 @@ def test_lower_return_void_at_end_of_loop():
assign_x('execute_flag', const_bool(0)),
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, expected_sexp, 'return_void_at_end_of_loop_lower_return',
- 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)
+ yield create_test_case(
+ input_sexp, input_sexp, 'return_void_at_end_of_loop_lower_nothing')
+ yield create_test_case(
+ input_sexp, expected_sexp, 'return_void_at_end_of_loop_lower_return',
+ lower_main_return=True)
+ yield create_test_case(
+ input_sexp, expected_sexp,
+ 'return_void_at_end_of_loop_lower_return_and_break',
+ 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
- properly lowered.
- """
+ """Test that a non-void return at the end of a loop is properly lowered."""
input_sexp = make_test_case('sub', 'float', (
loop(assign_x('a', const_float(1)) +
return_(const_float(2))) +
@@ -635,39 +621,23 @@ 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, expected_sexp, 'return_non_void_at_end_of_loop_lower_return',
- 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)
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser()
- parser.add_argument('--runner',
- help='The glsl_test runner',
- required=True)
- parser.add_argument('--outdir',
- help='Directory to put the generated files in',
- required=True)
- args = parser.parse_args()
- runner = args.runner
- outdir = args.outdir
-
- test_lower_returns_main()
- test_lower_returns_sub()
- test_lower_returns_1()
- test_lower_returns_2()
- test_lower_returns_3()
- test_lower_returns_4()
- test_lower_unified_returns()
- test_lower_pulled_out_jump()
- test_lower_breaks_1()
- test_lower_breaks_2()
- test_lower_breaks_3()
- test_lower_breaks_4()
- test_lower_breaks_5()
- test_lower_breaks_6()
- test_lower_guarded_conditional_break()
- test_remove_continue_at_end_of_loop()
- test_lower_return_void_at_end_of_loop()
- test_lower_return_non_void_at_end_of_loop()
+ yield create_test_case(
+ input_sexp, input_sexp, 'return_non_void_at_end_of_loop_lower_nothing')
+ yield create_test_case(
+ input_sexp, expected_sexp,
+ 'return_non_void_at_end_of_loop_lower_return', lower_sub_return=True)
+ yield create_test_case(
+ input_sexp, expected_sexp,
+ 'return_non_void_at_end_of_loop_lower_return_and_break',
+ lower_sub_return=True, lower_break=True)
+
+CASES = [
+ test_lower_breaks_1, test_lower_breaks_2, test_lower_breaks_3,
+ test_lower_breaks_4, test_lower_breaks_5, test_lower_breaks_6,
+ test_lower_guarded_conditional_break, test_lower_pulled_out_jump,
+ test_lower_return_non_void_at_end_of_loop,
+ test_lower_return_void_at_end_of_loop,
+ test_lower_returns_1, test_lower_returns_2, test_lower_returns_3,
+ test_lower_returns_4, test_lower_returns_main, test_lower_returns_sub,
+ test_lower_unified_returns, test_remove_continue_at_end_of_loop,
+]
diff --git a/src/compiler/glsl/tests/lower_jumps/.gitignore b/src/compiler/glsl/tests/lower_jumps/.gitignore
deleted file mode 100644
index e98df627fd8..00000000000
--- a/src/compiler/glsl/tests/lower_jumps/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.opt_test
-*.expected
-*.out
diff --git a/src/compiler/glsl/tests/optimization-test.sh b/src/compiler/glsl/tests/optimization-test.sh
index e54edc7fb01..410ed262ef0 100755
--- a/src/compiler/glsl/tests/optimization-test.sh
+++ b/src/compiler/glsl/tests/optimization-test.sh
@@ -1,88 +1,3 @@
#!/bin/sh
-if [ -z "$PYTHON2" ]; then
- PYTHON2=python2
-fi
-
-which $PYTHON2 >/dev/null
-if [ $? -ne 0 ]; then
- echo "Could not find python2. Make sure that PYTHON2 variable is correctly set."
- exit 1
-fi
-
-if [ -z "$srcdir" -o -z "$abs_builddir" ]; then
- echo ""
- echo "Warning: you're invoking the script manually and things may fail."
- echo "Attempting to determine/set srcdir and abs_builddir variables."
- echo ""
-
- # Variable should point to the Makefile.glsl.am
- srcdir=./../../
- cd `dirname "$0"`
- # Variable should point to the folder two levels above glsl_test
- abs_builddir=`pwd`/../../
-fi
-
-compare_ir=$srcdir/glsl/tests/compare_ir.py
-
-total=0
-pass=0
-has_tests=0
-
-# Store our location before we start diving into subdirectories.
-ORIGDIR=`pwd`
-echo "====== Generating tests ======"
-for dir in $srcdir/glsl/tests/*/; do
- if [ -e "${dir}create_test_cases.py" ]; then
- echo "$dir"
- # construct the correct builddir
- completedir="$abs_builddir/glsl/tests/`echo ${dir} | sed 's|.*/glsl/tests/||g'`"
- mkdir -p $completedir
- cd $dir;
- $PYTHON2 create_test_cases.py --runner $abs_builddir/glsl/glsl_test --outdir $completedir;
- if [ $? -eq 0 ]; then
- has_tests=1
- fi
- cd ..
- fi
-done
-cd "$ORIGDIR"
-
-if [ $has_tests -eq 0 ]; then
- echo "Could not generate any tests."
- exit 1
-fi
-
-if [ ! -f "$compare_ir" ]; then
- echo "Could not find compare_ir. Make sure that srcdir variable is correctly set."
- exit 1
-fi
-
-echo "====== Testing optimization passes ======"
-for test in `find . -iname '*.opt_test'`; do
- echo -n "Testing `echo $test| sed 's|.*/glsl/tests/||g'`..."
- ./$test > "$test.out" 2>&1
- total=$((total+1))
- if $PYTHON2 $PYTHON_FLAGS $compare_ir "$test.expected" "$test.out" >/dev/null 2>&1; then
- echo "PASS"
- pass=$((pass+1))
- else
- echo "FAIL"
- $PYTHON2 $PYTHON_FLAGS $compare_ir "$test.expected" "$test.out"
- fi
-done
-
-if [ $total -eq 0 ]; then
- echo "Could not find any tests."
- exit 1
-fi
-
-echo ""
-echo "$pass/$total tests returned correct results"
-echo ""
-
-if [ $pass = $total ]; then
- exit 0
-else
- exit 1
-fi
+$PYTHON2 $srcdir/glsl/tests/optimization_test.py --test-runner $abs_builddir/glsl/glsl_test
diff --git a/src/compiler/glsl/tests/optimization_test.py b/src/compiler/glsl/tests/optimization_test.py
new file mode 100755
index 00000000000..577d2dfc20f
--- /dev/null
+++ b/src/compiler/glsl/tests/optimization_test.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python2
+# encoding=utf-8
+# Copyright © 2018 Intel Corporation
+
+# 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 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.
+
+"""Script to generate and run glsl optimization tests."""
+
+from __future__ import print_function
+import argparse
+import difflib
+import subprocess
+import sys
+
+import sexps
+import lower_jump_cases
+
+
+def arg_parser():
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--test-runner',
+ required=True,
+ help='The glsl_test binary.')
+ return parser.parse_args()
+
+
+def compare(actual, expected):
+ """Compare the s-expresions and return a diff if they are different."""
+ actual = sexps.sort_decls(sexps.parse_sexp(actual))
+ expected = sexps.sort_decls(sexps.parse_sexp(expected))
+
+ if actual == expected:
+ return None
+
+ actual = sexps.sexp_to_string(actual)
+ expected = sexps.sexp_to_string(expected)
+
+ return difflib.unified_diff(expected.splitlines(), actual.splitlines())
+
+
+def main():
+ """Generate each test and report pass or fail."""
+ args = arg_parser()
+
+ total = 0
+ passes = 0
+
+ for gen in lower_jump_cases.CASES:
+ for name, opt, source, expected in gen():
+ total += 1
+ print('{}: '.format(name), end='')
+ proc = subprocess.Popen(
+ [args.test_runner, 'optpass', '--quiet', '--input-ir', opt],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE)
+ out, err = proc.communicate(source)
+ if err:
+ print('FAIL')
+ print('Unexpected output on stderr: {}'.format(err),
+ file=sys.stdout)
+ continue
+
+ result = compare(out, expected)
+ if result is not None:
+ print('FAIL')
+ for l in result:
+ print(l, file=sys.stderr)
+ else:
+ print('PASS')
+ passes += 1
+
+ print('{}/{} tests returned correct results'.format(passes, total))
+ exit(0 if passes == total else 1)
+
+
+if __name__ == '__main__':
+ main()