diff options
author | 2014-05-13 15:59:07 -0700 | |
---|---|---|
committer | 2014-05-21 05:17:24 -0700 | |
commit | b01bf15d18f9b08d77e7a3c6e2897af0e02bf8ca (patch) | |
tree | 8cafd7692046b4f8c95fb8e6a713755f9eeddeec | |
parent | d3236731ca6145e0723ce8aab8c6ff634ab021c2 (diff) |
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
-rw-r--r-- | compiler/dex/frontend.cc | 6 | ||||
-rw-r--r-- | compiler/dex/frontend.h | 3 | ||||
-rw-r--r-- | compiler/dex/quick/arm/codegen_arm.h | 2 | ||||
-rw-r--r-- | compiler/dex/quick/arm/target_arm.cc | 24 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/arm64_lir.h | 24 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/assemble_arm64.cc | 2 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/codegen_arm64.h | 2 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/target_arm64.cc | 40 | ||||
-rw-r--r-- | compiler/dex/quick/codegen_util.cc | 2 | ||||
-rw-r--r-- | compiler/dex/quick/mips/codegen_mips.h | 2 | ||||
-rw-r--r-- | compiler/dex/quick/mips/target_mips.cc | 25 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 16 | ||||
-rw-r--r-- | compiler/dex/quick/ralloc_util.cc | 46 | ||||
-rw-r--r-- | compiler/dex/quick/x86/codegen_x86.h | 2 | ||||
-rw-r--r-- | compiler/dex/quick/x86/target_x86.cc | 28 |
15 files changed, 121 insertions, 103 deletions
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc index 3bc060ba27..77b5057538 100644 --- a/compiler/dex/frontend.cc +++ b/compiler/dex/frontend.cc @@ -75,6 +75,7 @@ static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes // (1 << kDebugShowSummaryMemoryUsage) | // (1 << kDebugShowFilterStats) | // (1 << kDebugTimings) | + // (1 << kDebugCodegenDump) | 0; CompilationUnit::CompilationUnit(ArenaPool* pool) @@ -852,6 +853,10 @@ static CompiledMethod* CompileMethod(CompilerDriver& driver, } } + 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 @@ static CompiledMethod* CompileMethod(CompilerDriver& driver, 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 c3b8d120d2..9e376ee7ee 100644 --- a/compiler/dex/frontend.h +++ b/compiler/dex/frontend.h @@ -76,7 +76,8 @@ enum debugControlVector { 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 876419c8b4..2d1c19e2d2 100644 --- a/compiler/dex/quick/arm/codegen_arm.h +++ b/compiler/dex/quick/arm/codegen_arm.h @@ -54,8 +54,6 @@ class ArmMir2Lir FINAL : public Mir2Lir { 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 f7a7fe89f9..1520c52a7a 100644 --- a/compiler/dex/quick/arm/target_arm.cc +++ b/compiler/dex/quick/arm/target_arm.cc @@ -46,6 +46,7 @@ static const RegStorage sp_temps_arr[] = 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 @@ Mir2Lir* ArmCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, 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 33a1c009e7..c3b23fdf60 100644 --- a/compiler/dex/quick/arm64/arm64_lir.h +++ b/compiler/dex/quick/arm64/arm64_lir.h @@ -129,27 +129,32 @@ enum ArmResourceEncodingPos { 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_SUSPEND(RegStorage::kValid | rA64_SUSPEND); 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 01fcc0d873..656f8fd6a4 100644 --- a/compiler/dex/quick/arm64/assemble_arm64.cc +++ b/compiler/dex/quick/arm64/assemble_arm64.cc @@ -666,7 +666,7 @@ uint8_t* Arm64Mir2Lir::EncodeLIRs(uint8_t* write_pos, LIR* lir) { 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 01b7802d76..350e4830ae 100644 --- a/compiler/dex/quick/arm64/codegen_arm64.h +++ b/compiler/dex/quick/arm64/codegen_arm64.h @@ -54,8 +54,6 @@ class Arm64Mir2Lir : public Mir2Lir { 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 12ac4c8a0f..2b1c5e8386 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -27,6 +27,12 @@ namespace art { // 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 @@ static const RegStorage dp_regs_arr[] = 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 RegStorage dp_temps_arr[] = 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 @@ Mir2Lir* Arm64CodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph 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 d58015a979..6ccf252a14 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -991,7 +991,7 @@ void Mir2Lir::Materialize() { /* 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 0c59465260..2b57b35443 100644 --- a/compiler/dex/quick/mips/codegen_mips.h +++ b/compiler/dex/quick/mips/codegen_mips.h @@ -54,8 +54,6 @@ class MipsMir2Lir FINAL : public Mir2Lir { 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 7a3da717c2..55cf4344f1 100644 --- a/compiler/dex/quick/mips/target_mips.cc +++ b/compiler/dex/quick/mips/target_mips.cc @@ -46,6 +46,7 @@ static RegStorage sp_temps_arr[] = 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 @@ bool MipsMir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) { #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 7f0bf30e68..3e0ba7517a 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -411,10 +411,15 @@ class Mir2Lir : public Backend { 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 @@ class Mir2Lir : public Backend { } 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 @@ class Mir2Lir : public Backend { 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 @@ class Mir2Lir : public Backend { 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 06d05e2274..2c51c1f2fd 100644 --- a/compiler/dex/quick/ralloc_util.cc +++ b/compiler/dex/quick/ralloc_util.cc @@ -57,14 +57,19 @@ Mir2Lir::RegisterInfo::RegisterInfo(RegStorage r, uint64_t mask) 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 @@ Mir2Lir::RegisterPool::RegisterPool(Mir2Lir* m2l, ArenaAllocator* arena, 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 @@ Mir2Lir::RegisterPool::RegisterPool(Mir2Lir* m2l, ArenaAllocator* arena, 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 @@ RegStorage Mir2Lir::AllocTemp() { 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 @@ RegStorage Mir2Lir::AllocTempDouble() { 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 e717638fba..3070edd202 100644 --- a/compiler/dex/quick/x86/codegen_x86.h +++ b/compiler/dex/quick/x86/codegen_x86.h @@ -54,8 +54,6 @@ class X86Mir2Lir : public Mir2Lir { 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 9ddeb68e80..e7a629aa0b 100644 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -81,6 +81,7 @@ static const RegStorage dp_temps_arr_64[] = { #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 @@ bool X86Mir2Lir::GenMemBarrier(MemBarrierKind barrier_kind) { #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. |