compiler/oat_test.cc \
compiler/optimizing/codegen_test.cc \
compiler/optimizing/dead_code_elimination_test.cc \
- compiler/optimizing/constant_folding_test.cc \
+ compiler/optimizing/constant_propagation_test.cc \
compiler/optimizing/dominator_test.cc \
compiler/optimizing/find_loops_test.cc \
compiler/optimizing/graph_checker_test.cc \
optimizing/code_generator_arm.cc \
optimizing/code_generator_x86.cc \
optimizing/code_generator_x86_64.cc \
- optimizing/constant_folding.cc \
+ optimizing/constant_propagation.cc \
optimizing/dead_code_elimination.cc \
optimizing/graph_checker.cc \
optimizing/graph_visualizer.cc \
optimizing/instruction_simplifier.cc \
optimizing/locations.cc \
optimizing/nodes.cc \
- optimizing/optimization.cc \
optimizing/optimizing_compiler.cc \
optimizing/parallel_move_resolver.cc \
optimizing/register_allocator.cc \
+++ /dev/null
-/*
- * 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_
* limitations under the License.
*/
-#include "constant_folding.h"
+#include "constant_propagation.h"
namespace art {
-void HConstantFolding::Run() {
+void ConstantPropagation::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
* limitations under the License.
*/
-#include "optimization.h"
+#ifndef ART_COMPILER_OPTIMIZING_CONSTANT_PROPAGATION_H_
+#define ART_COMPILER_OPTIMIZING_CONSTANT_PROPAGATION_H_
-#include "graph_checker.h"
+#include "nodes.h"
namespace art {
-void HOptimization::Execute() {
- Run();
- visualizer_.DumpGraph(pass_name_);
- Check();
-}
-
-void HOptimization::Check() {
- if (kIsDebugBuild) {
- if (is_in_ssa_form_) {
- SSAChecker checker(graph_->GetArena(), graph_);
- CheckInternal(&checker);
- } else {
- GraphChecker checker(graph_->GetArena(), graph_);
- CheckInternal(&checker);
- }
- }
-}
+/**
+ * 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);
+};
} // namespace art
+
+#endif // ART_COMPILER_OPTIMIZING_CONSTANT_PROPAGATION_H_
* limitations under the License.
*/
-#include "code_generator_x86.h"
-#include "constant_folding.h"
+#include "constant_propagation.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"
std::string actual_before = printer_before.str();
ASSERT_EQ(expected_before, actual_before);
- x86::CodeGeneratorX86 codegen(graph);
- HGraphVisualizer visualizer(nullptr, graph, codegen, "");
- HConstantFolding(graph, visualizer).Run();
- SSAChecker ssa_checker(&allocator, graph);
- ssa_checker.VisitInsertionOrder();
- ASSERT_TRUE(ssa_checker.IsValid());
+ ConstantPropagation(graph).Run();
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);
- HDeadCodeElimination(graph, visualizer).Run();
- ssa_checker.VisitInsertionOrder();
- ASSERT_TRUE(ssa_checker.IsValid());
+ DeadCodeElimination(graph).Run();
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.VisitInsertionOrder();
+ ASSERT_TRUE(ssa_checker.IsValid());
}
* v2 <- v0 + v1 2. add-int v2, v0, v1
* return v2 4. return v2
*/
-TEST(ConstantFolding, IntConstantFoldingOnAddition1) {
+TEST(ConstantPropagation, IntConstantFoldingOnAddition1) {
const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
Instruction::CONST_4 | 0 << 8 | 1 << 12,
Instruction::CONST_4 | 1 << 8 | 2 << 12,
"BasicBlock 2, pred: 1\n"
" 13: Exit\n";
- // Expected difference after constant folding.
+ // Expected difference after constant propagation.
diff_t expected_cp_diff = {
{ " 3: IntConstant [9]\n", " 3: IntConstant\n" },
{ " 5: IntConstant [9]\n", " 5: IntConstant\n" },
* v2 <- v0 + v1 6. add-int v2, v0, v1
* return v2 8. return v2
*/
-TEST(ConstantFolding, IntConstantFoldingOnAddition2) {
+TEST(ConstantPropagation, IntConstantFoldingOnAddition2) {
const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
Instruction::CONST_4 | 0 << 8 | 1 << 12,
Instruction::CONST_4 | 1 << 8 | 2 << 12,
"BasicBlock 2, pred: 1\n"
" 25: Exit\n";
- // Expected difference after constant folding.
+ // Expected difference after constant propagation.
diff_t expected_cp_diff = {
{ " 3: IntConstant [9]\n", " 3: IntConstant\n" },
{ " 5: IntConstant [9]\n", " 5: IntConstant\n" },
* v2 <- v0 - v1 2. sub-int v2, v0, v1
* return v2 4. return v2
*/
-TEST(ConstantFolding, IntConstantFoldingOnSubtraction) {
+TEST(ConstantPropagation, IntConstantFoldingOnSubtraction) {
const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
Instruction::CONST_4 | 0 << 8 | 3 << 12,
Instruction::CONST_4 | 1 << 8 | 2 << 12,
"BasicBlock 2, pred: 1\n"
" 13: Exit\n";
- // Expected difference after constant folding.
+ // Expected difference after constant propagation.
diff_t expected_cp_diff = {
{ " 3: IntConstant [9]\n", " 3: IntConstant\n" },
{ " 5: IntConstant [9]\n", " 5: IntConstant\n" },
* (v0, v1) + (v1, v2) 4. add-long v4, v0, v2
* return (v4, v5) 6. return-wide v4
*/
-TEST(ConstantFolding, LongConstantFoldingOnAddition) {
+TEST(ConstantPropagation, LongConstantFoldingOnAddition) {
const uint16_t data[] = SIX_REGISTERS_CODE_ITEM(
Instruction::CONST_WIDE_16 | 0 << 8, 1,
Instruction::CONST_WIDE_16 | 2 << 8, 2,
"BasicBlock 2, pred: 1\n"
" 16: Exit\n";
- // Expected difference after constant folding.
+ // Expected difference after constant propagation.
diff_t expected_cp_diff = {
{ " 6: LongConstant [12]\n", " 6: LongConstant\n" },
{ " 8: LongConstant [12]\n", " 8: LongConstant\n" },
* (v0, v1) - (v1, v2) 4. sub-long v4, v0, v2
* return (v4, v5) 6. return-wide v4
*/
-TEST(ConstantFolding, LongConstantFoldingOnSubtraction) {
+TEST(ConstantPropagation, LongConstantFoldingOnSubtraction) {
const uint16_t data[] = SIX_REGISTERS_CODE_ITEM(
Instruction::CONST_WIDE_16 | 0 << 8, 3,
Instruction::CONST_WIDE_16 | 2 << 8, 2,
"BasicBlock 2, pred: 1\n"
" 16: Exit\n";
- // Expected difference after constant folding.
+ // Expected difference after constant propagation.
diff_t expected_cp_diff = {
{ " 6: LongConstant [12]\n", " 6: LongConstant\n" },
{ " 8: LongConstant [12]\n", " 8: LongConstant\n" },
* L3: v2 <- v1 + 4 11. add-int/lit16 v2, v1, #+4
* return v2 13. return v2
*/
-TEST(ConstantFolding, IntConstantFoldingAndJumps) {
+TEST(ConstantPropagation, IntConstantFoldingAndJumps) {
const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
Instruction::CONST_4 | 0 << 8 | 0 << 12,
Instruction::CONST_4 | 1 << 8 | 1 << 12,
"BasicBlock 5, pred: 4\n"
" 29: Exit\n";
- // Expected difference after constant folding.
+ // Expected difference after constant propagation.
diff_t expected_cp_diff = {
{ " 3: IntConstant [9]\n", " 3: IntConstant\n" },
{ " 5: IntConstant [9]\n", " 5: IntConstant []\n" },
* L1: v2 <- v0 + v1 5. add-int v2, v0, v1
* return-void 7. return
*/
-TEST(ConstantFolding, ConstantCondition) {
+TEST(ConstantPropagation, ConstantCondition) {
const uint16_t data[] = THREE_REGISTERS_CODE_ITEM(
Instruction::CONST_4 | 1 << 8 | 1 << 12,
Instruction::CONST_4 | 0 << 8 | 0 << 12,
"BasicBlock 5, pred: 1, succ: 3\n"
" 21: Goto 3\n";
- // Expected difference after constant folding.
+ // Expected difference after constant propagation.
diff_t expected_cp_diff = {
{ " 3: IntConstant [15, 22, 8]\n", " 3: IntConstant [15, 22]\n" },
{ " 5: IntConstant [22, 8]\n", " 5: IntConstant [22]\n" },
namespace art {
-void HDeadCodeElimination::Run() {
+void DeadCodeElimination::Run() {
// Process basic blocks in post-order in the dominator tree, so that
// a dead instruction depending on another dead instruction is
// removed.
#define ART_COMPILER_OPTIMIZING_DEAD_CODE_ELIMINATION_H_
#include "nodes.h"
-#include "optimization.h"
namespace art {
* Optimization pass performing dead code elimination (removal of
* unused variables/instructions) on the SSA form.
*/
-class HDeadCodeElimination : public HOptimization {
+class DeadCodeElimination : public ValueObject {
public:
- HDeadCodeElimination(HGraph* graph, const HGraphVisualizer& visualizer)
- : HOptimization(graph, true, kDeadCodeEliminationPassName, visualizer) {}
+ explicit DeadCodeElimination(HGraph* graph)
+ : graph_(graph) {}
- virtual void Run() OVERRIDE;
-
- static constexpr const char* kDeadCodeEliminationPassName =
- "dead_code_elimination";
+ void Run();
private:
- DISALLOW_COPY_AND_ASSIGN(HDeadCodeElimination);
+ HGraph* const graph_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeadCodeElimination);
};
} // namespace art
* 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"
std::string actual_before = printer_before.str();
ASSERT_EQ(actual_before, expected_before);
- x86::CodeGeneratorX86 codegen(graph);
- HGraphVisualizer visualizer(nullptr, graph, codegen, "");
- HDeadCodeElimination(graph, visualizer).Run();
- SSAChecker ssa_checker(&allocator, graph);
- ssa_checker.VisitInsertionOrder();
- ASSERT_TRUE(ssa_checker.IsValid());
+ DeadCodeElimination(graph).Run();
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.VisitInsertionOrder();
+ ASSERT_TRUE(ssa_checker.IsValid());
}
"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" },
"BasicBlock 5, pred: 4\n"
" 28: Exit\n";
- // Expected difference after dead code elimination.
+ // Expected difference after constant propagation.
diff_t expected_diff = {
{ " 13: IntConstant [14]\n", removed },
{ " 24: IntConstant [25]\n", removed },
#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,
- const char* dump_prefix = "art::GraphChecker: ")
+ GraphChecker(ArenaAllocator* allocator, HGraph* graph)
: HGraphVisitor(graph),
allocator_(allocator),
- errors_(allocator, 0),
- dump_prefix_(dump_prefix) {}
+ errors_(allocator, 0) {}
// Check `block`.
virtual void VisitBasicBlock(HBasicBlock* block) OVERRIDE;
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.
GrowableArray<std::string> errors_;
private:
- // String displayed before dumped errors.
- const char* dump_prefix_;
-
DISALLOW_COPY_AND_ASSIGN(GraphChecker);
};
typedef GraphChecker super_type;
SSAChecker(ArenaAllocator* allocator, HGraph* graph)
- : GraphChecker(allocator, graph, "art::SSAChecker: ") {}
+ : GraphChecker(allocator, graph) {}
// Perform SSA form checks on `block`.
virtual void VisitBasicBlock(HBasicBlock* block) OVERRIDE;
printer.EndTag("compilation");
}
-void HGraphVisualizer::DumpGraph(const char* pass_name) const {
+void HGraphVisualizer::DumpGraph(const char* pass_name) {
if (!is_enabled_) {
return;
}
* If this visualizer is enabled, emit the compilation information
* in `output_`.
*/
- void DumpGraph(const char* pass_name) const;
+ void DumpGraph(const char* pass_name);
private:
std::ostream* const output_;
+++ /dev/null
-/*
- * 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();
-
- template <typename T>
- void CheckInternal(T* checker) {
- checker->VisitInsertionOrder();
- if (!checker->IsValid()) {
- LOG(FATAL) << Dumpable<T>(*checker);
- }
- }
-
- protected:
- HGraph* const graph_;
-
- private:
- // Does the analyzed graph use SSA form?
- bool is_in_ssa_form_;
- // Optimization pass name.
- const char* pass_name_;
- // A graph visualiser invoked during the execution of the
- // optimization pass if non null.
- const HGraphVisualizer& visualizer_;
-
- DISALLOW_COPY_AND_ASSIGN(HOptimization);
-};
-
-} // namespace art
-
-#endif // ART_COMPILER_OPTIMIZING_OPTIMIZATION_H_
#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"
visualizer.DumpGraph("ssa");
graph->FindNaturalLoops();
- HDeadCodeElimination(graph, visualizer).Execute();
- HConstantFolding(graph, visualizer).Execute();
-
SsaRedundantPhiElimination(graph).Run();
SsaDeadPhiElimination(graph).Run();
InstructionSimplifier(graph).Run();