64-bit temp register support.
Add a 64-bit temp register allocation path. The recent physical
register handling rework supports multiple views of the same
physical register (or, such as for Arm's float/double regs,
different parts of the same physical register).
This CL adds a 64-bit core register view for 64-bit targets. In
short, each core register will have a 64-bit name, and a 32-bit
name. The different views will be kept in separate register pools,
but aliasing will be tracked. The core temp register allocation
routines will be largely identical - except for 32-bit targets,
which will continue to use pairs of 32-bit core registers for holding
long values.
Change-Id: I8f118e845eac7903ad8b6dcec1952f185023c053
diff --git a/compiler/dex/quick/ralloc_util.cc b/compiler/dex/quick/ralloc_util.cc
index 06d05e2..2c51c1f 100644
--- a/compiler/dex/quick/ralloc_util.cc
+++ b/compiler/dex/quick/ralloc_util.cc
@@ -57,14 +57,19 @@
Mir2Lir::RegisterPool::RegisterPool(Mir2Lir* m2l, ArenaAllocator* arena,
const std::vector<RegStorage>& core_regs,
+ const std::vector<RegStorage>& core64_regs,
const std::vector<RegStorage>& sp_regs,
const std::vector<RegStorage>& dp_regs,
const std::vector<RegStorage>& reserved_regs,
+ const std::vector<RegStorage>& reserved64_regs,
const std::vector<RegStorage>& core_temps,
+ const std::vector<RegStorage>& core64_temps,
const std::vector<RegStorage>& sp_temps,
const std::vector<RegStorage>& dp_temps) :
- core_regs_(arena, core_regs.size()), next_core_reg_(0), sp_regs_(arena, sp_regs.size()),
- next_sp_reg_(0), dp_regs_(arena, dp_regs.size()), next_dp_reg_(0), m2l_(m2l) {
+ core_regs_(arena, core_regs.size()), next_core_reg_(0),
+ core64_regs_(arena, core64_regs.size()), next_core64_reg_(0),
+ sp_regs_(arena, sp_regs.size()), 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();
if (kIsDebugBuild) {
@@ -82,6 +87,11 @@
m2l_->reginfo_map_.Put(reg.GetReg(), info);
core_regs_.Insert(info);
}
+ for (RegStorage reg : core64_regs) {
+ RegisterInfo* info = new (arena) RegisterInfo(reg, m2l_->GetRegMaskCommon(reg));
+ m2l_->reginfo_map_.Put(reg.GetReg(), info);
+ core64_regs_.Insert(info);
+ }
for (RegStorage reg : sp_regs) {
RegisterInfo* info = new (arena) RegisterInfo(reg, m2l_->GetRegMaskCommon(reg));
m2l_->reginfo_map_.Put(reg.GetReg(), info);
@@ -97,11 +107,17 @@
for (RegStorage reg : reserved_regs) {
m2l_->MarkInUse(reg);
}
+ for (RegStorage reg : reserved64_regs) {
+ m2l_->MarkInUse(reg);
+ }
// Mark temp regs - all others not in use can be used for promotion
for (RegStorage reg : core_temps) {
m2l_->MarkTemp(reg);
}
+ for (RegStorage reg : core64_temps) {
+ m2l_->MarkTemp(reg);
+ }
for (RegStorage reg : sp_temps) {
m2l_->MarkTemp(reg);
}
@@ -374,6 +390,18 @@
return AllocTempBody(reg_pool_->core_regs_, ®_pool_->next_core_reg_, true);
}
+RegStorage Mir2Lir::AllocTempWide() {
+ RegStorage res;
+ if (reg_pool_->core64_regs_.Size() != 0) {
+ res = AllocTempBody(reg_pool_->core64_regs_, ®_pool_->next_core64_reg_, true);
+ } else {
+ RegStorage low_reg = AllocTemp();
+ RegStorage high_reg = AllocTemp();
+ res = RegStorage::MakeRegPair(low_reg, high_reg);
+ }
+ return res;
+}
+
RegStorage Mir2Lir::AllocTempSingle() {
RegStorage res = AllocTempBody(reg_pool_->sp_regs_, ®_pool_->next_sp_reg_, true);
DCHECK(res.IsSingle()) << "Reg: 0x" << std::hex << res.GetRawBits();
@@ -386,6 +414,20 @@
return res;
}
+RegStorage Mir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
+ if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
+ return AllocTempDouble();
+ }
+ return AllocTempWide();
+}
+
+RegStorage Mir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
+ if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
+ return AllocTempSingle();
+ }
+ return AllocTemp();
+}
+
RegStorage Mir2Lir::FindLiveReg(GrowableArray<RegisterInfo*> ®s, int s_reg) {
RegStorage res;
GrowableArray<RegisterInfo*>::Iterator it(®s);