summaryrefslogtreecommitdiffstats
path: root/compiler/dex/global_value_numbering.cc
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2014-07-29 12:04:10 +0100
committerVladimir Marko <vmarko@google.com>2014-07-31 09:57:09 +0100
commitb19955d3c8fbd9588f7e17299e559d02938154b6 (patch)
tree10113a67776d1bb050115043e47e6970a85103c5 /compiler/dex/global_value_numbering.cc
parent36b111c7d3d635e262114dabde4c26952c7dcbe6 (diff)
downloadart-b19955d3c8fbd9588f7e17299e559d02938154b6.zip
art-b19955d3c8fbd9588f7e17299e559d02938154b6.tar.gz
art-b19955d3c8fbd9588f7e17299e559d02938154b6.tar.bz2
Reduce time and memory usage of GVN.
Filter out dead sregs in GVN. Reclaim memory after each LVN in the GVN modification phase. Bug: 16398693 Change-Id: I8c88c3009663754e1b66c0ef3f62c3b93276e385
Diffstat (limited to 'compiler/dex/global_value_numbering.cc')
-rw-r--r--compiler/dex/global_value_numbering.cc26
1 files changed, 19 insertions, 7 deletions
diff --git a/compiler/dex/global_value_numbering.cc b/compiler/dex/global_value_numbering.cc
index d86be4e..d7ef6f0 100644
--- a/compiler/dex/global_value_numbering.cc
+++ b/compiler/dex/global_value_numbering.cc
@@ -43,7 +43,8 @@ GlobalValueNumbering::~GlobalValueNumbering() {
STLDeleteElements(&lvns_);
}
-LocalValueNumbering* GlobalValueNumbering::PrepareBasicBlock(BasicBlock* bb) {
+LocalValueNumbering* GlobalValueNumbering::PrepareBasicBlock(BasicBlock* bb,
+ ScopedArenaAllocator* allocator) {
if (UNLIKELY(!Good())) {
return nullptr;
}
@@ -58,13 +59,17 @@ LocalValueNumbering* GlobalValueNumbering::PrepareBasicBlock(BasicBlock* bb) {
last_value_ = kNoValue; // Make bad.
return nullptr;
}
+ if (allocator == nullptr) {
+ allocator = allocator_;
+ }
DCHECK(work_lvn_.get() == nullptr);
- work_lvn_.reset(new (allocator_) LocalValueNumbering(this, bb->id));
+ work_lvn_.reset(new (allocator) LocalValueNumbering(this, bb->id, allocator));
if (bb->block_type == kEntryBlock) {
if ((cu_->access_flags & kAccStatic) == 0) {
// If non-static method, mark "this" as non-null
int this_reg = cu_->num_dalvik_registers - cu_->num_ins;
- work_lvn_->SetSRegNullChecked(this_reg);
+ uint16_t value_name = work_lvn_->GetSRegValueName(this_reg);
+ work_lvn_->SetValueNameNullChecked(value_name);
}
} else {
// To avoid repeated allocation on the ArenaStack, reuse a single vector kept as a member.
@@ -120,7 +125,9 @@ LocalValueNumbering* GlobalValueNumbering::PrepareBasicBlock(BasicBlock* bb) {
work_lvn_->MergeOne(*merge_lvns_[0], merge_type);
BasicBlock* pred_bb = mir_graph_->GetBasicBlock(merge_lvns_[0]->Id());
if (HasNullCheckLastInsn(pred_bb, bb->id)) {
- work_lvn_->SetSRegNullChecked(pred_bb->last_mir_insn->ssa_rep->uses[0]);
+ int s_reg = pred_bb->last_mir_insn->ssa_rep->uses[0];
+ uint16_t value_name = merge_lvns_[0]->GetSRegValueName(s_reg);
+ work_lvn_->SetValueNameNullChecked(value_name);
}
} else {
work_lvn_->Merge(merge_type);
@@ -135,9 +142,14 @@ bool GlobalValueNumbering::FinishBasicBlock(BasicBlock* bb) {
++bbs_processed_;
merge_lvns_.clear();
- std::unique_ptr<const LocalValueNumbering> old_lvn(lvns_[bb->id]);
- lvns_[bb->id] = work_lvn_.release();
- return (old_lvn == nullptr) || !old_lvn->Equals(*lvns_[bb->id]);
+ bool change = (lvns_[bb->id] == nullptr) || !lvns_[bb->id]->Equals(*work_lvn_);
+ if (change) {
+ std::unique_ptr<const LocalValueNumbering> old_lvn(lvns_[bb->id]);
+ lvns_[bb->id] = work_lvn_.release();
+ } else {
+ work_lvn_.reset();
+ }
+ return change;
}
uint16_t GlobalValueNumbering::GetFieldId(const MirFieldInfo& field_info, uint16_t type) {