David Brazdil | 2c27f2c | 2015-05-12 18:06:38 +0100 | [diff] [blame] | 1 | Checker is a testing tool which compiles a given test file and compares the |
| 2 | state of the control-flow graph before and after each optimization pass |
| 3 | against a set of assertions specified alongside the tests. |
| 4 | |
| 5 | Tests are written in Java, turned into DEX and compiled with the Optimizing |
| 6 | compiler. "Check lines" are assertions formatted as comments of the Java file. |
| 7 | They begin with prefix 'CHECK' followed by a pattern that the engine attempts |
| 8 | to match in the compiler-generated output. |
| 9 | |
| 10 | Assertions are tested in groups which correspond to the individual compiler |
| 11 | passes. Each group of check lines therefore must start with a 'CHECK-START' |
| 12 | header which specifies the output group it should be tested against. The group |
| 13 | name must exactly match one of the groups recognized in the output (they can |
| 14 | be listed with the '--list-groups' command-line flag). |
| 15 | |
| 16 | Matching of check lines is carried out in the order of appearance in the |
| 17 | source file. There are three types of check lines: |
| 18 | - CHECK: Must match an output line which appears in the output group |
| 19 | later than lines matched against any preceeding checks. Output |
| 20 | lines must therefore match the check lines in the same order. |
| 21 | These are referred to as "in-order" checks in the code. |
| 22 | - CHECK-DAG: Must match an output line which appears in the output group |
| 23 | later than lines matched against any preceeding in-order checks. |
| 24 | In other words, the order of output lines does not matter |
| 25 | between consecutive DAG checks. |
| 26 | - CHECK-NOT: Must not match any output line which appears in the output group |
| 27 | later than lines matched against any preceeding checks and |
| 28 | earlier than lines matched against any subsequent checks. |
| 29 | Surrounding non-negative checks (or boundaries of the group) |
| 30 | therefore create a scope within which the assertion is verified. |
| 31 | |
| 32 | Check-line patterns are treated as plain text rather than regular expressions |
| 33 | but are whitespace agnostic. |
| 34 | |
| 35 | Actual regex patterns can be inserted enclosed in '{{' and '}}' brackets. If |
| 36 | curly brackets need to be used inside the body of the regex, they need to be |
| 37 | enclosed in round brackets. For example, the pattern '{{foo{2}}}' will parse |
| 38 | the invalid regex 'foo{2', but '{{(fo{2})}}' will match 'foo'. |
| 39 | |
| 40 | Regex patterns can be named and referenced later. A new variable is defined |
| 41 | with '[[name:regex]]' and can be referenced with '[[name]]'. Variables are |
| 42 | only valid within the scope of the defining group. Within a group they cannot |
| 43 | be redefined or used undefined. |
| 44 | |
| 45 | Example: |
| 46 | The following assertions can be placed in a Java source file: |
| 47 | |
| 48 | // CHECK-START: int MyClass.MyMethod() constant_folding (after) |
| 49 | // CHECK: [[ID:i\d+]] IntConstant {{11|22}} |
| 50 | // CHECK: Return [ [[ID]] ] |
| 51 | |
| 52 | The engine will attempt to match the check lines against the output of the |
| 53 | group named on the first line. Together they verify that the CFG after |
| 54 | constant folding returns an integer constant with value either 11 or 22. |