1# coding=utf-8
2#
3# Copyright © 2011 Intel Corporation
4#
5# Permission is hereby granted, free of charge, to any person obtaining a
6# copy of this software and associated documentation files (the "Software"),
7# to deal in the Software without restriction, including without limitation
8# the rights to use, copy, modify, merge, publish, distribute, sublicense,
9# and/or sell copies of the Software, and to permit persons to whom the
10# Software is furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice (including the next
13# paragraph) shall be included in all copies or substantial portions of the
14# Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22# DEALINGS IN THE SOFTWARE.
23
24import argparse
25import os
26import os.path
27import re
28import subprocess
29import sys
30
31sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) # For access to sexps.py, which is in parent dir
32from sexps import *
33
34runner = ":"
35outdir = "."
36def make_test_case(f_name, ret_type, body):
37    """Create a simple optimization test case consisting of a single
38    function with the given name, return type, and body.
39
40    Global declarations are automatically created for any undeclared
41    variables that are referenced by the function.  All undeclared
42    variables are assumed to be floats.
43    """
44    check_sexp(body)
45    declarations = {}
46    def make_declarations(sexp, already_declared = ()):
47        if isinstance(sexp, list):
48            if len(sexp) == 2 and sexp[0] == 'var_ref':
49                if sexp[1] not in already_declared:
50                    declarations[sexp[1]] = [
51                        'declare', ['in'], 'float', sexp[1]]
52            elif len(sexp) == 4 and sexp[0] == 'assign':
53                assert sexp[2][0] == 'var_ref'
54                if sexp[2][1] not in already_declared:
55                    declarations[sexp[2][1]] = [
56                        'declare', ['out'], 'float', sexp[2][1]]
57                make_declarations(sexp[3], already_declared)
58            else:
59                already_declared = set(already_declared)
60                for s in sexp:
61                    if isinstance(s, list) and len(s) >= 4 and \
62                            s[0] == 'declare':
63                        already_declared.add(s[3])
64                    else:
65                        make_declarations(s, already_declared)
66    make_declarations(body)
67    return declarations.values() + \
68        [['function', f_name, ['signature', ret_type, ['parameters'], body]]]
69
70
71# The following functions can be used to build expressions.
72
73def const_float(value):
74    """Create an expression representing the given floating point value."""
75    return ['constant', 'float', ['{0:.6f}'.format(value)]]
76
77def const_bool(value):
78    """Create an expression representing the given boolean value.
79
80    If value is not a boolean, it is converted to a boolean.  So, for
81    instance, const_bool(1) is equivalent to const_bool(True).
82    """
83    return ['constant', 'bool', ['{0}'.format(1 if value else 0)]]
84
85def gt_zero(var_name):
86    """Create Construct the expression var_name > 0"""
87    return ['expression', 'bool', '<', const_float(0), ['var_ref', var_name]]
88
89
90# The following functions can be used to build complex control flow
91# statements.  All of these functions return statement lists (even
92# those which only create a single statement), so that statements can
93# be sequenced together using the '+' operator.
94
95def return_(value = None):
96    """Create a return statement."""
97    if value is not None:
98        return [['return', value]]
99    else:
100        return [['return']]
101
102def break_():
103    """Create a break statement."""
104    return ['break']
105
106def continue_():
107    """Create a continue statement."""
108    return ['continue']
109
110def simple_if(var_name, then_statements, else_statements = None):
111    """Create a statement of the form
112
113    if (var_name > 0.0) {
114       <then_statements>
115    } else {
116       <else_statements>
117    }
118
119    else_statements may be omitted.
120    """
121    if else_statements is None:
122        else_statements = []
123    check_sexp(then_statements)
124    check_sexp(else_statements)
125    return [['if', gt_zero(var_name), then_statements, else_statements]]
126
127def loop(statements):
128    """Create a loop containing the given statements as its loop
129    body.
130    """
131    check_sexp(statements)
132    return [['loop', statements]]
133
134def declare_temp(var_type, var_name):
135    """Create a declaration of the form
136
137    (declare (temporary) <var_type> <var_name)
138    """
139    return [['declare', ['temporary'], var_type, var_name]]
140
141def assign_x(var_name, value):
142    """Create a statement that assigns <value> to the variable
143    <var_name>.  The assignment uses the mask (x).
144    """
145    check_sexp(value)
146    return [['assign', ['x'], ['var_ref', var_name], value]]
147
148def complex_if(var_prefix, statements):
149    """Create a statement of the form
150
151    if (<var_prefix>a > 0.0) {
152       if (<var_prefix>b > 0.0) {
153          <statements>
154       }
155    }
156
157    This is useful in testing jump lowering, because if <statements>
158    ends in a jump, lower_jumps.cpp won't try to combine this
159    construct with the code that follows it, as it might do for a
160    simple if.
161
162    All variables used in the if statement are prefixed with
163    var_prefix.  This can be used to ensure uniqueness.
164    """
165    check_sexp(statements)
166    return simple_if(var_prefix + 'a', simple_if(var_prefix + 'b', statements))
167
168def declare_execute_flag():
169    """Create the statements that lower_jumps.cpp uses to declare and
170    initialize the temporary boolean execute_flag.
171    """
172    return declare_temp('bool', 'execute_flag') + \
173        assign_x('execute_flag', const_bool(True))
174
175def declare_return_flag():
176    """Create the statements that lower_jumps.cpp uses to declare and
177    initialize the temporary boolean return_flag.
178    """
179    return declare_temp('bool', 'return_flag') + \
180        assign_x('return_flag', const_bool(False))
181
182def declare_return_value():
183    """Create the statements that lower_jumps.cpp uses to declare and
184    initialize the temporary variable return_value.  Assume that
185    return_value is a float.
186    """
187    return declare_temp('float', 'return_value')
188
189def declare_break_flag():
190    """Create the statements that lower_jumps.cpp uses to declare and
191    initialize the temporary boolean break_flag.
192    """
193    return declare_temp('bool', 'break_flag') + \
194        assign_x('break_flag', const_bool(False))
195
196def lowered_return_simple(value = None):
197    """Create the statements that lower_jumps.cpp lowers a return
198    statement to, in situations where it does not need to clear the
199    execute flag.
200    """
201    if value:
202        result = assign_x('return_value', value)
203    else:
204        result = []
205    return result + assign_x('return_flag', const_bool(True))
206
207def lowered_return(value = None):
208    """Create the statements that lower_jumps.cpp lowers a return
209    statement to, in situations where it needs to clear the execute
210    flag.
211    """
212    return lowered_return_simple(value) + \
213        assign_x('execute_flag', const_bool(False))
214
215def lowered_continue():
216    """Create the statement that lower_jumps.cpp lowers a continue
217    statement to.
218    """
219    return assign_x('execute_flag', const_bool(False))
220
221def lowered_break_simple():
222    """Create the statement that lower_jumps.cpp lowers a break
223    statement to, in situations where it does not need to clear the
224    execute flag.
225    """
226    return assign_x('break_flag', const_bool(True))
227
228def lowered_break():
229    """Create the statement that lower_jumps.cpp lowers a break
230    statement to, in situations where it needs to clear the execute
231    flag.
232    """
233    return lowered_break_simple() + assign_x('execute_flag', const_bool(False))
234
235def if_execute_flag(statements):
236    """Wrap statements in an if test so that they will only execute if
237    execute_flag is True.
238    """
239    check_sexp(statements)
240    return [['if', ['var_ref', 'execute_flag'], statements, []]]
241
242def if_return_flag(then_statements, else_statements):
243    """Wrap statements in an if test with return_flag as the condition.
244    """
245    check_sexp(then_statements)
246    check_sexp(else_statements)
247    return [['if', ['var_ref', 'return_flag'], then_statements, else_statements]]
248
249def if_not_return_flag(statements):
250    """Wrap statements in an if test so that they will only execute if
251    return_flag is False.
252    """
253    check_sexp(statements)
254    return [['if', ['var_ref', 'return_flag'], [], statements]]
255
256def final_return():
257    """Create the return statement that lower_jumps.cpp places at the
258    end of a function when lowering returns.
259    """
260    return [['return', ['var_ref', 'return_value']]]
261
262def final_break():
263    """Create the conditional break statement that lower_jumps.cpp
264    places at the end of a function when lowering breaks.
265    """
266    return [['if', ['var_ref', 'break_flag'], break_(), []]]
267
268def bash_quote(*args):
269    """Quote the arguments appropriately so that bash will understand
270    each argument as a single word.
271    """
272    def quote_word(word):
273        for c in word:
274            if not (c.isalpha() or c.isdigit() or c in '@%_-+=:,./'):
275                break
276        else:
277            if not word:
278                return "''"
279            return word
280        return "'{0}'".format(word.replace("'", "'\"'\"'"))
281    return ' '.join(quote_word(word) for word in args)
282
283def create_test_case(doc_string, input_sexp, expected_sexp, test_name,
284                     pull_out_jumps=False, lower_sub_return=False,
285                     lower_main_return=False, lower_continue=False,
286                     lower_break=False):
287    """Create a test case that verifies that do_lower_jumps transforms
288    the given code in the expected way.
289    """
290    doc_lines = [line.strip() for line in doc_string.splitlines()]
291    doc_string = ''.join('# {0}\n'.format(line) for line in doc_lines if line != '')
292    check_sexp(input_sexp)
293    check_sexp(expected_sexp)
294    input_str = sexp_to_string(sort_decls(input_sexp))
295    expected_output = sexp_to_string(sort_decls(expected_sexp))
296
297    optimization = (
298        'do_lower_jumps({0:d}, {1:d}, {2:d}, {3:d}, {4:d})'.format(
299            pull_out_jumps, lower_sub_return, lower_main_return,
300            lower_continue, lower_break))
301    args = [runner, 'optpass', '--quiet', '--input-ir', optimization]
302    test_file = os.path.join(outdir, '{0}.opt_test'.format(test_name))
303    with open(test_file, 'w') as f:
304        f.write('#!/usr/bin/env bash\n#\n# This file was generated by create_test_cases.py.\n#\n')
305        f.write(doc_string)
306        f.write('{0} <<EOF\n'.format(bash_quote(*args)))
307        f.write('{0}\nEOF\n'.format(input_str))
308    os.chmod(test_file, 0774)
309    expected_file = os.path.join(outdir, '{0}.opt_test.expected'.format(test_name))
310    with open(expected_file, 'w') as f:
311        f.write('{0}\n'.format(expected_output))
312
313def test_lower_returns_main():
314    doc_string = """Test that do_lower_jumps respects the lower_main_return
315    flag in deciding whether to lower returns in the main
316    function.
317    """
318    input_sexp = make_test_case('main', 'void', (
319            complex_if('', return_())
320            ))
321    expected_sexp = make_test_case('main', 'void', (
322            declare_execute_flag() +
323            declare_return_flag() +
324            complex_if('', lowered_return())
325            ))
326    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_main_true',
327                     lower_main_return=True)
328    create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_main_false',
329                     lower_main_return=False)
330
331def test_lower_returns_sub():
332    doc_string = """Test that do_lower_jumps respects the lower_sub_return flag
333    in deciding whether to lower returns in subroutines.
334    """
335    input_sexp = make_test_case('sub', 'void', (
336            complex_if('', return_())
337            ))
338    expected_sexp = make_test_case('sub', 'void', (
339            declare_execute_flag() +
340            declare_return_flag() +
341            complex_if('', lowered_return())
342            ))
343    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_sub_true',
344                     lower_sub_return=True)
345    create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_sub_false',
346                     lower_sub_return=False)
347
348def test_lower_returns_1():
349    doc_string = """Test that a void return at the end of a function is
350    eliminated.
351    """
352    input_sexp = make_test_case('main', 'void', (
353            assign_x('a', const_float(1)) +
354            return_()
355            ))
356    expected_sexp = make_test_case('main', 'void', (
357            assign_x('a', const_float(1))
358            ))
359    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_1',
360                     lower_main_return=True)
361
362def test_lower_returns_2():
363    doc_string = """Test that lowering is not performed on a non-void return at
364    the end of subroutine.
365    """
366    input_sexp = make_test_case('sub', 'float', (
367            assign_x('a', const_float(1)) +
368            return_(const_float(1))
369            ))
370    create_test_case(doc_string, input_sexp, input_sexp, 'lower_returns_2',
371                     lower_sub_return=True)
372
373def test_lower_returns_3():
374    doc_string = """Test lowering of returns when there is one nested inside a
375    complex structure of ifs, and one at the end of a function.
376
377    In this case, the latter return needs to be lowered because it
378    will not be at the end of the function once the final return
379    is inserted.
380    """
381    input_sexp = make_test_case('sub', 'float', (
382            complex_if('', return_(const_float(1))) +
383            return_(const_float(2))
384            ))
385    expected_sexp = make_test_case('sub', 'float', (
386            declare_execute_flag() +
387            declare_return_value() +
388            declare_return_flag() +
389            complex_if('', lowered_return(const_float(1))) +
390            if_execute_flag(lowered_return(const_float(2))) +
391            final_return()
392            ))
393    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_3',
394                     lower_sub_return=True)
395
396def test_lower_returns_4():
397    doc_string = """Test that returns are properly lowered when they occur in
398    both branches of an if-statement.
399    """
400    input_sexp = make_test_case('sub', 'float', (
401            simple_if('a', return_(const_float(1)),
402                      return_(const_float(2)))
403            ))
404    expected_sexp = make_test_case('sub', 'float', (
405            declare_execute_flag() +
406            declare_return_value() +
407            declare_return_flag() +
408            simple_if('a', lowered_return(const_float(1)),
409                      lowered_return(const_float(2))) +
410            final_return()
411            ))
412    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_returns_4',
413                     lower_sub_return=True)
414
415def test_lower_unified_returns():
416    doc_string = """If both branches of an if statement end in a return, and
417    pull_out_jumps is True, then those returns should be lifted
418    outside the if and then properly lowered.
419
420    Verify that this lowering occurs during the same pass as the
421    lowering of other returns by checking that extra temporary
422    variables aren't generated.
423    """
424    input_sexp = make_test_case('main', 'void', (
425            complex_if('a', return_()) +
426            simple_if('b', simple_if('c', return_(), return_()))
427            ))
428    expected_sexp = make_test_case('main', 'void', (
429            declare_execute_flag() +
430            declare_return_flag() +
431            complex_if('a', lowered_return()) +
432            if_execute_flag(simple_if('b', (simple_if('c', [], []) +
433                                            lowered_return())))
434            ))
435    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_unified_returns',
436                     lower_main_return=True, pull_out_jumps=True)
437
438def test_lower_pulled_out_jump():
439    doc_string = """If one branch of an if ends in a jump, and control cannot
440    fall out the bottom of the other branch, and pull_out_jumps is
441    True, then the jump is lifted outside the if.
442
443    Verify that this lowering occurs during the same pass as the
444    lowering of other jumps by checking that extra temporary
445    variables aren't generated.
446    """
447    input_sexp = make_test_case('main', 'void', (
448            complex_if('a', return_()) +
449            loop(simple_if('b', simple_if('c', break_(), continue_()),
450                           return_())) +
451            assign_x('d', const_float(1))
452            ))
453    # Note: optimization produces two other effects: the break
454    # gets lifted out of the if statements, and the code after the
455    # loop gets guarded so that it only executes if the return
456    # flag is clear.
457    expected_sexp = make_test_case('main', 'void', (
458            declare_execute_flag() +
459            declare_return_flag() +
460            complex_if('a', lowered_return()) +
461            if_execute_flag(
462                loop(simple_if('b', simple_if('c', [], continue_()),
463                               lowered_return_simple()) +
464                     break_()) +
465
466                if_return_flag(assign_x('return_flag', const_bool(1)) +
467                               assign_x('execute_flag', const_bool(0)),
468                               assign_x('d', const_float(1))))
469            ))
470    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_pulled_out_jump',
471                     lower_main_return=True, pull_out_jumps=True)
472
473def test_lower_breaks_1():
474    doc_string = """If a loop contains an unconditional break at the bottom of
475    it, it should not be lowered."""
476    input_sexp = make_test_case('main', 'void', (
477            loop(assign_x('a', const_float(1)) +
478                 break_())
479            ))
480    expected_sexp = input_sexp
481    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_1', lower_break=True)
482
483def test_lower_breaks_2():
484    doc_string = """If a loop contains a conditional break at the bottom of it,
485    it should not be lowered if it is in the then-clause.
486    """
487    input_sexp = make_test_case('main', 'void', (
488            loop(assign_x('a', const_float(1)) +
489                 simple_if('b', break_()))
490            ))
491    expected_sexp = input_sexp
492    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_2', lower_break=True)
493
494def test_lower_breaks_3():
495    doc_string = """If a loop contains a conditional break at the bottom of it,
496    it should not be lowered if it is in the then-clause, even if
497    there are statements preceding the break.
498    """
499    input_sexp = make_test_case('main', 'void', (
500            loop(assign_x('a', const_float(1)) +
501                 simple_if('b', (assign_x('c', const_float(1)) +
502                                 break_())))
503            ))
504    expected_sexp = input_sexp
505    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_3', lower_break=True)
506
507def test_lower_breaks_4():
508    doc_string = """If a loop contains a conditional break at the bottom of it,
509    it should not be lowered if it is in the else-clause.
510    """
511    input_sexp = make_test_case('main', 'void', (
512            loop(assign_x('a', const_float(1)) +
513                 simple_if('b', [], break_()))
514            ))
515    expected_sexp = input_sexp
516    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_4', lower_break=True)
517
518def test_lower_breaks_5():
519    doc_string = """If a loop contains a conditional break at the bottom of it,
520    it should not be lowered if it is in the else-clause, even if
521    there are statements preceding the break.
522    """
523    input_sexp = make_test_case('main', 'void', (
524            loop(assign_x('a', const_float(1)) +
525                 simple_if('b', [], (assign_x('c', const_float(1)) +
526                                     break_())))
527            ))
528    expected_sexp = input_sexp
529    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_5', lower_break=True)
530
531def test_lower_breaks_6():
532    doc_string = """If a loop contains conditional breaks and continues, and
533    ends in an unconditional break, then the unconditional break
534    needs to be lowered, because it will no longer be at the end
535    of the loop after the final break is added.
536    """
537    input_sexp = make_test_case('main', 'void', (
538            loop(simple_if('a', (complex_if('b', continue_()) +
539                                 complex_if('c', break_()))) +
540                 break_())
541            ))
542    expected_sexp = make_test_case('main', 'void', (
543            declare_break_flag() +
544            loop(declare_execute_flag() +
545                 simple_if(
546                    'a',
547                    (complex_if('b', lowered_continue()) +
548                     if_execute_flag(
549                            complex_if('c', lowered_break())))) +
550                 if_execute_flag(lowered_break_simple()) +
551                 final_break())
552            ))
553    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_breaks_6',
554                     lower_break=True, lower_continue=True)
555
556def test_lower_guarded_conditional_break():
557    doc_string = """Normally a conditional break at the end of a loop isn't
558    lowered, however if the conditional break gets placed inside
559    an if(execute_flag) because of earlier lowering of continues,
560    then the break needs to be lowered.
561    """
562    input_sexp = make_test_case('main', 'void', (
563            loop(complex_if('a', continue_()) +
564                 simple_if('b', break_()))
565            ))
566    expected_sexp = make_test_case('main', 'void', (
567            declare_break_flag() +
568            loop(declare_execute_flag() +
569                 complex_if('a', lowered_continue()) +
570                 if_execute_flag(simple_if('b', lowered_break())) +
571                 final_break())
572            ))
573    create_test_case(doc_string, input_sexp, expected_sexp, 'lower_guarded_conditional_break',
574                     lower_break=True, lower_continue=True)
575
576def test_remove_continue_at_end_of_loop():
577    doc_string = """Test that a redundant continue-statement at the end of a
578    loop is removed.
579    """
580    input_sexp = make_test_case('main', 'void', (
581            loop(assign_x('a', const_float(1)) +
582                 continue_())
583            ))
584    expected_sexp = make_test_case('main', 'void', (
585            loop(assign_x('a', const_float(1)))
586            ))
587    create_test_case(doc_string, input_sexp, expected_sexp, 'remove_continue_at_end_of_loop')
588
589def test_lower_return_void_at_end_of_loop():
590    doc_string = """Test that a return of void at the end of a loop is properly
591    lowered.
592    """
593    input_sexp = make_test_case('main', 'void', (
594            loop(assign_x('a', const_float(1)) +
595                 return_()) +
596            assign_x('b', const_float(2))
597            ))
598    expected_sexp = make_test_case('main', 'void', (
599            declare_execute_flag() +
600            declare_return_flag() +
601            loop(assign_x('a', const_float(1)) +
602                 lowered_return_simple() +
603                 break_()) +
604            if_return_flag(assign_x('return_flag', const_bool(1)) +
605                           assign_x('execute_flag', const_bool(0)),
606                           assign_x('b', const_float(2)))
607            ))
608    create_test_case(doc_string, input_sexp, input_sexp, 'return_void_at_end_of_loop_lower_nothing')
609    create_test_case(doc_string, input_sexp, expected_sexp, 'return_void_at_end_of_loop_lower_return',
610                     lower_main_return=True)
611    create_test_case(doc_string, input_sexp, expected_sexp, 'return_void_at_end_of_loop_lower_return_and_break',
612                     lower_main_return=True, lower_break=True)
613
614def test_lower_return_non_void_at_end_of_loop():
615    doc_string = """Test that a non-void return at the end of a loop is
616    properly lowered.
617    """
618    input_sexp = make_test_case('sub', 'float', (
619            loop(assign_x('a', const_float(1)) +
620                 return_(const_float(2))) +
621            assign_x('b', const_float(3)) +
622            return_(const_float(4))
623            ))
624    expected_sexp = make_test_case('sub', 'float', (
625            declare_execute_flag() +
626            declare_return_value() +
627            declare_return_flag() +
628            loop(assign_x('a', const_float(1)) +
629                 lowered_return_simple(const_float(2)) +
630                 break_()) +
631            if_return_flag(assign_x('return_value', '(var_ref return_value)') +
632                           assign_x('return_flag', const_bool(1)) +
633                           assign_x('execute_flag', const_bool(0)),
634                           assign_x('b', const_float(3)) +
635                               lowered_return(const_float(4))) +
636            final_return()
637            ))
638    create_test_case(doc_string, input_sexp, input_sexp, 'return_non_void_at_end_of_loop_lower_nothing')
639    create_test_case(doc_string, input_sexp, expected_sexp, 'return_non_void_at_end_of_loop_lower_return',
640                     lower_sub_return=True)
641    create_test_case(doc_string, input_sexp, expected_sexp, 'return_non_void_at_end_of_loop_lower_return_and_break',
642                     lower_sub_return=True, lower_break=True)
643
644if __name__ == '__main__':
645    parser = argparse.ArgumentParser()
646    parser.add_argument('--runner',
647                        help='The glsl_test runner',
648                        required=True)
649    parser.add_argument('--outdir',
650                        help='Directory to put the generated files in',
651                        required=True)
652    args = parser.parse_args()
653    runner = args.runner
654    outdir = args.outdir
655
656    test_lower_returns_main()
657    test_lower_returns_sub()
658    test_lower_returns_1()
659    test_lower_returns_2()
660    test_lower_returns_3()
661    test_lower_returns_4()
662    test_lower_unified_returns()
663    test_lower_pulled_out_jump()
664    test_lower_breaks_1()
665    test_lower_breaks_2()
666    test_lower_breaks_3()
667    test_lower_breaks_4()
668    test_lower_breaks_5()
669    test_lower_breaks_6()
670    test_lower_guarded_conditional_break()
671    test_remove_continue_at_end_of_loop()
672    test_lower_return_void_at_end_of_loop()
673    test_lower_return_non_void_at_end_of_loop()
674