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/frontend.cc b/compiler/dex/frontend.cc
index 3bc060b..77b5057 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -75,6 +75,7 @@
// (1 << kDebugShowSummaryMemoryUsage) |
// (1 << kDebugShowFilterStats) |
// (1 << kDebugTimings) |
+ // (1 << kDebugCodegenDump) |
0;
CompilationUnit::CompilationUnit(ArenaPool* pool)
@@ -852,6 +853,10 @@
}
}
+ if (cu.verbose) {
+ cu.enable_debug |= (1 << kDebugCodegenDump);
+ }
+
/*
* TODO: rework handling of optimization and debug flags. Should we split out
* MIR and backend flags? Need command-line setting as well.
@@ -877,6 +882,7 @@
if (cu.instruction_set == kArm64) {
// TODO(Arm64): enable optimizations once backend is mature enough.
cu.disable_opt = ~(uint32_t)0;
+ cu.enable_debug |= (1 << kDebugCodegenDump);
}
cu.StartTimingSplit("BuildMIRGraph");
diff --git a/compiler/dex/frontend.h b/compiler/dex/frontend.h
index c3b8d12..9e376ee 100644
--- a/compiler/dex/frontend.h
+++ b/compiler/dex/frontend.h
@@ -76,7 +76,8 @@
kDebugVerifyBitcode,
kDebugShowSummaryMemoryUsage,
kDebugShowFilterStats,
- kDebugTimings
+ kDebugTimings,
+ kDebugCodegenDump
};
class LLVMInfo {
diff --git a/compiler/dex/quick/arm/codegen_arm.h b/compiler/dex/quick/arm/codegen_arm.h
index 876419c..2d1c19e 100644
--- a/compiler/dex/quick/arm/codegen_arm.h
+++ b/compiler/dex/quick/arm/codegen_arm.h
@@ -54,8 +54,6 @@
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
// Required for target - register utilities.
- RegStorage AllocTypedTemp(bool fp_hint, int reg_class);
- RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
RegStorage TargetReg(SpecialTargetRegister reg);
RegStorage GetArgMappingToPhysicalReg(int arg_num);
RegLocation GetReturnAlt();
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc
index f7a7fe8..1520c52 100644
--- a/compiler/dex/quick/arm/target_arm.cc
+++ b/compiler/dex/quick/arm/target_arm.cc
@@ -46,6 +46,7 @@
static const RegStorage dp_temps_arr[] =
{rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7};
+static const std::vector<RegStorage> empty_pool;
static const std::vector<RegStorage> core_regs(core_regs_arr,
core_regs_arr + sizeof(core_regs_arr) / sizeof(core_regs_arr[0]));
static const std::vector<RegStorage> sp_regs(sp_regs_arr,
@@ -554,26 +555,11 @@
return new ArmMir2Lir(cu, mir_graph, arena);
}
-// Alloc a pair of core registers, or a double.
-RegStorage ArmMir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- return AllocTempDouble();
- } else {
- RegStorage low_reg = AllocTemp();
- RegStorage high_reg = AllocTemp();
- return RegStorage::MakeRegPair(low_reg, high_reg);
- }
-}
-
-RegStorage ArmMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg))
- return AllocTempSingle();
- return AllocTemp();
-}
-
void ArmMir2Lir::CompilerInitializeRegAlloc() {
- reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, sp_regs, dp_regs, reserved_regs,
- core_temps, sp_temps, dp_temps);
+ reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, empty_pool /* core64 */, sp_regs,
+ dp_regs, reserved_regs, empty_pool /* reserved64 */,
+ core_temps, empty_pool /* core64_temps */, sp_temps,
+ dp_temps);
// Target-specific adjustments.
diff --git a/compiler/dex/quick/arm64/arm64_lir.h b/compiler/dex/quick/arm64/arm64_lir.h
index 33a1c00..c3b23fd 100644
--- a/compiler/dex/quick/arm64/arm64_lir.h
+++ b/compiler/dex/quick/arm64/arm64_lir.h
@@ -129,27 +129,32 @@
R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
// Registers (integer) values.
-// TODO(Arm64): for now we define rx##nr identically to rw##nr. We should rather define rx##nr as
-// a k64BitSolo. We should do this once the register allocator is ready.
enum A64NativeRegisterPool {
# define A64_DEFINE_REGISTERS(nr) \
rw##nr = RegStorage::k32BitSolo | RegStorage::kCoreRegister | nr, \
- rx##nr = RegStorage::k32BitSolo | RegStorage::kCoreRegister | nr, \
+ rx##nr = RegStorage::k64BitSolo | RegStorage::kCoreRegister | nr, \
rf##nr = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | nr, \
rd##nr = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | nr,
A64_REGISTER_CODE_LIST(A64_DEFINE_REGISTERS)
#undef A64_DEFINE_REGISTERS
- // TODO(Arm64): can we change the lines below such that rwzr != rwsp && rxzr != rsp?
- // This would be desirable to allow detecting usage-errors in the assembler.
rwzr = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0x3f,
- rxzr = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0x3f,
+ rxzr = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 0x3f,
rwsp = rw31,
rsp = rx31,
rA64_SUSPEND = rx19,
rA64_SELF = rx18,
rA64_SP = rx31,
- rA64_LR = rx30
+ rA64_LR = rx30,
+ /*
+ * FIXME: It's a bit awkward to define both 32 and 64-bit views of these - we'll only ever use
+ * the 64-bit view. However, for now we'll define a 32-bit view to keep these from being
+ * allocated as 32-bit temp registers.
+ */
+ rA32_SUSPEND = rw19,
+ rA32_SELF = rw18,
+ rA32_SP = rw31,
+ rA32_LR = rw30
};
#define A64_DEFINE_REGSTORAGES(nr) \
@@ -166,6 +171,11 @@
constexpr RegStorage rs_rA64_SELF(RegStorage::kValid | rA64_SELF);
constexpr RegStorage rs_rA64_SP(RegStorage::kValid | rA64_SP);
constexpr RegStorage rs_rA64_LR(RegStorage::kValid | rA64_LR);
+// TODO: eliminate the need for these.
+constexpr RegStorage rs_rA32_SUSPEND(RegStorage::kValid | rA32_SUSPEND);
+constexpr RegStorage rs_rA32_SELF(RegStorage::kValid | rA32_SELF);
+constexpr RegStorage rs_rA32_SP(RegStorage::kValid | rA32_SP);
+constexpr RegStorage rs_rA32_LR(RegStorage::kValid | rA32_LR);
// RegisterLocation templates return values (following the hard-float calling convention).
const RegLocation arm_loc_c_return =
diff --git a/compiler/dex/quick/arm64/assemble_arm64.cc b/compiler/dex/quick/arm64/assemble_arm64.cc
index 01fcc0d..656f8fd 100644
--- a/compiler/dex/quick/arm64/assemble_arm64.cc
+++ b/compiler/dex/quick/arm64/assemble_arm64.cc
@@ -666,7 +666,7 @@
expected = "core register";
} else if (want_size_match && (reg.Is64Bit() != want_64_bit)) {
expected = (want_64_bit) ? "x-register" : "w-register";
- } else if (reg.GetRegNum() == 31 && is_zero == want_zero) {
+ } else if (reg.GetRegNum() == 31 && is_zero != want_zero) {
expected = (want_zero) ? "zero-register" : "sp-register";
}
}
diff --git a/compiler/dex/quick/arm64/codegen_arm64.h b/compiler/dex/quick/arm64/codegen_arm64.h
index 01b7802..350e483 100644
--- a/compiler/dex/quick/arm64/codegen_arm64.h
+++ b/compiler/dex/quick/arm64/codegen_arm64.h
@@ -54,8 +54,6 @@
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
// Required for target - register utilities.
- RegStorage AllocTypedTemp(bool fp_hint, int reg_class);
- RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
RegStorage TargetReg(SpecialTargetRegister reg);
RegStorage GetArgMappingToPhysicalReg(int arg_num);
RegLocation GetReturnAlt();
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index 12ac4c8..2b1c5e8 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -27,6 +27,12 @@
// TODO: rework this when c++11 support allows.
static const RegStorage core_regs_arr[] =
+ {rs_w0, rs_w1, rs_w2, rs_w3, rs_w4, rs_w5, rs_w6, rs_w7,
+ rs_w8, rs_w9, rs_w10, rs_w11, rs_w12, rs_w13, rs_w14, rs_w15,
+ rs_w16, rs_w17, rs_w18, rs_w19, rs_w20, rs_w21, rs_w22, rs_w23,
+ rs_w24, rs_w25, rs_w26, rs_w27, rs_w28, rs_w29, rs_w30, rs_w31,
+ rs_wzr};
+static const RegStorage core64_regs_arr[] =
{rs_x0, rs_x1, rs_x2, rs_x3, rs_x4, rs_x5, rs_x6, rs_x7,
rs_x8, rs_x9, rs_x10, rs_x11, rs_x12, rs_x13, rs_x14, rs_x15,
rs_x16, rs_x17, rs_x18, rs_x19, rs_x20, rs_x21, rs_x22, rs_x23,
@@ -43,12 +49,18 @@
rs_d16, rs_d17, rs_d18, rs_d19, rs_d20, rs_d21, rs_d22, rs_d23,
rs_d24, rs_d25, rs_d26, rs_d27, rs_d28, rs_d29, rs_d30, rs_d31};
static const RegStorage reserved_regs_arr[] =
+ {rs_rA32_SUSPEND, rs_rA32_SELF, rs_rA32_SP, rs_rA32_LR, rs_wzr};
+static const RegStorage reserved64_regs_arr[] =
{rs_rA64_SUSPEND, rs_rA64_SELF, rs_rA64_SP, rs_rA64_LR, rs_xzr};
// TUNING: Are there too many temp registers and too less promote target?
// This definition need to be matched with runtime.cc, quick entry assembly and JNI compiler
// Note: we are not able to call to C function directly if it un-match C ABI.
// Currently, rs_rA64_SELF is not a callee save register which does not match C ABI.
static const RegStorage core_temps_arr[] =
+ {rs_w0, rs_w1, rs_w2, rs_w3, rs_w4, rs_w5, rs_w6, rs_w7,
+ rs_w8, rs_w9, rs_w10, rs_w11, rs_w12, rs_w13, rs_w14, rs_w15, rs_w16,
+ rs_w17};
+static const RegStorage core64_temps_arr[] =
{rs_x0, rs_x1, rs_x2, rs_x3, rs_x4, rs_x5, rs_x6, rs_x7,
rs_x8, rs_x9, rs_x10, rs_x11, rs_x12, rs_x13, rs_x14, rs_x15, rs_x16,
rs_x17};
@@ -63,14 +75,20 @@
static const std::vector<RegStorage> core_regs(core_regs_arr,
core_regs_arr + arraysize(core_regs_arr));
+static const std::vector<RegStorage> core64_regs(core64_regs_arr,
+ core64_regs_arr + arraysize(core64_regs_arr));
static const std::vector<RegStorage> sp_regs(sp_regs_arr,
sp_regs_arr + arraysize(sp_regs_arr));
static const std::vector<RegStorage> dp_regs(dp_regs_arr,
dp_regs_arr + arraysize(dp_regs_arr));
static const std::vector<RegStorage> reserved_regs(reserved_regs_arr,
reserved_regs_arr + arraysize(reserved_regs_arr));
+static const std::vector<RegStorage> reserved64_regs(reserved64_regs_arr,
+ reserved64_regs_arr + arraysize(reserved64_regs_arr));
static const std::vector<RegStorage> core_temps(core_temps_arr,
core_temps_arr + arraysize(core_temps_arr));
+static const std::vector<RegStorage> core64_temps(core64_temps_arr,
+ core64_temps_arr + arraysize(core64_temps_arr));
static const std::vector<RegStorage> sp_temps(sp_temps_arr, sp_temps_arr + arraysize(sp_temps_arr));
static const std::vector<RegStorage> dp_temps(dp_temps_arr, dp_temps_arr + arraysize(dp_temps_arr));
@@ -578,26 +596,10 @@
return new Arm64Mir2Lir(cu, mir_graph, arena);
}
-// Alloc a pair of core registers, or a double.
-RegStorage Arm64Mir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- return AllocTempDouble();
- } else {
- RegStorage low_reg = AllocTemp();
- RegStorage high_reg = AllocTemp();
- return RegStorage::MakeRegPair(low_reg, high_reg);
- }
-}
-
-RegStorage Arm64Mir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg))
- return AllocTempSingle();
- return AllocTemp();
-}
-
void Arm64Mir2Lir::CompilerInitializeRegAlloc() {
- reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, sp_regs, dp_regs, reserved_regs,
- core_temps, sp_temps, dp_temps);
+ reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, core64_regs, sp_regs, dp_regs,
+ reserved_regs, reserved64_regs, core_temps, core64_temps,
+ sp_temps, dp_temps);
// Target-specific adjustments.
// Alias single precision float registers to corresponding double registers.
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index d58015a..6ccf252 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -991,7 +991,7 @@
/* Convert LIR into machine code. */
AssembleLIR();
- if (cu_->verbose) {
+ if ((cu_->enable_debug & (1 << kDebugCodegenDump)) != 0) {
CodegenDump();
}
}
diff --git a/compiler/dex/quick/mips/codegen_mips.h b/compiler/dex/quick/mips/codegen_mips.h
index 0c59465..2b57b35 100644
--- a/compiler/dex/quick/mips/codegen_mips.h
+++ b/compiler/dex/quick/mips/codegen_mips.h
@@ -54,8 +54,6 @@
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
// Required for target - register utilities.
- RegStorage AllocTypedTemp(bool fp_hint, int reg_class);
- RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
RegStorage TargetReg(SpecialTargetRegister reg);
RegStorage GetArgMappingToPhysicalReg(int arg_num);
RegLocation GetReturnAlt();
diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc
index 7a3da71..55cf434 100644
--- a/compiler/dex/quick/mips/target_mips.cc
+++ b/compiler/dex/quick/mips/target_mips.cc
@@ -46,6 +46,7 @@
static RegStorage dp_temps_arr[] =
{rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7};
+static const std::vector<RegStorage> empty_pool;
static const std::vector<RegStorage> core_regs(core_regs_arr,
core_regs_arr + sizeof(core_regs_arr) / sizeof(core_regs_arr[0]));
static const std::vector<RegStorage> sp_regs(sp_regs_arr,
@@ -442,27 +443,11 @@
#endif
}
-// Alloc a pair of core registers, or a double.
-RegStorage MipsMir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- return AllocTempDouble();
- }
-
- RegStorage low_reg = AllocTemp();
- RegStorage high_reg = AllocTemp();
- return RegStorage::MakeRegPair(low_reg, high_reg);
-}
-
-RegStorage MipsMir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- return AllocTempSingle();
- }
- return AllocTemp();
-}
-
void MipsMir2Lir::CompilerInitializeRegAlloc() {
- reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, sp_regs, dp_regs, reserved_regs,
- core_temps, sp_temps, dp_temps);
+ reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs, empty_pool /* core64 */, sp_regs,
+ dp_regs, reserved_regs, empty_pool /* reserved64 */,
+ core_temps, empty_pool /* core64_temps */, sp_temps,
+ dp_temps);
// Target-specific adjustments.
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 7f0bf30..3e0ba75 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -411,10 +411,15 @@
class RegisterPool {
public:
- RegisterPool(Mir2Lir* m2l, ArenaAllocator* arena, const std::vector<RegStorage>& core_regs,
- const std::vector<RegStorage>& sp_regs, const std::vector<RegStorage>& dp_regs,
+ 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);
~RegisterPool() {}
@@ -428,6 +433,8 @@
}
GrowableArray<RegisterInfo*> core_regs_;
int next_core_reg_;
+ GrowableArray<RegisterInfo*> core64_regs_;
+ int next_core64_reg_;
GrowableArray<RegisterInfo*> sp_regs_; // Single precision float.
int next_sp_reg_;
GrowableArray<RegisterInfo*> dp_regs_; // Double precision float.
@@ -673,8 +680,11 @@
RegStorage AllocTempBody(GrowableArray<RegisterInfo*> ®s, int* next_temp, bool required);
virtual RegStorage AllocFreeTemp();
virtual RegStorage AllocTemp();
+ virtual RegStorage AllocTempWide();
virtual RegStorage AllocTempSingle();
virtual RegStorage AllocTempDouble();
+ virtual RegStorage AllocTypedTemp(bool fp_hint, int reg_class);
+ virtual RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
void FlushReg(RegStorage reg);
void FlushRegWide(RegStorage reg);
RegStorage AllocLiveReg(int s_reg, int reg_class, bool wide);
@@ -1088,8 +1098,6 @@
virtual void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg) = 0;
// Required for target - register utilities.
- virtual RegStorage AllocTypedTemp(bool fp_hint, int reg_class) = 0;
- virtual RegStorage AllocTypedTempWide(bool fp_hint, int reg_class) = 0;
virtual RegStorage TargetReg(SpecialTargetRegister reg) = 0;
virtual RegStorage GetArgMappingToPhysicalReg(int arg_num) = 0;
virtual RegLocation GetReturnAlt() = 0;
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);
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index e717638..3070edd 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -54,8 +54,6 @@
void MarkGCCard(RegStorage val_reg, RegStorage tgt_addr_reg);
// Required for target - register utilities.
- RegStorage AllocTypedTemp(bool fp_hint, int reg_class);
- RegStorage AllocTypedTempWide(bool fp_hint, int reg_class);
RegStorage TargetReg(SpecialTargetRegister reg);
RegStorage GetArgMappingToPhysicalReg(int arg_num);
RegLocation GetReturnAlt();
diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc
index 9ddeb68..e7a629a 100644
--- a/compiler/dex/quick/x86/target_x86.cc
+++ b/compiler/dex/quick/x86/target_x86.cc
@@ -81,6 +81,7 @@
#endif
};
+static const std::vector<RegStorage> empty_pool;
static const std::vector<RegStorage> core_regs_32(core_regs_arr_32,
core_regs_arr_32 + sizeof(core_regs_arr_32) / sizeof(core_regs_arr_32[0]));
static const std::vector<RegStorage> core_regs_64(core_regs_arr_64,
@@ -528,30 +529,15 @@
#endif
}
-// Alloc a pair of core registers, or a double.
-RegStorage X86Mir2Lir::AllocTypedTempWide(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- return AllocTempDouble();
- }
- RegStorage low_reg = AllocTemp();
- RegStorage high_reg = AllocTemp();
- return RegStorage::MakeRegPair(low_reg, high_reg);
-}
-
-RegStorage X86Mir2Lir::AllocTypedTemp(bool fp_hint, int reg_class) {
- if (((reg_class == kAnyReg) && fp_hint) || (reg_class == kFPReg)) {
- return AllocTempSingle();
- }
- return AllocTemp();
-}
-
void X86Mir2Lir::CompilerInitializeRegAlloc() {
if (Gen64Bit()) {
- reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs_64, sp_regs_64, dp_regs_64, reserved_regs_64,
- core_temps_64, sp_temps_64, dp_temps_64);
+ reg_pool_ = new (arena_) RegisterPool(this, arena_, empty_pool, core_regs_64, sp_regs_64,
+ dp_regs_64, empty_pool, reserved_regs_64,
+ empty_pool, core_temps_64, sp_temps_64, dp_temps_64);
} else {
- reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs_32, sp_regs_32, dp_regs_32, reserved_regs_32,
- core_temps_32, sp_temps_32, dp_temps_32);
+ reg_pool_ = new (arena_) RegisterPool(this, arena_, core_regs_32, empty_pool, sp_regs_32,
+ dp_regs_32, reserved_regs_32, empty_pool,
+ core_temps_32, empty_pool, sp_temps_32, dp_temps_32);
}
// Target-specific adjustments.