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