Home | History | Annotate | only in /art/tools/checker
Up to higher level directory
NameDateSize
checker.py21-Aug-20184.4K
common/21-Aug-2018
file_format/21-Aug-2018
match/21-Aug-2018
README21-Aug-20184.4K
run_unit_tests.py21-Aug-20181.3K

README

      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 or Smali, turned into DEX and compiled with the
      6 Optimizing compiler. "Check lines" are assertions formatted as comments of the
      7 source file. They begin with prefix "/// CHECK" or "## CHECK", respectively,
      8 followed by a pattern that the engine attempts to match in the compiler 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-passes' 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  - 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'.
     35 
     36 Check-line patterns are treated as plain text rather than regular expressions
     37 but are whitespace agnostic.
     38 
     39 Actual regex patterns can be inserted enclosed in '{{' and '}}' brackets. If
     40 curly brackets need to be used inside the body of the regex, they need to be
     41 enclosed in round brackets. For example, the pattern '{{foo{2}}}' will parse
     42 the invalid regex 'foo{2', but '{{(fo{2})}}' will match 'foo'.
     43 
     44 Regex patterns can be named and referenced later. A new variable is defined
     45 with '<<name:regex>>' and can be referenced with '<<name>>'. Variables are
     46 only valid within the scope of the defining group. Within a group they cannot
     47 be redefined or used undefined.
     48 
     49 Example:
     50   The following assertions can be placed in a Java source file:
     51 
     52   /// CHECK-START: int MyClass.MyMethod() constant_folding (after)
     53   /// CHECK:         <<ID:i\d+>>  IntConstant {{11|22}}
     54   /// CHECK:                      Return [<<ID>>]
     55 
     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.
     59 
     60 
     61 Of the language constructs above, 'CHECK-EVAL' lines support only referencing of
     62 variables. Any other surrounding text will be passed to Python's `eval` as is.
     63 
     64 Example:
     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 
     71 A group of check lines can be made architecture-specific by inserting '-<arch>'
     72 after the 'CHECK-START' keyword. The previous example can be updated to run for
     73 arm64 only with:
     74 
     75 Example:
     76   /// CHECK-START-ARM64: int MyClass.MyMethod() constant_folding (after)
     77   /// CHECK:         <<ID:i\d+>>  IntConstant {{11|22}}
     78   /// CHECK:                      Return [<<ID>>]
     79 
     80 For convenience, several architectures can be specified as set after the
     81 'CHECK-START' keyword. Any listed architecture will match in that case,
     82 thereby avoiding to repeat the check lines if some, but not all architectures
     83 match. An example line looks like:
     84 
     85   /// CHECK-START-{MIPS,ARM,ARM64}: int MyClass.MyMethod() constant_folding (after)
     86