summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/graph_visualizer.cc23
-rw-r--r--compiler/optimizing/graph_visualizer.h16
-rw-r--r--compiler/optimizing/optimizing_compiler.cc24
-rw-r--r--compiler/optimizing/test/ConstantFolding.java221
4 files changed, 254 insertions, 30 deletions
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 5d1703e237..b14b0a70e2 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -167,6 +167,15 @@ class HGraphVisualizerPrinter : public HGraphVisitor {
}
output_ << "]";
}
+ if (instruction->IsIntConstant()) {
+ output_ << " " << instruction->AsIntConstant()->GetValue();
+ } else if (instruction->IsLongConstant()) {
+ output_ << " " << instruction->AsLongConstant()->GetValue();
+ } else if (instruction->IsFloatConstant()) {
+ output_ << " " << instruction->AsFloatConstant()->GetValue();
+ } else if (instruction->IsDoubleConstant()) {
+ output_ << " " << instruction->AsDoubleConstant()->GetValue();
+ }
if (pass_name_ == kLivenessPassName && instruction->GetLifetimePosition() != kNoLifetime) {
output_ << " (liveness: " << instruction->GetLifetimePosition();
if (instruction->HasLiveInterval()) {
@@ -270,7 +279,7 @@ HGraphVisualizer::HGraphVisualizer(std::ostream* output,
const char* string_filter,
const CodeGenerator& codegen,
const char* method_name)
- : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) {
+ : output_(output), graph_(graph), codegen_(codegen), is_enabled_(false) {
if (output == nullptr) {
return;
}
@@ -279,7 +288,7 @@ HGraphVisualizer::HGraphVisualizer(std::ostream* output,
}
is_enabled_ = true;
- HGraphVisualizerPrinter printer(graph, *output_, "", codegen_);
+ HGraphVisualizerPrinter printer(graph_, *output_, "", codegen_);
printer.StartTag("compilation");
printer.PrintProperty("name", method_name);
printer.PrintProperty("method", method_name);
@@ -287,12 +296,12 @@ HGraphVisualizer::HGraphVisualizer(std::ostream* output,
printer.EndTag("compilation");
}
-void HGraphVisualizer::DumpGraph(const char* pass_name) const {
- if (!is_enabled_) {
- return;
+void HGraphVisualizer::DumpGraph(const char* pass_name, bool is_after_pass) const {
+ if (is_enabled_) {
+ std::string pass_desc = std::string(pass_name) + (is_after_pass ? " (after)" : " (before)");
+ HGraphVisualizerPrinter printer(graph_, *output_, pass_desc.c_str(), codegen_);
+ printer.Run();
}
- HGraphVisualizerPrinter printer(graph_, *output_, pass_name, codegen_);
- printer.Run();
}
} // namespace art
diff --git a/compiler/optimizing/graph_visualizer.h b/compiler/optimizing/graph_visualizer.h
index b5baed9c99..b90d15e1ff 100644
--- a/compiler/optimizing/graph_visualizer.h
+++ b/compiler/optimizing/graph_visualizer.h
@@ -32,28 +32,18 @@ static const char* kLivenessPassName = "liveness";
static const char* kRegisterAllocatorPassName = "register";
/**
- * If enabled, emits compilation information suitable for the c1visualizer tool
- * and IRHydra.
- * Currently only works if the compiler is single threaded.
+ * This class outputs the HGraph in the C1visualizer format.
+ * Note: Currently only works if the compiler is single threaded.
*/
class HGraphVisualizer : public ValueObject {
public:
- /**
- * If output is not null, and the method name of the dex compilation
- * unit contains `string_filter`, the compilation information will be
- * emitted.
- */
HGraphVisualizer(std::ostream* output,
HGraph* graph,
const char* string_filter,
const CodeGenerator& codegen,
const char* method_name);
- /**
- * If this visualizer is enabled, emit the compilation information
- * in `output_`.
- */
- void DumpGraph(const char* pass_name) const;
+ void DumpGraph(const char* pass_name, bool is_after_pass = true) const;
private:
std::ostream* const output_;
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index deebaf7414..94751f876c 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -68,13 +68,8 @@ class CodeVectorAllocator FINAL : public CodeAllocator {
};
/**
- * 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 @@ class OptimizingCompiler FINAL : public Compiler {
void InitCompilationUnit(CompilationUnit& cu ATTRIBUTE_UNUSED) const OVERRIDE {}
- void Init() const OVERRIDE {}
+ void Init() OVERRIDE;
void UnInit() const OVERRIDE {}
@@ -136,8 +131,16 @@ OptimizingCompiler::OptimizingCompiler(CompilerDriver* driver)
: 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 @@ static void RunOptimizations(HGraph* graph,
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();
}
}
diff --git a/compiler/optimizing/test/ConstantFolding.java b/compiler/optimizing/test/ConstantFolding.java
new file mode 100644
index 0000000000..7fac5a985c
--- /dev/null
+++ b/compiler/optimizing/test/ConstantFolding.java
@@ -0,0 +1,221 @@
+/*
+* Copyright (C) 2014 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+public class ConstantFolding {
+
+ /**
+ * Tiny three-register program exercising int constant folding
+ * on negation.
+ */
+
+ // CHECK-START: int ConstantFolding.IntNegation() constant_folding (before)
+ // CHECK: [[Const42:i[0-9]+]] IntConstant 42
+ // CHECK: [[Neg:i[0-9]+]] Neg [ [[Const42]] ]
+ // CHECK: Return [ [[Neg]] ]
+
+ // CHECK-START: int ConstantFolding.IntNegation() constant_folding (after)
+ // CHECK: [[ConstN42:i[0-9]+]] IntConstant -42
+ // CHECK: Return [ [[ConstN42]] ]
+
+ public static int IntNegation() {
+ int x, y;
+ x = 42;
+ y = -x;
+ return y;
+ }
+
+ /**
+ * Tiny three-register program exercising int constant folding
+ * on addition.
+ */
+
+ // CHECK-START: int ConstantFolding.IntAddition1() constant_folding (before)
+ // CHECK: [[Const1:i[0-9]+]] IntConstant 1
+ // CHECK: [[Const2:i[0-9]+]] IntConstant 2
+ // CHECK: [[Add:i[0-9]+]] Add [ [[Const1]] [[Const2]] ]
+ // CHECK: Return [ [[Add]] ]
+
+ // CHECK-START: int ConstantFolding.IntAddition1() constant_folding (after)
+ // CHECK: [[Const3:i[0-9]+]] IntConstant 3
+ // CHECK: Return [ [[Const3]] ]
+
+ public static int IntAddition1() {
+ int a, b, c;
+ a = 1;
+ b = 2;
+ c = a + b;
+ return c;
+ }
+
+ /**
+ * Small three-register program exercising int constant folding
+ * on addition.
+ */
+
+ // CHECK-START: int ConstantFolding.IntAddition2() constant_folding (before)
+ // CHECK: [[Const1:i[0-9]+]] IntConstant 1
+ // CHECK: [[Const2:i[0-9]+]] IntConstant 2
+ // CHECK: [[Const5:i[0-9]+]] IntConstant 5
+ // CHECK: [[Const6:i[0-9]+]] IntConstant 6
+ // CHECK: [[Add1:i[0-9]+]] Add [ [[Const1]] [[Const2]] ]
+ // CHECK: [[Add2:i[0-9]+]] Add [ [[Const5]] [[Const6]] ]
+ // CHECK: [[Add3:i[0-9]+]] Add [ [[Add1]] [[Add2]] ]
+ // CHECK: Return [ [[Add3]] ]
+
+ // CHECK-START: int ConstantFolding.IntAddition2() constant_folding (after)
+ // CHECK: [[Const14:i[0-9]+]] IntConstant 14
+ // CHECK: Return [ [[Const14]] ]
+
+ public static int IntAddition2() {
+ int a, b, c;
+ a = 1;
+ b = 2;
+ a += b;
+ b = 5;
+ c = 6;
+ b += c;
+ c = a + b;
+ return c;
+ }
+
+ /**
+ * Tiny three-register program exercising int constant folding
+ * on subtraction.
+ */
+
+ // CHECK-START: int ConstantFolding.IntSubtraction() constant_folding (before)
+ // CHECK: [[Const5:i[0-9]+]] IntConstant 5
+ // CHECK: [[Const2:i[0-9]+]] IntConstant 2
+ // CHECK: [[Sub:i[0-9]+]] Sub [ [[Const5]] [[Const2]] ]
+ // CHECK: Return [ [[Sub]] ]
+
+ // CHECK-START: int ConstantFolding.IntSubtraction() constant_folding (after)
+ // CHECK: [[Const3:i[0-9]+]] IntConstant 3
+ // CHECK: Return [ [[Const3]] ]
+
+ public static int IntSubtraction() {
+ int a, b, c;
+ a = 5;
+ b = 2;
+ c = a - b;
+ return c;
+ }
+
+ /**
+ * Tiny three-register program exercising long constant folding
+ * on addition.
+ */
+
+ // CHECK-START: long ConstantFolding.LongAddition() constant_folding (before)
+ // CHECK: [[Const1:j[0-9]+]] LongConstant 1
+ // CHECK: [[Const2:j[0-9]+]] LongConstant 2
+ // CHECK: [[Add:j[0-9]+]] Add [ [[Const1]] [[Const2]] ]
+ // CHECK: Return [ [[Add]] ]
+
+ // CHECK-START: long ConstantFolding.LongAddition() constant_folding (after)
+ // CHECK: [[Const3:j[0-9]+]] LongConstant 3
+ // CHECK: Return [ [[Const3]] ]
+
+ public static long LongAddition() {
+ long a, b, c;
+ a = 1L;
+ b = 2L;
+ c = a + b;
+ return c;
+ }
+
+ /**
+ * Tiny three-register program exercising long constant folding
+ * on subtraction.
+ */
+
+ // CHECK-START: long ConstantFolding.LongSubtraction() constant_folding (before)
+ // CHECK: [[Const5:j[0-9]+]] LongConstant 5
+ // CHECK: [[Const2:j[0-9]+]] LongConstant 2
+ // CHECK: [[Sub:j[0-9]+]] Sub [ [[Const5]] [[Const2]] ]
+ // CHECK: Return [ [[Sub]] ]
+
+ // CHECK-START: long ConstantFolding.LongSubtraction() constant_folding (after)
+ // CHECK: [[Const3:j[0-9]+]] LongConstant 3
+ // CHECK: Return [ [[Const3]] ]
+
+ public static long LongSubtraction() {
+ long a, b, c;
+ a = 5L;
+ b = 2L;
+ c = a - b;
+ return c;
+ }
+
+ /**
+ * Three-register program with a constant (static) condition.
+ */
+
+ // CHECK-START: int ConstantFolding.StaticCondition() constant_folding (before)
+ // CHECK: [[Const5:i[0-9]+]] IntConstant 5
+ // CHECK: [[Const2:i[0-9]+]] IntConstant 2
+ // CHECK: [[Cond:z[0-9]+]] GreaterThanOrEqual [ [[Const5]] [[Const2]] ]
+ // CHECK: If [ [[Cond]] ]
+
+ // CHECK-START: int ConstantFolding.StaticCondition() constant_folding (after)
+ // CHECK: [[Const1:i[0-9]+]] IntConstant 1
+ // CHECK: If [ [[Const1]] ]
+
+ public static int StaticCondition() {
+ int a, b, c;
+ a = 5;
+ b = 2;
+ if (a < b)
+ c = a + b;
+ else
+ c = a - b;
+ return c;
+ }
+
+ /**
+ * Four-variable program with jumps leading to the creation of many
+ * blocks.
+ *
+ * The intent of this test is to ensure that all constant expressions
+ * are actually evaluated at compile-time, thanks to the reverse
+ * (forward) post-order traversal of the the dominator tree.
+ */
+
+ // CHECK-START: int ConstantFolding.JumpsAndConditionals(boolean) constant_folding (before)
+ // CHECK: [[Const5:i[0-9]+]] IntConstant 5
+ // CHECK: [[Const2:i[0-9]+]] IntConstant 2
+ // CHECK: [[Add:i[0-9]+]] Add [ [[Const5]] [[Const2]] ]
+ // CHECK: [[Phi:i[0-9]+]] Phi [ [[Add]] [[Sub:i[0-9]+]] ]
+ // CHECK: Return [ [[Phi]] ]
+ // CHECK: [[Sub]] Sub [ [[Const5]] [[Const2]] ]
+
+ // CHECK-START: int ConstantFolding.JumpsAndConditionals(boolean) constant_folding (after)
+ // CHECK: [[Const7:i[0-9]+]] IntConstant 7
+ // CHECK: [[Phi:i[0-9]+]] Phi [ [[Const7]] [[Const3:i[0-9]+]] ]
+ // CHECK: Return [ [[Phi]] ]
+ // CHECK: [[Const3]] IntConstant 3
+
+ public static int JumpsAndConditionals(boolean cond) {
+ int a, b, c;
+ a = 5;
+ b = 2;
+ if (cond)
+ c = a + b;
+ else
+ c = a - b;
+ return c;
+ }
+}