blob: b8dd80376e88e780855850218617b7ece27ec106 [file] [log] [blame]
David Brazdil2c27f2c2015-05-12 18:06:38 +01001Checker is a testing tool which compiles a given test file and compares the
2state of the control-flow graph before and after each optimization pass
3against a set of assertions specified alongside the tests.
4
David Brazdilb34c35e2015-08-20 11:46:04 +01005Tests are written in Java or Smali, turned into DEX and compiled with the
6Optimizing compiler. "Check lines" are assertions formatted as comments of the
7source file. They begin with prefix "/// CHECK" or "## CHECK", respectively,
8followed by a pattern that the engine attempts to match in the compiler output.
David Brazdil2c27f2c2015-05-12 18:06:38 +01009
10Assertions are tested in groups which correspond to the individual compiler
11passes. Each group of check lines therefore must start with a 'CHECK-START'
12header which specifies the output group it should be tested against. The group
13name must exactly match one of the groups recognized in the output (they can
David Brazdilc2c48ff2015-05-15 14:24:31 +010014be listed with the '--list-passes' command-line flag).
David Brazdil2c27f2c2015-05-12 18:06:38 +010015
16Matching of check lines is carried out in the order of appearance in the
17source file. There are three types of check lines:
David Brazdilb34c35e2015-08-20 11:46:04 +010018 - 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 - CHECK-NEXT: Must match the output line which comes right after the line which
32 matched the previous check. Cannot be used after any but the
33 in-order CHECK.
34 - CHECK-EVAL: Specifies a Python expression which must evaluate to 'True'.
David Brazdil2c27f2c2015-05-12 18:06:38 +010035
36Check-line patterns are treated as plain text rather than regular expressions
37but are whitespace agnostic.
38
39Actual regex patterns can be inserted enclosed in '{{' and '}}' brackets. If
40curly brackets need to be used inside the body of the regex, they need to be
41enclosed in round brackets. For example, the pattern '{{foo{2}}}' will parse
42the invalid regex 'foo{2', but '{{(fo{2})}}' will match 'foo'.
43
44Regex patterns can be named and referenced later. A new variable is defined
David Brazdilc2c48ff2015-05-15 14:24:31 +010045with '<<name:regex>>' and can be referenced with '<<name>>'. Variables are
David Brazdil2c27f2c2015-05-12 18:06:38 +010046only valid within the scope of the defining group. Within a group they cannot
47be redefined or used undefined.
48
49Example:
50 The following assertions can be placed in a Java source file:
51
David Brazdilb34c35e2015-08-20 11:46:04 +010052 /// CHECK-START: int MyClass.MyMethod() constant_folding (after)
53 /// CHECK: <<ID:i\d+>> IntConstant {{11|22}}
54 /// CHECK: Return [<<ID>>]
David Brazdil2c27f2c2015-05-12 18:06:38 +010055
56 The engine will attempt to match the check lines against the output of the
57 group named on the first line. Together they verify that the CFG after
58 constant folding returns an integer constant with value either 11 or 22.
Alexandre Rames5e2c8d32015-08-06 14:49:28 +010059
David Brazdilb34c35e2015-08-20 11:46:04 +010060
61Of the language constructs above, 'CHECK-EVAL' lines support only referencing of
62variables. Any other surrounding text will be passed to Python's `eval` as is.
63
64Example:
65 /// CHECK-START: int MyClass.MyMethod() liveness (after)
66 /// CHECK: InstructionA liveness:<<VarA:\d+>>
67 /// CHECK: InstructionB liveness:<<VarB:\d+>>
68 /// CHECK-EVAL: <<VarA>> != <<VarB>>
69
70
Alexandre Rames5e2c8d32015-08-06 14:49:28 +010071A group of check lines can be made architecture-specific by inserting '-<arch>'
72after the 'CHECK-START' keyword. The previous example can be updated to run for
73arm64 only with:
74
David Brazdilb34c35e2015-08-20 11:46:04 +010075Example:
76 /// CHECK-START-ARM64: int MyClass.MyMethod() constant_folding (after)
77 /// CHECK: <<ID:i\d+>> IntConstant {{11|22}}
78 /// CHECK: Return [<<ID>>]
Aart Bik92706a82017-11-30 11:46:45 -080079
80For convenience, several architectures can be specified as set after the
81'CHECK-START' keyword. Any listed architecture will match in that case,
82thereby avoiding to repeat the check lines if some, but not all architectures
83match. An example line looks like:
84
85 /// CHECK-START-{MIPS,ARM,ARM64}: int MyClass.MyMethod() constant_folding (after)