# 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"),
# 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.
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_())
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_())
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_()
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))) +
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)),
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_()) +
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
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)) +
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)) +
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_()) +
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_()) +
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)) +
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_()) +
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))) +
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,
+]