diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 23 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.h | 16 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 24 | ||||
-rw-r--r-- | compiler/optimizing/test/ConstantFolding.java | 221 |
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; + } +} |