Dead code elimination based on GVN results.
Change-Id: I5b77411a8f088f0b561da14b123cf6b0501c9db5
diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc
index dac0210..2f547ea 100644
--- a/compiler/dex/mir_optimization.cc
+++ b/compiler/dex/mir_optimization.cc
@@ -21,6 +21,7 @@
#include "driver/compiler_driver.h"
#include "driver/dex_compilation_unit.h"
#include "global_value_numbering.h"
+#include "gvn_dead_code_elimination.h"
#include "local_value_numbering.h"
#include "mir_field_info.h"
#include "quick/dex_file_method_inliner.h"
@@ -1333,9 +1334,9 @@
DCHECK(temp_scoped_alloc_ == nullptr);
temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack));
- temp_.gvn.ifield_ids_ =
+ temp_.gvn.ifield_ids =
GlobalValueNumbering::PrepareGvnFieldIds(temp_scoped_alloc_.get(), ifield_lowering_infos_);
- temp_.gvn.sfield_ids_ =
+ temp_.gvn.sfield_ids =
GlobalValueNumbering::PrepareGvnFieldIds(temp_scoped_alloc_.get(), sfield_lowering_infos_);
DCHECK(temp_.gvn.gvn == nullptr);
temp_.gvn.gvn = new (temp_scoped_alloc_.get()) GlobalValueNumbering(
@@ -1359,8 +1360,8 @@
// Perform modifications.
DCHECK(temp_.gvn.gvn != nullptr);
if (temp_.gvn.gvn->Good()) {
+ temp_.gvn.gvn->StartPostProcessing();
if (max_nested_loops_ != 0u) {
- temp_.gvn.gvn->StartPostProcessing();
TopologicalSortIterator iter(this);
for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) {
ScopedArenaAllocator allocator(&cu_->arena_stack); // Reclaim memory after each LVN.
@@ -1378,12 +1379,45 @@
cu_->disable_opt |= (1u << kLocalValueNumbering);
} else {
LOG(WARNING) << "GVN failed for " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
+ cu_->disable_opt |= (1u << kGvnDeadCodeElimination);
}
+ if ((cu_->disable_opt & (1 << kGvnDeadCodeElimination)) != 0) {
+ EliminateDeadCodeEnd();
+ } // else preserve GVN data for CSE.
+}
+
+bool MIRGraph::EliminateDeadCodeGate() {
+ if ((cu_->disable_opt & (1 << kGvnDeadCodeElimination)) != 0) {
+ return false;
+ }
+ DCHECK(temp_scoped_alloc_ != nullptr);
+ temp_.gvn.dce = new (temp_scoped_alloc_.get()) GvnDeadCodeElimination(temp_.gvn.gvn,
+ temp_scoped_alloc_.get());
+ return true;
+}
+
+bool MIRGraph::EliminateDeadCode(BasicBlock* bb) {
+ DCHECK(temp_scoped_alloc_ != nullptr);
+ DCHECK(temp_.gvn.gvn != nullptr);
+ if (bb->block_type != kDalvikByteCode) {
+ return false;
+ }
+ DCHECK(temp_.gvn.dce != nullptr);
+ temp_.gvn.dce->Apply(bb);
+ return false; // No need to repeat.
+}
+
+void MIRGraph::EliminateDeadCodeEnd() {
+ DCHECK_EQ(temp_.gvn.dce != nullptr, (cu_->disable_opt & (1 << kGvnDeadCodeElimination)) == 0);
+ if (temp_.gvn.dce != nullptr) {
+ delete temp_.gvn.dce;
+ temp_.gvn.dce = nullptr;
+ }
delete temp_.gvn.gvn;
temp_.gvn.gvn = nullptr;
- temp_.gvn.ifield_ids_ = nullptr;
- temp_.gvn.sfield_ids_ = nullptr;
+ temp_.gvn.ifield_ids = nullptr;
+ temp_.gvn.sfield_ids = nullptr;
DCHECK(temp_scoped_alloc_ != nullptr);
temp_scoped_alloc_.reset();
}
@@ -1553,9 +1587,9 @@
void MIRGraph::BasicBlockOptimizationStart() {
if ((cu_->disable_opt & (1 << kLocalValueNumbering)) == 0) {
temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack));
- temp_.gvn.ifield_ids_ =
+ temp_.gvn.ifield_ids =
GlobalValueNumbering::PrepareGvnFieldIds(temp_scoped_alloc_.get(), ifield_lowering_infos_);
- temp_.gvn.sfield_ids_ =
+ temp_.gvn.sfield_ids =
GlobalValueNumbering::PrepareGvnFieldIds(temp_scoped_alloc_.get(), sfield_lowering_infos_);
}
}
@@ -1581,8 +1615,8 @@
void MIRGraph::BasicBlockOptimizationEnd() {
// Clean up after LVN.
- temp_.gvn.ifield_ids_ = nullptr;
- temp_.gvn.sfield_ids_ = nullptr;
+ temp_.gvn.ifield_ids = nullptr;
+ temp_.gvn.sfield_ids = nullptr;
temp_scoped_alloc_.reset();
}
@@ -1684,7 +1718,7 @@
temp_.sce.inliner = nullptr;
}
-bool MIRGraph::CanThrow(MIR* mir) {
+bool MIRGraph::CanThrow(MIR* mir) const {
if ((mir->dalvikInsn.FlagsOf() & Instruction::kThrow) == 0) {
return false;
}
@@ -1718,7 +1752,6 @@
// Non-throwing only if range check has been eliminated.
return ((opt_flags & MIR_IGNORE_RANGE_CHECK) == 0);
} else if (mir->dalvikInsn.opcode == Instruction::ARRAY_LENGTH ||
- mir->dalvikInsn.opcode == Instruction::FILL_ARRAY_DATA ||
static_cast<int>(mir->dalvikInsn.opcode) == kMirOpNullCheck) {
// No more checks for these (null check was processed above).
return false;