summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick/ralloc_util.cc
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2014-05-12 15:13:16 -0700
committerbuzbee <buzbee@google.com>2014-05-12 15:13:16 -0700
commitba57451494946a128703e1cbd8bf5969ee8dc598 (patch)
treeb2f4702946b6f5feb7f59bac94debe3508c18149 /compiler/dex/quick/ralloc_util.cc
parente1910f1d802dff79bba5ef61e1c4fd0b95f6e5b0 (diff)
downloadandroid_art-ba57451494946a128703e1cbd8bf5969ee8dc598.tar.gz
android_art-ba57451494946a128703e1cbd8bf5969ee8dc598.tar.bz2
android_art-ba57451494946a128703e1cbd8bf5969ee8dc598.zip
Quick compiler: fix compile-time perf regression
The recent changes to the temp register liveness tracking introduced a measureable compile-time performance regression. This CL cleans it up. Change-Id: Id698b93e957f0ecab7ddfab94727f85e49cf10cf
Diffstat (limited to 'compiler/dex/quick/ralloc_util.cc')
-rw-r--r--compiler/dex/quick/ralloc_util.cc63
1 files changed, 40 insertions, 23 deletions
diff --git a/compiler/dex/quick/ralloc_util.cc b/compiler/dex/quick/ralloc_util.cc
index ca9a3ab64f..5e6e73be96 100644
--- a/compiler/dex/quick/ralloc_util.cc
+++ b/compiler/dex/quick/ralloc_util.cc
@@ -40,7 +40,8 @@ void Mir2Lir::ResetRegPool() {
Mir2Lir::RegisterInfo::RegisterInfo(RegStorage r, uint64_t mask)
: reg_(r), is_temp_(false), wide_value_(false), dirty_(false), aliased_(false), partner_(r),
- s_reg_(INVALID_SREG), def_use_mask_(mask), master_(this) {
+ s_reg_(INVALID_SREG), def_use_mask_(mask), master_(this), def_start_(nullptr),
+ def_end_(nullptr), alias_chain_(nullptr) {
switch (r.StorageSize()) {
case 0: storage_mask_ = 0xffffffff; break;
case 4: storage_mask_ = 0x00000001; break;
@@ -66,9 +67,13 @@ Mir2Lir::RegisterPool::RegisterPool(Mir2Lir* m2l, ArenaAllocator* arena,
next_sp_reg_(0), dp_regs_(arena, dp_regs.size()), next_dp_reg_(0), m2l_(m2l) {
// Initialize the fast lookup map.
m2l_->reginfo_map_.Reset();
- m2l_->reginfo_map_.Resize(RegStorage::kMaxRegs);
- for (unsigned i = 0; i < RegStorage::kMaxRegs; i++) {
- m2l_->reginfo_map_.Insert(nullptr);
+ if (kIsDebugBuild) {
+ m2l_->reginfo_map_.Resize(RegStorage::kMaxRegs);
+ for (unsigned i = 0; i < RegStorage::kMaxRegs; i++) {
+ m2l_->reginfo_map_.Insert(nullptr);
+ }
+ } else {
+ m2l_->reginfo_map_.SetSize(RegStorage::kMaxRegs);
}
// Construct the register pool.
@@ -139,29 +144,43 @@ void Mir2Lir::DumpRegPools() {
}
void Mir2Lir::Clobber(RegStorage reg) {
- if (reg.IsPair()) {
+ if (UNLIKELY(reg.IsPair())) {
DCHECK(!GetRegInfo(reg.GetLow())->IsAliased());
- ClobberBody(GetRegInfo(reg.GetLow()));
+ Clobber(reg.GetLow());
DCHECK(!GetRegInfo(reg.GetHigh())->IsAliased());
- ClobberBody(GetRegInfo(reg.GetHigh()));
+ Clobber(reg.GetHigh());
} else {
RegisterInfo* info = GetRegInfo(reg);
- if (info->IsAliased()) {
- ClobberAliases(info);
- } else if (info != info->Master() && info->Master()->SReg() != INVALID_SREG) {
- ClobberBody(info->Master());
+ if (info->IsTemp() && !info->IsDead()) {
+ ClobberBody(info);
+ if (info->IsAliased()) {
+ ClobberAliases(info);
+ } else {
+ RegisterInfo* master = info->Master();
+ if (info != master) {
+ ClobberBody(info->Master());
+ }
+ }
}
- ClobberBody(info);
}
}
void Mir2Lir::ClobberAliases(RegisterInfo* info) {
- DCHECK(info->IsAliased());
- GrowableArray<RegisterInfo*>::Iterator iter(&tempreg_info_);
- for (RegisterInfo* tmpreg_info = iter.Next(); tmpreg_info != NULL; tmpreg_info = iter.Next()) {
- if (tmpreg_info->Master() == info) {
- // tmpreg_info is an alias of info.
- ClobberBody(tmpreg_info);
+ for (RegisterInfo* alias = info->GetAliasChain(); alias != nullptr;
+ alias = alias->GetAliasChain()) {
+ DCHECK(!alias->IsAliased()); // Only the master should be marked as alised.
+ if (alias->SReg() != INVALID_SREG) {
+ alias->SetSReg(INVALID_SREG);
+ alias->ResetDefBody();
+ if (alias->IsWide()) {
+ alias->SetIsWide(false);
+ if (alias->GetReg() != alias->Partner()) {
+ RegisterInfo* p = GetRegInfo(alias->Partner());
+ p->SetIsWide(false);
+ p->MarkDead();
+ p->ResetDefBody();
+ }
+ }
}
}
}
@@ -185,11 +204,10 @@ void Mir2Lir::ClobberSReg(int s_reg) {
GrowableArray<RegisterInfo*>::Iterator iter(&tempreg_info_);
for (RegisterInfo* info = iter.Next(); info != NULL; info = iter.Next()) {
if (info->SReg() == s_reg) {
+ ClobberBody(info);
if (info->IsAliased()) {
- // TUNING: if this gets hot, we could add links to follow - aliasing is static.
ClobberAliases(info);
}
- ClobberBody(info);
}
}
}
@@ -645,7 +663,7 @@ void Mir2Lir::ResetDefTracking() {
}
}
-void Mir2Lir::ClobberAllRegs() {
+void Mir2Lir::ClobberAllTemps() {
GrowableArray<RegisterInfo*>::Iterator iter(&tempreg_info_);
for (RegisterInfo* info = iter.Next(); info != NULL; info = iter.Next()) {
ClobberBody(info);
@@ -703,10 +721,9 @@ void Mir2Lir::FlushSpecificReg(RegisterInfo* info) {
void Mir2Lir::FlushAllRegs() {
GrowableArray<RegisterInfo*>::Iterator it(&tempreg_info_);
for (RegisterInfo* info = it.Next(); info != nullptr; info = it.Next()) {
- if (info->IsLive() && info->IsDirty()) {
+ if (info->IsDirty() && info->IsLive()) {
FlushSpecificReg(info);
}
- DCHECK(info->IsTemp());
info->MarkDead();
info->SetSReg(INVALID_SREG);
info->ResetDefBody();