ART: Added Checker, a pattern matching test engine
This patch adds a Python script which implements a domain-specific
mini-language similar to that of LLVM's FileCheck. It is primarily
intended for writing tests for the optimizing compiler but could be
configured for other use cases too. It is implemented from scratch in
order to avoid dependency on LLVM.
Checker tests are written in Java and dex2oat is invoked with a flag
which dumps the CFG before and after each pass of the optimizing
compiler. The output is then compared against assertions in the
test's comments parsed by Checker. See comments in tools/checker.py
for more details about the currently supported language features.
This initial CL implements only one type of assertion - whether the
output contains lines matching a desired pattern in the given order -
but supports both plain text and regex matching and allows for
equivalency testing by matching for the outcome of a previous match.
See the tests in compiler/optimizing/test/ConstantFolding.java for
examples.
Change-Id: I1ad7431b399c38dc0391ccee74d2c643ba0b0675
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index deebaf7..94751f8 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -68,13 +68,8 @@
};
/**
- * If set to true, generates a file suitable for the c1visualizer tool and IRHydra.
- */
-static bool kIsVisualizerEnabled = false;
-
-/**
* Filter to apply to the visualizer. Methods whose name contain that filter will
- * be in the file.
+ * be dumped.
*/
static const char* kStringFilter = "";
@@ -114,7 +109,7 @@
void InitCompilationUnit(CompilationUnit& cu ATTRIBUTE_UNUSED) const OVERRIDE {}
- void Init() const OVERRIDE {}
+ void Init() OVERRIDE;
void UnInit() const OVERRIDE {}
@@ -136,8 +131,16 @@
: Compiler(driver, kMaximumCompilationTimeBeforeWarning),
run_optimizations_(
driver->GetCompilerOptions().GetCompilerFilter() != CompilerOptions::kTime),
- compilation_stats_() {
- if (kIsVisualizerEnabled) {
+ compilation_stats_() {}
+
+void OptimizingCompiler::Init() {
+ // Enable C1visualizer output. Must be done in Init() because the compiler
+ // driver is not fully initialized when passed to the compiler's constructor.
+ CompilerDriver* driver = GetCompilerDriver();
+ if (driver->GetDumpPasses()) {
+ CHECK_EQ(driver->GetThreadCount(), 1U)
+ << "Graph visualizer requires the compiler to run single-threaded. "
+ << "Invoke the compiler with '-j1'.";
visualizer_output_.reset(new std::ofstream("art.cfg"));
}
}
@@ -213,8 +216,9 @@
for (size_t i = 0; i < arraysize(optimizations); ++i) {
HOptimization* optimization = optimizations[i];
+ visualizer.DumpGraph(optimization->GetPassName(), /*is_after=*/false);
optimization->Run();
- visualizer.DumpGraph(optimization->GetPassName());
+ visualizer.DumpGraph(optimization->GetPassName(), /*is_after=*/true);
optimization->Check();
}
}