diff options
author | Roland Levillain <rpl@google.com> | 2014-10-17 17:02:00 +0100 |
---|---|---|
committer | Roland Levillain <rpl@google.com> | 2014-10-17 17:11:43 +0100 |
commit | 75be28332b278cff9039b54bfb228ac72f539ccc (patch) | |
tree | a01829ba0412d0f6637a833b41694f0d757d8f43 /compiler/optimizing | |
parent | ffb078ee815a38123581e706099a3bed65a6cb24 (diff) | |
download | art-75be28332b278cff9039b54bfb228ac72f539ccc.zip art-75be28332b278cff9039b54bfb228ac72f539ccc.tar.gz art-75be28332b278cff9039b54bfb228ac72f539ccc.tar.bz2 |
Revert "Revert "Introduce a class to implement optimization passes.""
This reverts commit 1ddbf6d4b37979a9f11a203c12befd5ae8b65df4.
Change-Id: I110a14668d1564ee0604dc958b91394b40da89fc
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/constant_folding.cc (renamed from compiler/optimizing/constant_propagation.cc) | 4 | ||||
-rw-r--r-- | compiler/optimizing/constant_folding.h | 48 | ||||
-rw-r--r-- | compiler/optimizing/constant_folding_test.cc (renamed from compiler/optimizing/constant_propagation_test.cc) | 146 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination.h | 16 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination_test.cc | 17 | ||||
-rw-r--r-- | compiler/optimizing/graph_checker.h | 20 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/optimization.cc (renamed from compiler/optimizing/constant_propagation.h) | 46 | ||||
-rw-r--r-- | compiler/optimizing/optimization.h | 71 | ||||
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 5 |
12 files changed, 265 insertions, 114 deletions
diff --git a/compiler/optimizing/constant_propagation.cc b/compiler/optimizing/constant_folding.cc index d675164..0b3ad98 100644 --- a/compiler/optimizing/constant_propagation.cc +++ b/compiler/optimizing/constant_folding.cc @@ -14,11 +14,11 @@ * limitations under the License. */ -#include "constant_propagation.h" +#include "constant_folding.h" namespace art { -void ConstantPropagation::Run() { +void HConstantFolding::Run() { // Process basic blocks in reverse post-order in the dominator tree, // so that an instruction turned into a constant, used as input of // another instruction, may possibly be used to turn that second diff --git a/compiler/optimizing/constant_folding.h b/compiler/optimizing/constant_folding.h new file mode 100644 index 0000000..d2acfa6 --- /dev/null +++ b/compiler/optimizing/constant_folding.h @@ -0,0 +1,48 @@ +/* + * 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. + */ + +#ifndef ART_COMPILER_OPTIMIZING_CONSTANT_FOLDING_H_ +#define ART_COMPILER_OPTIMIZING_CONSTANT_FOLDING_H_ + +#include "nodes.h" +#include "optimization.h" + +namespace art { + +/** + * Optimization pass performing a simple constant-expression + * evaluation on the SSA form. + * + * This class is named art::HConstantFolding to avoid name + * clashes with the art::ConstantPropagation class defined in + * compiler/dex/post_opt_passes.h. + */ +class HConstantFolding : public HOptimization { + public: + HConstantFolding(HGraph* graph, const HGraphVisualizer& visualizer) + : HOptimization(graph, true, kConstantFoldingPassName, visualizer) {} + + virtual void Run() OVERRIDE; + + static constexpr const char* kConstantFoldingPassName = "constant_folding"; + + private: + DISALLOW_COPY_AND_ASSIGN(HConstantFolding); +}; + +} // namespace art + +#endif // ART_COMPILER_OPTIMIZING_CONSTANT_FOLDING_H_ diff --git a/compiler/optimizing/constant_propagation_test.cc b/compiler/optimizing/constant_folding_test.cc index ff44805..ec2ff33 100644 --- a/compiler/optimizing/constant_propagation_test.cc +++ b/compiler/optimizing/constant_folding_test.cc @@ -16,11 +16,12 @@ #include <functional> -#include "constant_propagation.h" +#include "code_generator_x86.h" +#include "constant_folding.h" #include "dead_code_elimination.h" -#include "pretty_printer.h" #include "graph_checker.h" #include "optimizing_unit_test.h" +#include "pretty_printer.h" #include "gtest/gtest.h" @@ -28,9 +29,9 @@ namespace art { static void TestCode(const uint16_t* data, const std::string& expected_before, - const std::string& expected_after_cp, + const std::string& expected_after_cf, const std::string& expected_after_dce, - std::function<void(HGraph*)> check_after_cp, + std::function<void(HGraph*)> check_after_cf, Primitive::Type return_type = Primitive::kPrimInt) { ArenaPool pool; ArenaAllocator allocator(&pool); @@ -45,25 +46,28 @@ static void TestCode(const uint16_t* data, std::string actual_before = printer_before.str(); ASSERT_EQ(expected_before, actual_before); - ConstantPropagation(graph).Run(); + x86::CodeGeneratorX86 codegen(graph); + HGraphVisualizer visualizer(nullptr, graph, codegen, ""); + HConstantFolding(graph, visualizer).Run(); + SSAChecker ssa_checker(&allocator, graph); + ssa_checker.Run(); + ASSERT_TRUE(ssa_checker.IsValid()); - StringPrettyPrinter printer_after_cp(graph); - printer_after_cp.VisitInsertionOrder(); - std::string actual_after_cp = printer_after_cp.str(); - ASSERT_EQ(expected_after_cp, actual_after_cp); + StringPrettyPrinter printer_after_cf(graph); + printer_after_cf.VisitInsertionOrder(); + std::string actual_after_cf = printer_after_cf.str(); + ASSERT_EQ(expected_after_cf, actual_after_cf); - check_after_cp(graph); + check_after_cf(graph); - DeadCodeElimination(graph).Run(); + HDeadCodeElimination(graph, visualizer).Run(); + ssa_checker.Run(); + ASSERT_TRUE(ssa_checker.IsValid()); StringPrettyPrinter printer_after_dce(graph); printer_after_dce.VisitInsertionOrder(); std::string actual_after_dce = printer_after_dce.str(); ASSERT_EQ(expected_after_dce, actual_after_dce); - - SSAChecker ssa_checker(&allocator, graph); - ssa_checker.Run(); - ASSERT_TRUE(ssa_checker.IsValid()); } @@ -78,7 +82,7 @@ static void TestCode(const uint16_t* data, * v2 <- v0 + v1 2. add-int v2, v0, v1 * return v2 4. return v2 */ -TEST(ConstantPropagation, IntConstantFoldingOnAddition1) { +TEST(ConstantFolding, IntConstantFoldingOnAddition1) { const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( Instruction::CONST_4 | 0 << 8 | 1 << 12, Instruction::CONST_4 | 1 << 8 | 2 << 12, @@ -97,17 +101,17 @@ TEST(ConstantPropagation, IntConstantFoldingOnAddition1) { "BasicBlock 2, pred: 1\n" " 13: Exit\n"; - // Expected difference after constant propagation. - diff_t expected_cp_diff = { + // Expected difference after constant folding. + diff_t expected_cf_diff = { { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, { " 9: Add(3, 5) [12]\n", " 16: IntConstant [12]\n" }, { " 12: Return(9)\n", " 12: Return(16)\n" } }; - std::string expected_after_cp = Patch(expected_before, expected_cp_diff); + std::string expected_after_cf = Patch(expected_before, expected_cf_diff); // Check the value of the computed constant. - auto check_after_cp = [](HGraph* graph) { + auto check_after_cf = [](HGraph* graph) { HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction(); ASSERT_TRUE(inst->IsIntConstant()); ASSERT_EQ(inst->AsIntConstant()->GetValue(), 3); @@ -118,13 +122,13 @@ TEST(ConstantPropagation, IntConstantFoldingOnAddition1) { { " 3: IntConstant\n", removed }, { " 5: IntConstant\n", removed } }; - std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff); + std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); TestCode(data, expected_before, - expected_after_cp, + expected_after_cf, expected_after_dce, - check_after_cp); + check_after_cf); } /** @@ -142,7 +146,7 @@ TEST(ConstantPropagation, IntConstantFoldingOnAddition1) { * v2 <- v0 + v1 6. add-int v2, v0, v1 * return v2 8. return v2 */ -TEST(ConstantPropagation, IntConstantFoldingOnAddition2) { +TEST(ConstantFolding, IntConstantFoldingOnAddition2) { const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( Instruction::CONST_4 | 0 << 8 | 1 << 12, Instruction::CONST_4 | 1 << 8 | 2 << 12, @@ -169,8 +173,8 @@ TEST(ConstantPropagation, IntConstantFoldingOnAddition2) { "BasicBlock 2, pred: 1\n" " 25: Exit\n"; - // Expected difference after constant propagation. - diff_t expected_cp_diff = { + // Expected difference after constant folding. + diff_t expected_cf_diff = { { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, { " 11: IntConstant [17]\n", " 11: IntConstant\n" }, @@ -180,10 +184,10 @@ TEST(ConstantPropagation, IntConstantFoldingOnAddition2) { { " 21: Add(9, 17) [24]\n", " 30: IntConstant [24]\n" }, { " 24: Return(21)\n", " 24: Return(30)\n" } }; - std::string expected_after_cp = Patch(expected_before, expected_cp_diff); + std::string expected_after_cf = Patch(expected_before, expected_cf_diff); // Check the values of the computed constants. - auto check_after_cp = [](HGraph* graph) { + auto check_after_cf = [](HGraph* graph) { HInstruction* inst1 = graph->GetBlock(1)->GetFirstInstruction(); ASSERT_TRUE(inst1->IsIntConstant()); ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 3); @@ -204,13 +208,13 @@ TEST(ConstantPropagation, IntConstantFoldingOnAddition2) { { " 28: IntConstant\n", removed }, { " 29: IntConstant\n", removed } }; - std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff); + std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); TestCode(data, expected_before, - expected_after_cp, + expected_after_cf, expected_after_dce, - check_after_cp); + check_after_cf); } /** @@ -224,7 +228,7 @@ TEST(ConstantPropagation, IntConstantFoldingOnAddition2) { * v2 <- v0 - v1 2. sub-int v2, v0, v1 * return v2 4. return v2 */ -TEST(ConstantPropagation, IntConstantFoldingOnSubtraction) { +TEST(ConstantFolding, IntConstantFoldingOnSubtraction) { const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( Instruction::CONST_4 | 0 << 8 | 3 << 12, Instruction::CONST_4 | 1 << 8 | 2 << 12, @@ -243,17 +247,17 @@ TEST(ConstantPropagation, IntConstantFoldingOnSubtraction) { "BasicBlock 2, pred: 1\n" " 13: Exit\n"; - // Expected difference after constant propagation. - diff_t expected_cp_diff = { + // Expected difference after constant folding. + diff_t expected_cf_diff = { { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, { " 5: IntConstant [9]\n", " 5: IntConstant\n" }, { " 9: Sub(3, 5) [12]\n", " 16: IntConstant [12]\n" }, { " 12: Return(9)\n", " 12: Return(16)\n" } }; - std::string expected_after_cp = Patch(expected_before, expected_cp_diff); + std::string expected_after_cf = Patch(expected_before, expected_cf_diff); // Check the value of the computed constant. - auto check_after_cp = [](HGraph* graph) { + auto check_after_cf = [](HGraph* graph) { HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction(); ASSERT_TRUE(inst->IsIntConstant()); ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); @@ -264,13 +268,13 @@ TEST(ConstantPropagation, IntConstantFoldingOnSubtraction) { { " 3: IntConstant\n", removed }, { " 5: IntConstant\n", removed } }; - std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff); + std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); TestCode(data, expected_before, - expected_after_cp, + expected_after_cf, expected_after_dce, - check_after_cp); + check_after_cf); } #define SIX_REGISTERS_CODE_ITEM(...) \ @@ -289,7 +293,7 @@ TEST(ConstantPropagation, IntConstantFoldingOnSubtraction) { * (v0, v1) + (v1, v2) 4. add-long v4, v0, v2 * return (v4, v5) 6. return-wide v4 */ -TEST(ConstantPropagation, LongConstantFoldingOnAddition) { +TEST(ConstantFolding, LongConstantFoldingOnAddition) { const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( Instruction::CONST_WIDE_16 | 0 << 8, 1, Instruction::CONST_WIDE_16 | 2 << 8, 2, @@ -308,17 +312,17 @@ TEST(ConstantPropagation, LongConstantFoldingOnAddition) { "BasicBlock 2, pred: 1\n" " 16: Exit\n"; - // Expected difference after constant propagation. - diff_t expected_cp_diff = { + // Expected difference after constant folding. + diff_t expected_cf_diff = { { " 6: LongConstant [12]\n", " 6: LongConstant\n" }, { " 8: LongConstant [12]\n", " 8: LongConstant\n" }, { " 12: Add(6, 8) [15]\n", " 19: LongConstant [15]\n" }, { " 15: Return(12)\n", " 15: Return(19)\n" } }; - std::string expected_after_cp = Patch(expected_before, expected_cp_diff); + std::string expected_after_cf = Patch(expected_before, expected_cf_diff); // Check the value of the computed constant. - auto check_after_cp = [](HGraph* graph) { + auto check_after_cf = [](HGraph* graph) { HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction(); ASSERT_TRUE(inst->IsLongConstant()); ASSERT_EQ(inst->AsLongConstant()->GetValue(), 3); @@ -329,13 +333,13 @@ TEST(ConstantPropagation, LongConstantFoldingOnAddition) { { " 6: LongConstant\n", removed }, { " 8: LongConstant\n", removed } }; - std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff); + std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); TestCode(data, expected_before, - expected_after_cp, + expected_after_cf, expected_after_dce, - check_after_cp, + check_after_cf, Primitive::kPrimLong); } @@ -352,7 +356,7 @@ TEST(ConstantPropagation, LongConstantFoldingOnAddition) { * (v0, v1) - (v1, v2) 4. sub-long v4, v0, v2 * return (v4, v5) 6. return-wide v4 */ -TEST(ConstantPropagation, LongConstantFoldingOnSubtraction) { +TEST(ConstantFolding, LongConstantFoldingOnSubtraction) { const uint16_t data[] = SIX_REGISTERS_CODE_ITEM( Instruction::CONST_WIDE_16 | 0 << 8, 3, Instruction::CONST_WIDE_16 | 2 << 8, 2, @@ -371,17 +375,17 @@ TEST(ConstantPropagation, LongConstantFoldingOnSubtraction) { "BasicBlock 2, pred: 1\n" " 16: Exit\n"; - // Expected difference after constant propagation. - diff_t expected_cp_diff = { + // Expected difference after constant folding. + diff_t expected_cf_diff = { { " 6: LongConstant [12]\n", " 6: LongConstant\n" }, { " 8: LongConstant [12]\n", " 8: LongConstant\n" }, { " 12: Sub(6, 8) [15]\n", " 19: LongConstant [15]\n" }, { " 15: Return(12)\n", " 15: Return(19)\n" } }; - std::string expected_after_cp = Patch(expected_before, expected_cp_diff); + std::string expected_after_cf = Patch(expected_before, expected_cf_diff); // Check the value of the computed constant. - auto check_after_cp = [](HGraph* graph) { + auto check_after_cf = [](HGraph* graph) { HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction(); ASSERT_TRUE(inst->IsLongConstant()); ASSERT_EQ(inst->AsLongConstant()->GetValue(), 1); @@ -392,13 +396,13 @@ TEST(ConstantPropagation, LongConstantFoldingOnSubtraction) { { " 6: LongConstant\n", removed }, { " 8: LongConstant\n", removed } }; - std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff); + std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); TestCode(data, expected_before, - expected_after_cp, + expected_after_cf, expected_after_dce, - check_after_cp, + check_after_cf, Primitive::kPrimLong); } @@ -424,7 +428,7 @@ TEST(ConstantPropagation, LongConstantFoldingOnSubtraction) { * L3: v2 <- v1 + 4 11. add-int/lit16 v2, v1, #+4 * return v2 13. return v2 */ -TEST(ConstantPropagation, IntConstantFoldingAndJumps) { +TEST(ConstantFolding, IntConstantFoldingAndJumps) { const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( Instruction::CONST_4 | 0 << 8 | 0 << 12, Instruction::CONST_4 | 1 << 8 | 1 << 12, @@ -462,8 +466,8 @@ TEST(ConstantPropagation, IntConstantFoldingAndJumps) { "BasicBlock 5, pred: 4\n" " 29: Exit\n"; - // Expected difference after constant propagation. - diff_t expected_cp_diff = { + // Expected difference after constant folding. + diff_t expected_cf_diff = { { " 3: IntConstant [9]\n", " 3: IntConstant\n" }, { " 5: IntConstant [9]\n", " 5: IntConstant []\n" }, { " 13: IntConstant [14]\n", " 13: IntConstant\n" }, @@ -475,10 +479,10 @@ TEST(ConstantPropagation, IntConstantFoldingAndJumps) { { " 25: Add(14, 24) [28]\n", " 35: IntConstant [28]\n" }, { " 28: Return(25)\n", " 28: Return(35)\n"} }; - std::string expected_after_cp = Patch(expected_before, expected_cp_diff); + std::string expected_after_cf = Patch(expected_before, expected_cf_diff); // Check the values of the computed constants. - auto check_after_cp = [](HGraph* graph) { + auto check_after_cf = [](HGraph* graph) { HInstruction* inst1 = graph->GetBlock(1)->GetFirstInstruction(); ASSERT_TRUE(inst1->IsIntConstant()); ASSERT_EQ(inst1->AsIntConstant()->GetValue(), 1); @@ -501,13 +505,13 @@ TEST(ConstantPropagation, IntConstantFoldingAndJumps) { { " 24: IntConstant\n", removed }, { " 34: IntConstant\n", removed }, }; - std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff); + std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); TestCode(data, expected_before, - expected_after_cp, + expected_after_cf, expected_after_dce, - check_after_cp); + check_after_cf); } @@ -524,7 +528,7 @@ TEST(ConstantPropagation, IntConstantFoldingAndJumps) { * L1: v2 <- v0 + v1 5. add-int v2, v0, v1 * return-void 7. return */ -TEST(ConstantPropagation, ConstantCondition) { +TEST(ConstantFolding, ConstantCondition) { const uint16_t data[] = THREE_REGISTERS_CODE_ITEM( Instruction::CONST_4 | 1 << 8 | 1 << 12, Instruction::CONST_4 | 0 << 8 | 0 << 12, @@ -553,17 +557,17 @@ TEST(ConstantPropagation, ConstantCondition) { "BasicBlock 5, pred: 1, succ: 3\n" " 21: Goto 3\n"; - // Expected difference after constant propagation. - diff_t expected_cp_diff = { + // Expected difference after constant folding. + diff_t expected_cf_diff = { { " 3: IntConstant [15, 22, 8]\n", " 3: IntConstant [15, 22]\n" }, { " 5: IntConstant [22, 8]\n", " 5: IntConstant [22]\n" }, { " 8: GreaterThanOrEqual(3, 5) [9]\n", " 23: IntConstant [9]\n" }, { " 9: If(8)\n", " 9: If(23)\n" } }; - std::string expected_after_cp = Patch(expected_before, expected_cp_diff); + std::string expected_after_cf = Patch(expected_before, expected_cf_diff); // Check the values of the computed constants. - auto check_after_cp = [](HGraph* graph) { + auto check_after_cf = [](HGraph* graph) { HInstruction* inst = graph->GetBlock(1)->GetFirstInstruction(); ASSERT_TRUE(inst->IsIntConstant()); ASSERT_EQ(inst->AsIntConstant()->GetValue(), 1); @@ -575,13 +579,13 @@ TEST(ConstantPropagation, ConstantCondition) { { " 22: Phi(3, 5) [15]\n", " 22: Phi(3, 5)\n" }, { " 15: Add(22, 3)\n", removed } }; - std::string expected_after_dce = Patch(expected_after_cp, expected_dce_diff); + std::string expected_after_dce = Patch(expected_after_cf, expected_dce_diff); TestCode(data, expected_before, - expected_after_cp, + expected_after_cf, expected_after_dce, - check_after_cp); + check_after_cf); } } // namespace art diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index 5655544..fc3dd01 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -20,7 +20,7 @@ namespace art { -void DeadCodeElimination::Run() { +void HDeadCodeElimination::Run() { // Process basic blocks in post-order in the dominator tree, so that // a dead instruction depending on another dead instruction is // removed. diff --git a/compiler/optimizing/dead_code_elimination.h b/compiler/optimizing/dead_code_elimination.h index 48739be..a4446ae 100644 --- a/compiler/optimizing/dead_code_elimination.h +++ b/compiler/optimizing/dead_code_elimination.h @@ -18,6 +18,7 @@ #define ART_COMPILER_OPTIMIZING_DEAD_CODE_ELIMINATION_H_ #include "nodes.h" +#include "optimization.h" namespace art { @@ -25,17 +26,18 @@ namespace art { * Optimization pass performing dead code elimination (removal of * unused variables/instructions) on the SSA form. */ -class DeadCodeElimination : public ValueObject { +class HDeadCodeElimination : public HOptimization { public: - explicit DeadCodeElimination(HGraph* graph) - : graph_(graph) {} + HDeadCodeElimination(HGraph* graph, const HGraphVisualizer& visualizer) + : HOptimization(graph, true, kDeadCodeEliminationPassName, visualizer) {} - void Run(); + virtual void Run() OVERRIDE; - private: - HGraph* const graph_; + static constexpr const char* kDeadCodeEliminationPassName = + "dead_code_elimination"; - DISALLOW_COPY_AND_ASSIGN(DeadCodeElimination); + private: + DISALLOW_COPY_AND_ASSIGN(HDeadCodeElimination); }; } // namespace art diff --git a/compiler/optimizing/dead_code_elimination_test.cc b/compiler/optimizing/dead_code_elimination_test.cc index 3e0ba3a..0c68074 100644 --- a/compiler/optimizing/dead_code_elimination_test.cc +++ b/compiler/optimizing/dead_code_elimination_test.cc @@ -14,10 +14,11 @@ * limitations under the License. */ +#include "code_generator_x86.h" #include "dead_code_elimination.h" -#include "pretty_printer.h" #include "graph_checker.h" #include "optimizing_unit_test.h" +#include "pretty_printer.h" #include "gtest/gtest.h" @@ -39,16 +40,17 @@ static void TestCode(const uint16_t* data, std::string actual_before = printer_before.str(); ASSERT_EQ(actual_before, expected_before); - DeadCodeElimination(graph).Run(); + x86::CodeGeneratorX86 codegen(graph); + HGraphVisualizer visualizer(nullptr, graph, codegen, ""); + HDeadCodeElimination(graph, visualizer).Run(); + SSAChecker ssa_checker(&allocator, graph); + ssa_checker.Run(); + ASSERT_TRUE(ssa_checker.IsValid()); StringPrettyPrinter printer_after(graph); printer_after.VisitInsertionOrder(); std::string actual_after = printer_after.str(); ASSERT_EQ(actual_after, expected_after); - - SSAChecker ssa_checker(&allocator, graph); - ssa_checker.Run(); - ASSERT_TRUE(ssa_checker.IsValid()); } @@ -94,6 +96,7 @@ TEST(DeadCodeElimination, AdditionAndConditionalJump) { "BasicBlock 5, pred: 1, succ: 3\n" " 21: Goto 3\n"; + // Expected difference after dead code elimination. diff_t expected_diff = { { " 3: IntConstant [15, 22, 8]\n", " 3: IntConstant [22, 8]\n" }, { " 22: Phi(3, 5) [15]\n", " 22: Phi(3, 5)\n" }, @@ -164,7 +167,7 @@ TEST(DeadCodeElimination, AdditionsAndInconditionalJumps) { "BasicBlock 5, pred: 4\n" " 28: Exit\n"; - // Expected difference after constant propagation. + // Expected difference after dead code elimination. diff_t expected_diff = { { " 13: IntConstant [14]\n", removed }, { " 24: IntConstant [25]\n", removed }, diff --git a/compiler/optimizing/graph_checker.h b/compiler/optimizing/graph_checker.h index 862f1b6..db31306 100644 --- a/compiler/optimizing/graph_checker.h +++ b/compiler/optimizing/graph_checker.h @@ -19,15 +19,19 @@ #include "nodes.h" +#include <ostream> + namespace art { // A control-flow graph visitor performing various checks. class GraphChecker : public HGraphVisitor { public: - GraphChecker(ArenaAllocator* allocator, HGraph* graph) + GraphChecker(ArenaAllocator* allocator, HGraph* graph, + const char* dump_prefix = "art::GraphChecker: ") : HGraphVisitor(graph), allocator_(allocator), - errors_(allocator, 0) {} + errors_(allocator, 0), + dump_prefix_(dump_prefix) {} // Check the whole graph (in insertion order). virtual void Run() { VisitInsertionOrder(); } @@ -48,6 +52,13 @@ class GraphChecker : public HGraphVisitor { return errors_; } + // Print detected errors on output stream `os`. + void Dump(std::ostream& os) { + for (size_t i = 0, e = errors_.Size(); i < e; ++i) { + os << dump_prefix_ << errors_.Get(i) << std::endl; + } + } + protected: ArenaAllocator* const allocator_; // The block currently visited. @@ -56,6 +67,9 @@ class GraphChecker : public HGraphVisitor { GrowableArray<std::string> errors_; private: + // String displayed before dumped errors. + const char* dump_prefix_; + DISALLOW_COPY_AND_ASSIGN(GraphChecker); }; @@ -66,7 +80,7 @@ class SSAChecker : public GraphChecker { typedef GraphChecker super_type; SSAChecker(ArenaAllocator* allocator, HGraph* graph) - : GraphChecker(allocator, graph) {} + : GraphChecker(allocator, graph, "art::SSAChecker: ") {} // Check the whole graph (in reverse post-order). virtual void Run() { diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index b4eb89d..459010d 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -309,7 +309,7 @@ HGraphVisualizer::HGraphVisualizer(std::ostream* output, printer.EndTag("compilation"); } -void HGraphVisualizer::DumpGraph(const char* pass_name) { +void HGraphVisualizer::DumpGraph(const char* pass_name) const { if (!is_enabled_) { return; } diff --git a/compiler/optimizing/graph_visualizer.h b/compiler/optimizing/graph_visualizer.h index f17ba3b..05984a0 100644 --- a/compiler/optimizing/graph_visualizer.h +++ b/compiler/optimizing/graph_visualizer.h @@ -61,7 +61,7 @@ class HGraphVisualizer : public ValueObject { * If this visualizer is enabled, emit the compilation information * in `output_`. */ - void DumpGraph(const char* pass_name); + void DumpGraph(const char* pass_name) const; private: std::ostream* const output_; diff --git a/compiler/optimizing/constant_propagation.h b/compiler/optimizing/optimization.cc index 0729881..33dc040 100644 --- a/compiler/optimizing/constant_propagation.h +++ b/compiler/optimizing/optimization.cc @@ -14,30 +14,34 @@ * limitations under the License. */ -#ifndef ART_COMPILER_OPTIMIZING_CONSTANT_PROPAGATION_H_ -#define ART_COMPILER_OPTIMIZING_CONSTANT_PROPAGATION_H_ +#include "optimization.h" -#include "nodes.h" +#include "graph_checker.h" namespace art { -/** - * Optimization pass performing a simple constant propagation on the - * SSA form. - */ -class ConstantPropagation : public ValueObject { - public: - explicit ConstantPropagation(HGraph* graph) - : graph_(graph) {} - - void Run(); - - private: - HGraph* const graph_; - - DISALLOW_COPY_AND_ASSIGN(ConstantPropagation); -}; +void HOptimization::Execute() { + Run(); + visualizer_.DumpGraph(pass_name_); + Check(); +} + +void HOptimization::Check() { + if (kIsDebugBuild) { + if (is_in_ssa_form_) { + SSAChecker checker(graph_->GetArena(), graph_); + checker.Run(); + if (!checker.IsValid()) { + LOG(FATAL) << Dumpable<SSAChecker>(checker); + } + } else { + GraphChecker checker(graph_->GetArena(), graph_); + checker.Run(); + if (!checker.IsValid()) { + LOG(FATAL) << Dumpable<GraphChecker>(checker); + } + } + } +} } // namespace art - -#endif // ART_COMPILER_OPTIMIZING_CONSTANT_PROPAGATION_H_ diff --git a/compiler/optimizing/optimization.h b/compiler/optimizing/optimization.h new file mode 100644 index 0000000..59683e2 --- /dev/null +++ b/compiler/optimizing/optimization.h @@ -0,0 +1,71 @@ +/* + * 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. + */ + +#ifndef ART_COMPILER_OPTIMIZING_OPTIMIZATION_H_ +#define ART_COMPILER_OPTIMIZING_OPTIMIZATION_H_ + +#include "graph_visualizer.h" +#include "nodes.h" + +namespace art { + +/** + * Abstraction to implement an optimization pass. + */ +class HOptimization : public ValueObject { + public: + HOptimization(HGraph* graph, + bool is_in_ssa_form, + const char* pass_name, + const HGraphVisualizer& visualizer) + : graph_(graph), + is_in_ssa_form_(is_in_ssa_form), + pass_name_(pass_name), + visualizer_(visualizer) {} + + virtual ~HOptimization() {} + + // Execute the optimization pass. + void Execute(); + + // Return the name of the pass. + const char* GetPassName() const { return pass_name_; } + + // Peform the analysis itself. + virtual void Run() = 0; + + private: + // Verify the graph; abort if it is not valid. + void Check(); + + protected: + HGraph* const graph_; + + private: + // Does the analyzed graph use the SSA form? + const bool is_in_ssa_form_; + // Optimization pass name. + const char* pass_name_; + // A graph visualiser invoked after the execution of the optimization + // pass if enabled. + const HGraphVisualizer& visualizer_; + + DISALLOW_COPY_AND_ASSIGN(HOptimization); +}; + +} // namespace art + +#endif // ART_COMPILER_OPTIMIZING_OPTIMIZATION_H_ diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 3cf5a0b..dce8e6d 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -22,6 +22,8 @@ #include "builder.h" #include "code_generator.h" #include "compiler.h" +#include "constant_folding.h" +#include "dead_code_elimination.h" #include "driver/compiler_driver.h" #include "driver/dex_compilation_unit.h" #include "graph_visualizer.h" @@ -261,6 +263,9 @@ CompiledMethod* OptimizingCompiler::TryCompile(const DexFile::CodeItem* code_ite visualizer.DumpGraph("ssa"); graph->FindNaturalLoops(); + HDeadCodeElimination(graph, visualizer).Execute(); + HConstantFolding(graph, visualizer).Execute(); + SsaRedundantPhiElimination(graph).Run(); SsaDeadPhiElimination(graph).Run(); InstructionSimplifier(graph).Run(); |