diff options
author | Vladimir Marko <vmarko@google.com> | 2014-06-05 10:57:05 +0100 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2014-06-05 11:13:21 +0100 |
commit | 089142cf1d0c028b5a7c703baf0b97f4a4ada3f7 (patch) | |
tree | 0868af5fe31881ec24ed1b549fcb36fd91dd3f7c | |
parent | 8ab62f8cb31eb2d42eb2dd58becea4382719be54 (diff) | |
download | android_art-089142cf1d0c028b5a7c703baf0b97f4a4ada3f7.tar.gz android_art-089142cf1d0c028b5a7c703baf0b97f4a4ada3f7.tar.bz2 android_art-089142cf1d0c028b5a7c703baf0b97f4a4ada3f7.zip |
Avoid register pool allocations on the heap.
Create a helper template class ArrayRef and use it instead
of std::vector<> for register pools in target_<arch>.cc to
avoid these heap allocations during program startup.
Change-Id: I4ab0205af9c1d28a239c0a105fcdc60ba800a70a
-rw-r--r-- | compiler/dex/quick/arm/target_arm.cc | 38 | ||||
-rw-r--r-- | compiler/dex/quick/arm64/target_arm64.cc | 49 | ||||
-rw-r--r-- | compiler/dex/quick/mips/target_mips.cc | 37 | ||||
-rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 21 | ||||
-rw-r--r-- | compiler/dex/quick/ralloc_util.cc | 20 | ||||
-rw-r--r-- | compiler/dex/quick/x86/target_x86.cc | 101 | ||||
-rw-r--r-- | compiler/utils/array_ref.h | 184 |
7 files changed, 296 insertions, 154 deletions
diff --git a/compiler/dex/quick/arm/target_arm.cc b/compiler/dex/quick/arm/target_arm.cc index a50b90a0ec..5340d8370a 100644 --- a/compiler/dex/quick/arm/target_arm.cc +++ b/compiler/dex/quick/arm/target_arm.cc @@ -25,42 +25,34 @@ namespace art { -// TODO: rework this when c++11 support allows. -static const RegStorage core_regs_arr[] = +static constexpr RegStorage core_regs_arr[] = {rs_r0, rs_r1, rs_r2, rs_r3, rs_rARM_SUSPEND, rs_r5, rs_r6, rs_r7, rs_r8, rs_rARM_SELF, rs_r10, rs_r11, rs_r12, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC}; -static const RegStorage sp_regs_arr[] = +static constexpr RegStorage sp_regs_arr[] = {rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, rs_fr8, rs_fr9, rs_fr10, rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15, rs_fr16, rs_fr17, rs_fr18, rs_fr19, rs_fr20, rs_fr21, rs_fr22, rs_fr23, rs_fr24, rs_fr25, rs_fr26, rs_fr27, rs_fr28, rs_fr29, rs_fr30, rs_fr31}; -static const RegStorage dp_regs_arr[] = +static constexpr RegStorage dp_regs_arr[] = {rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7, rs_dr8, rs_dr9, rs_dr10, rs_dr11, rs_dr12, rs_dr13, rs_dr14, rs_dr15}; -static const RegStorage reserved_regs_arr[] = +static constexpr RegStorage reserved_regs_arr[] = {rs_rARM_SUSPEND, rs_rARM_SELF, rs_rARM_SP, rs_rARM_LR, rs_rARM_PC}; -static const RegStorage core_temps_arr[] = {rs_r0, rs_r1, rs_r2, rs_r3, rs_r12}; -static const RegStorage sp_temps_arr[] = +static constexpr RegStorage core_temps_arr[] = {rs_r0, rs_r1, rs_r2, rs_r3, rs_r12}; +static constexpr RegStorage sp_temps_arr[] = {rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, rs_fr8, rs_fr9, rs_fr10, rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15}; -static const RegStorage dp_temps_arr[] = +static constexpr 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, - sp_regs_arr + sizeof(sp_regs_arr) / sizeof(sp_regs_arr[0])); -static const std::vector<RegStorage> dp_regs(dp_regs_arr, - dp_regs_arr + sizeof(dp_regs_arr) / sizeof(dp_regs_arr[0])); -static const std::vector<RegStorage> reserved_regs(reserved_regs_arr, - reserved_regs_arr + sizeof(reserved_regs_arr) / sizeof(reserved_regs_arr[0])); -static const std::vector<RegStorage> core_temps(core_temps_arr, - core_temps_arr + sizeof(core_temps_arr) / sizeof(core_temps_arr[0])); -static const std::vector<RegStorage> sp_temps(sp_temps_arr, - sp_temps_arr + sizeof(sp_temps_arr) / sizeof(sp_temps_arr[0])); -static const std::vector<RegStorage> dp_temps(dp_temps_arr, - dp_temps_arr + sizeof(dp_temps_arr) / sizeof(dp_temps_arr[0])); +static constexpr ArrayRef<const RegStorage> empty_pool; +static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr); +static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr); +static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr); +static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr); +static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr); +static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr); +static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr); RegLocation ArmMir2Lir::LocCReturn() { return arm_loc_c_return; diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc index 0524191bbf..b287399900 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -25,72 +25,63 @@ namespace art { -// TODO: rework this when c++11 support allows. -static const RegStorage core_regs_arr[] = +static constexpr 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[] = +static constexpr 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, rs_x24, rs_x25, rs_x26, rs_x27, rs_x28, rs_x29, rs_x30, rs_x31, rs_xzr}; -static const RegStorage sp_regs_arr[] = +static constexpr RegStorage sp_regs_arr[] = {rs_f0, rs_f1, rs_f2, rs_f3, rs_f4, rs_f5, rs_f6, rs_f7, rs_f8, rs_f9, rs_f10, rs_f11, rs_f12, rs_f13, rs_f14, rs_f15, rs_f16, rs_f17, rs_f18, rs_f19, rs_f20, rs_f21, rs_f22, rs_f23, rs_f24, rs_f25, rs_f26, rs_f27, rs_f28, rs_f29, rs_f30, rs_f31}; -static const RegStorage dp_regs_arr[] = +static constexpr RegStorage dp_regs_arr[] = {rs_d0, rs_d1, rs_d2, rs_d3, rs_d4, rs_d5, rs_d6, rs_d7, rs_d8, rs_d9, rs_d10, rs_d11, rs_d12, rs_d13, rs_d14, rs_d15, 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[] = +static constexpr RegStorage reserved_regs_arr[] = {rs_rA32_SUSPEND, rs_rA32_SELF, rs_rA32_SP, rs_rA32_LR, rs_wzr}; -static const RegStorage reserved64_regs_arr[] = +static constexpr 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[] = +static constexpr 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[] = +static constexpr 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}; -static const RegStorage sp_temps_arr[] = +static constexpr RegStorage sp_temps_arr[] = {rs_f0, rs_f1, rs_f2, rs_f3, rs_f4, rs_f5, rs_f6, rs_f7, rs_f16, rs_f17, rs_f18, rs_f19, rs_f20, rs_f21, rs_f22, rs_f23, rs_f24, rs_f25, rs_f26, rs_f27, rs_f28, rs_f29, rs_f30, rs_f31}; -static const RegStorage dp_temps_arr[] = +static constexpr RegStorage dp_temps_arr[] = {rs_d0, rs_d1, rs_d2, rs_d3, rs_d4, rs_d5, rs_d6, rs_d7, 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 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)); +static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr); +static constexpr ArrayRef<const RegStorage> core64_regs(core64_regs_arr); +static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr); +static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr); +static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr); +static constexpr ArrayRef<const RegStorage> reserved64_regs(reserved64_regs_arr); +static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr); +static constexpr ArrayRef<const RegStorage> core64_temps(core64_temps_arr); +static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr); +static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr); RegLocation Arm64Mir2Lir::LocCReturn() { return arm_loc_c_return; diff --git a/compiler/dex/quick/mips/target_mips.cc b/compiler/dex/quick/mips/target_mips.cc index fcf5f94159..c1a7c990f0 100644 --- a/compiler/dex/quick/mips/target_mips.cc +++ b/compiler/dex/quick/mips/target_mips.cc @@ -26,41 +26,34 @@ namespace art { -static const RegStorage core_regs_arr[] = +static constexpr RegStorage core_regs_arr[] = {rs_rZERO, rs_rAT, rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2, rs_rT3, rs_rT4, rs_rT5, rs_rT6, rs_rT7, rs_rS0, rs_rS1, rs_rS2, rs_rS3, rs_rS4, rs_rS5, rs_rS6, rs_rS7, rs_rT8, rs_rT9, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rFP, rs_rRA}; -static RegStorage sp_regs_arr[] = +static constexpr RegStorage sp_regs_arr[] = {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10, rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15}; -static RegStorage dp_regs_arr[] = +static constexpr RegStorage dp_regs_arr[] = {rs_rD0, rs_rD1, rs_rD2, rs_rD3, rs_rD4, rs_rD5, rs_rD6, rs_rD7}; -static const RegStorage reserved_regs_arr[] = +static constexpr RegStorage reserved_regs_arr[] = {rs_rZERO, rs_rAT, rs_rS0, rs_rS1, rs_rK0, rs_rK1, rs_rGP, rs_rSP, rs_rRA}; -static RegStorage core_temps_arr[] = +static constexpr RegStorage core_temps_arr[] = {rs_rV0, rs_rV1, rs_rA0, rs_rA1, rs_rA2, rs_rA3, rs_rT0, rs_rT1, rs_rT2, rs_rT3, rs_rT4, rs_rT5, rs_rT6, rs_rT7, rs_rT8}; -static RegStorage sp_temps_arr[] = +static constexpr RegStorage sp_temps_arr[] = {rs_rF0, rs_rF1, rs_rF2, rs_rF3, rs_rF4, rs_rF5, rs_rF6, rs_rF7, rs_rF8, rs_rF9, rs_rF10, rs_rF11, rs_rF12, rs_rF13, rs_rF14, rs_rF15}; -static RegStorage dp_temps_arr[] = +static constexpr 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, - sp_regs_arr + sizeof(sp_regs_arr) / sizeof(sp_regs_arr[0])); -static const std::vector<RegStorage> dp_regs(dp_regs_arr, - dp_regs_arr + sizeof(dp_regs_arr) / sizeof(dp_regs_arr[0])); -static const std::vector<RegStorage> reserved_regs(reserved_regs_arr, - reserved_regs_arr + sizeof(reserved_regs_arr) / sizeof(reserved_regs_arr[0])); -static const std::vector<RegStorage> core_temps(core_temps_arr, - core_temps_arr + sizeof(core_temps_arr) / sizeof(core_temps_arr[0])); -static const std::vector<RegStorage> sp_temps(sp_temps_arr, - sp_temps_arr + sizeof(sp_temps_arr) / sizeof(sp_temps_arr[0])); -static const std::vector<RegStorage> dp_temps(dp_temps_arr, - dp_temps_arr + sizeof(dp_temps_arr) / sizeof(dp_temps_arr[0])); +static constexpr ArrayRef<const RegStorage> empty_pool; +static constexpr ArrayRef<const RegStorage> core_regs(core_regs_arr); +static constexpr ArrayRef<const RegStorage> sp_regs(sp_regs_arr); +static constexpr ArrayRef<const RegStorage> dp_regs(dp_regs_arr); +static constexpr ArrayRef<const RegStorage> reserved_regs(reserved_regs_arr); +static constexpr ArrayRef<const RegStorage> core_temps(core_temps_arr); +static constexpr ArrayRef<const RegStorage> sp_temps(sp_temps_arr); +static constexpr ArrayRef<const RegStorage> dp_temps(dp_temps_arr); RegLocation MipsMir2Lir::LocCReturn() { return mips_loc_c_return; diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 1281d45990..ed94a8d844 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -26,6 +26,7 @@ #include "driver/compiler_driver.h" #include "leb128.h" #include "safe_map.h" +#include "utils/array_ref.h" #include "utils/arena_allocator.h" #include "utils/growable_array.h" @@ -429,16 +430,16 @@ class Mir2Lir : public Backend { class RegisterPool { public: 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); + const ArrayRef<const RegStorage>& core_regs, + const ArrayRef<const RegStorage>& core64_regs, + const ArrayRef<const RegStorage>& sp_regs, + const ArrayRef<const RegStorage>& dp_regs, + const ArrayRef<const RegStorage>& reserved_regs, + const ArrayRef<const RegStorage>& reserved64_regs, + const ArrayRef<const RegStorage>& core_temps, + const ArrayRef<const RegStorage>& core64_temps, + const ArrayRef<const RegStorage>& sp_temps, + const ArrayRef<const RegStorage>& dp_temps); ~RegisterPool() {} static void* operator new(size_t size, ArenaAllocator* arena) { return arena->Alloc(size, kArenaAllocRegAlloc); diff --git a/compiler/dex/quick/ralloc_util.cc b/compiler/dex/quick/ralloc_util.cc index 2303c62992..bbeef50d73 100644 --- a/compiler/dex/quick/ralloc_util.cc +++ b/compiler/dex/quick/ralloc_util.cc @@ -56,16 +56,16 @@ 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) : + const ArrayRef<const RegStorage>& core_regs, + const ArrayRef<const RegStorage>& core64_regs, + const ArrayRef<const RegStorage>& sp_regs, + const ArrayRef<const RegStorage>& dp_regs, + const ArrayRef<const RegStorage>& reserved_regs, + const ArrayRef<const RegStorage>& reserved64_regs, + const ArrayRef<const RegStorage>& core_temps, + const ArrayRef<const RegStorage>& core64_temps, + const ArrayRef<const RegStorage>& sp_temps, + const ArrayRef<const RegStorage>& dp_temps) : 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), diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index 79081c81a0..6a3ec671c5 100644 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -26,124 +26,105 @@ namespace art { -static const RegStorage core_regs_arr_32[] = { +static constexpr RegStorage core_regs_arr_32[] = { rs_rAX, rs_rCX, rs_rDX, rs_rBX, rs_rX86_SP_32, rs_rBP, rs_rSI, rs_rDI, }; -static const RegStorage core_regs_arr_64[] = { +static constexpr RegStorage core_regs_arr_64[] = { rs_rAX, rs_rCX, rs_rDX, rs_rBX, rs_rX86_SP_64, rs_rBP, rs_rSI, rs_rDI, #ifdef TARGET_REX_SUPPORT rs_r8, rs_r9, rs_r10, rs_r11, rs_r12, rs_r13, rs_r14, rs_r15 #endif }; -static const RegStorage core_regs_arr_64q[] = { +static constexpr RegStorage core_regs_arr_64q[] = { rs_r0q, rs_r1q, rs_r2q, rs_r3q, rs_rX86_SP_64, rs_r5q, rs_r6q, rs_r7q, #ifdef TARGET_REX_SUPPORT rs_r8q, rs_r9q, rs_r10q, rs_r11q, rs_r12q, rs_r13q, rs_r14q, rs_r15q #endif }; -static const RegStorage sp_regs_arr_32[] = { +static constexpr RegStorage sp_regs_arr_32[] = { rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, }; -static const RegStorage sp_regs_arr_64[] = { +static constexpr RegStorage sp_regs_arr_64[] = { rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, #ifdef TARGET_REX_SUPPORT rs_fr8, rs_fr9, rs_fr10, rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15 #endif }; -static const RegStorage dp_regs_arr_32[] = { +static constexpr RegStorage dp_regs_arr_32[] = { rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7, }; -static const RegStorage dp_regs_arr_64[] = { +static constexpr RegStorage dp_regs_arr_64[] = { rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7, #ifdef TARGET_REX_SUPPORT rs_dr8, rs_dr9, rs_dr10, rs_dr11, rs_dr12, rs_dr13, rs_dr14, rs_dr15 #endif }; -static const RegStorage reserved_regs_arr_32[] = {rs_rX86_SP_32}; -static const RegStorage reserved_regs_arr_64[] = {rs_rX86_SP_64}; -static const RegStorage reserved_regs_arr_64q[] = {rs_rX86_SP_64}; -static const RegStorage core_temps_arr_32[] = {rs_rAX, rs_rCX, rs_rDX, rs_rBX}; -static const RegStorage core_temps_arr_64[] = { +static constexpr RegStorage reserved_regs_arr_32[] = {rs_rX86_SP_32}; +static constexpr RegStorage reserved_regs_arr_64[] = {rs_rX86_SP_64}; +static constexpr RegStorage reserved_regs_arr_64q[] = {rs_rX86_SP_64}; +static constexpr RegStorage core_temps_arr_32[] = {rs_rAX, rs_rCX, rs_rDX, rs_rBX}; +static constexpr RegStorage core_temps_arr_64[] = { rs_rAX, rs_rCX, rs_rDX, rs_rSI, rs_rDI, #ifdef TARGET_REX_SUPPORT rs_r8, rs_r9, rs_r10, rs_r11 #endif }; -static const RegStorage core_temps_arr_64q[] = { +static constexpr RegStorage core_temps_arr_64q[] = { rs_r0q, rs_r1q, rs_r2q, rs_r6q, rs_r7q, #ifdef TARGET_REX_SUPPORT rs_r8q, rs_r9q, rs_r10q, rs_r11q #endif }; -static const RegStorage sp_temps_arr_32[] = { +static constexpr RegStorage sp_temps_arr_32[] = { rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, }; -static const RegStorage sp_temps_arr_64[] = { +static constexpr RegStorage sp_temps_arr_64[] = { rs_fr0, rs_fr1, rs_fr2, rs_fr3, rs_fr4, rs_fr5, rs_fr6, rs_fr7, #ifdef TARGET_REX_SUPPORT rs_fr8, rs_fr9, rs_fr10, rs_fr11, rs_fr12, rs_fr13, rs_fr14, rs_fr15 #endif }; -static const RegStorage dp_temps_arr_32[] = { +static constexpr RegStorage dp_temps_arr_32[] = { rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7, }; -static const RegStorage dp_temps_arr_64[] = { +static constexpr RegStorage dp_temps_arr_64[] = { rs_dr0, rs_dr1, rs_dr2, rs_dr3, rs_dr4, rs_dr5, rs_dr6, rs_dr7, #ifdef TARGET_REX_SUPPORT rs_dr8, rs_dr9, rs_dr10, rs_dr11, rs_dr12, rs_dr13, rs_dr14, rs_dr15 #endif }; -static const RegStorage xp_temps_arr_32[] = { +static constexpr RegStorage xp_temps_arr_32[] = { rs_xr0, rs_xr1, rs_xr2, rs_xr3, rs_xr4, rs_xr5, rs_xr6, rs_xr7, }; -static const RegStorage xp_temps_arr_64[] = { +static constexpr RegStorage xp_temps_arr_64[] = { rs_xr0, rs_xr1, rs_xr2, rs_xr3, rs_xr4, rs_xr5, rs_xr6, rs_xr7, #ifdef TARGET_REX_SUPPORT rs_xr8, rs_xr9, rs_xr10, rs_xr11, rs_xr12, rs_xr13, rs_xr14, rs_xr15 #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, - core_regs_arr_64 + sizeof(core_regs_arr_64) / sizeof(core_regs_arr_64[0])); -static const std::vector<RegStorage> core_regs_64q(core_regs_arr_64q, - core_regs_arr_64q + sizeof(core_regs_arr_64q) / sizeof(core_regs_arr_64q[0])); -static const std::vector<RegStorage> sp_regs_32(sp_regs_arr_32, - sp_regs_arr_32 + sizeof(sp_regs_arr_32) / sizeof(sp_regs_arr_32[0])); -static const std::vector<RegStorage> sp_regs_64(sp_regs_arr_64, - sp_regs_arr_64 + sizeof(sp_regs_arr_64) / sizeof(sp_regs_arr_64[0])); -static const std::vector<RegStorage> dp_regs_32(dp_regs_arr_32, - dp_regs_arr_32 + sizeof(dp_regs_arr_32) / sizeof(dp_regs_arr_32[0])); -static const std::vector<RegStorage> dp_regs_64(dp_regs_arr_64, - dp_regs_arr_64 + sizeof(dp_regs_arr_64) / sizeof(dp_regs_arr_64[0])); -static const std::vector<RegStorage> reserved_regs_32(reserved_regs_arr_32, - reserved_regs_arr_32 + sizeof(reserved_regs_arr_32) / sizeof(reserved_regs_arr_32[0])); -static const std::vector<RegStorage> reserved_regs_64(reserved_regs_arr_64, - reserved_regs_arr_64 + sizeof(reserved_regs_arr_64) / sizeof(reserved_regs_arr_64[0])); -static const std::vector<RegStorage> reserved_regs_64q(reserved_regs_arr_64q, - reserved_regs_arr_64q + sizeof(reserved_regs_arr_64q) / sizeof(reserved_regs_arr_64q[0])); -static const std::vector<RegStorage> core_temps_32(core_temps_arr_32, - core_temps_arr_32 + sizeof(core_temps_arr_32) / sizeof(core_temps_arr_32[0])); -static const std::vector<RegStorage> core_temps_64(core_temps_arr_64, - core_temps_arr_64 + sizeof(core_temps_arr_64) / sizeof(core_temps_arr_64[0])); -static const std::vector<RegStorage> core_temps_64q(core_temps_arr_64q, - core_temps_arr_64q + sizeof(core_temps_arr_64q) / sizeof(core_temps_arr_64q[0])); -static const std::vector<RegStorage> sp_temps_32(sp_temps_arr_32, - sp_temps_arr_32 + sizeof(sp_temps_arr_32) / sizeof(sp_temps_arr_32[0])); -static const std::vector<RegStorage> sp_temps_64(sp_temps_arr_64, - sp_temps_arr_64 + sizeof(sp_temps_arr_64) / sizeof(sp_temps_arr_64[0])); -static const std::vector<RegStorage> dp_temps_32(dp_temps_arr_32, - dp_temps_arr_32 + sizeof(dp_temps_arr_32) / sizeof(dp_temps_arr_32[0])); -static const std::vector<RegStorage> dp_temps_64(dp_temps_arr_64, - dp_temps_arr_64 + sizeof(dp_temps_arr_64) / sizeof(dp_temps_arr_64[0])); - -static const std::vector<RegStorage> xp_temps_32(xp_temps_arr_32, - xp_temps_arr_32 + sizeof(xp_temps_arr_32) / sizeof(xp_temps_arr_32[0])); -static const std::vector<RegStorage> xp_temps_64(xp_temps_arr_64, - xp_temps_arr_64 + sizeof(xp_temps_arr_64) / sizeof(xp_temps_arr_64[0])); +static constexpr ArrayRef<const RegStorage> empty_pool; +static constexpr ArrayRef<const RegStorage> core_regs_32(core_regs_arr_32); +static constexpr ArrayRef<const RegStorage> core_regs_64(core_regs_arr_64); +static constexpr ArrayRef<const RegStorage> core_regs_64q(core_regs_arr_64q); +static constexpr ArrayRef<const RegStorage> sp_regs_32(sp_regs_arr_32); +static constexpr ArrayRef<const RegStorage> sp_regs_64(sp_regs_arr_64); +static constexpr ArrayRef<const RegStorage> dp_regs_32(dp_regs_arr_32); +static constexpr ArrayRef<const RegStorage> dp_regs_64(dp_regs_arr_64); +static constexpr ArrayRef<const RegStorage> reserved_regs_32(reserved_regs_arr_32); +static constexpr ArrayRef<const RegStorage> reserved_regs_64(reserved_regs_arr_64); +static constexpr ArrayRef<const RegStorage> reserved_regs_64q(reserved_regs_arr_64q); +static constexpr ArrayRef<const RegStorage> core_temps_32(core_temps_arr_32); +static constexpr ArrayRef<const RegStorage> core_temps_64(core_temps_arr_64); +static constexpr ArrayRef<const RegStorage> core_temps_64q(core_temps_arr_64q); +static constexpr ArrayRef<const RegStorage> sp_temps_32(sp_temps_arr_32); +static constexpr ArrayRef<const RegStorage> sp_temps_64(sp_temps_arr_64); +static constexpr ArrayRef<const RegStorage> dp_temps_32(dp_temps_arr_32); +static constexpr ArrayRef<const RegStorage> dp_temps_64(dp_temps_arr_64); + +static constexpr ArrayRef<const RegStorage> xp_temps_32(xp_temps_arr_32); +static constexpr ArrayRef<const RegStorage> xp_temps_64(xp_temps_arr_64); RegStorage rs_rX86_SP; @@ -582,7 +563,7 @@ void X86Mir2Lir::CompilerInitializeRegAlloc() { // Target-specific adjustments. // Add in XMM registers. - const std::vector<RegStorage> *xp_temps = Gen64Bit() ? &xp_temps_64 : &xp_temps_32; + const ArrayRef<const RegStorage> *xp_temps = Gen64Bit() ? &xp_temps_64 : &xp_temps_32; for (RegStorage reg : *xp_temps) { RegisterInfo* info = new (arena_) RegisterInfo(reg, GetRegMaskCommon(reg)); reginfo_map_.Put(reg.GetReg(), info); diff --git a/compiler/utils/array_ref.h b/compiler/utils/array_ref.h new file mode 100644 index 0000000000..5a68874da8 --- /dev/null +++ b/compiler/utils/array_ref.h @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_UTILS_ARRAY_REF_H_ +#define ART_COMPILER_UTILS_ARRAY_REF_H_ + +#include <type_traits> +#include <vector> + +#include "base/logging.h" + +namespace art { + +template <typename T, bool ok> struct ArrayRefHelper; + +/** + * @brief A container that references an array. + * + * @details The template class ArrayRef provides a container that references + * an external array. This external array must remain alive while the ArrayRef + * object is in use. The external array may be a std::vector<>-backed storage + * or any other contiguous chunk of memory but that memory must remain valid, + * i.e. the std::vector<> must not be resized for example. + * + * Except for copy/assign and insert/erase/capacity functions, the interface + * is essentially the same as std::vector<>. Since we don't want to throw + * exceptions, at() is also excluded. + */ +template <typename T> +class ArrayRef { + public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; + typedef T* iterator; + typedef const T* const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; + typedef ptrdiff_t difference_type; + typedef size_t size_type; + + // Constructors. + + constexpr ArrayRef() + : array_(nullptr), size_(0u) { + } + + template <size_t size> + constexpr ArrayRef(T (&array)[size]) + : array_(array), size_(size) { + } + + template <typename U, size_t size> + constexpr ArrayRef(U (&array)[size], + typename ArrayRefHelper<T, std::is_same<T, const U>::value>::tag t = tag()) + : array_(array), size_(size) { + } + + constexpr ArrayRef(T* array, size_t size) + : array_(array), size_(size) { + } + + template <typename U> + constexpr ArrayRef(U* array, size_t size, + typename ArrayRefHelper<T, std::is_same<T, const U>::value>::tag t = tag()) + : array_(array), size_(size) { + } + + explicit ArrayRef(std::vector<T>& v) + : array_(v.data()), size_(v.size()) { + } + + template <typename U> + ArrayRef(const std::vector<U>& v, + typename ArrayRefHelper<T, std::is_same<T, const U>::value>::tag t = tag()) + : array_(v.data()), size_(v.size()) { + } + + // Assignment operators. + + ArrayRef& operator=(const ArrayRef& other) { + array_ = other.array_; + size_ = other.size_; + return *this; + } + + template <typename U> + typename ArrayRefHelper<T, std::is_same<T, const U>::value>::type& + operator=(const ArrayRef<U>& other) { + return *this = ArrayRef(other); + } + + // Destructor. + ~ArrayRef() = default; + + // Iterators. + iterator begin() { return array_; } + const_iterator begin() const { return array_; } + const_iterator cbegin() const { return array_; } + iterator end() { return array_ + size_; } + const_iterator end() const { return array_ + size_; } + const_iterator cend() const { return array_ + size_; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator crbegin() const { return const_reverse_iterator(cend()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + const_reverse_iterator crend() const { return const_reverse_iterator(cbegin()); } + + // Size. + size_type size() const { return size_; } + bool empty() const { return size() == 0u; } + + // Element access. NOTE: Not providing at(). + + reference operator[](size_type n) { + DCHECK_LT(n, size_); + return array_[n]; + } + + const_reference operator[](size_type n) const { + DCHECK_LT(n, size_); + return array_[n]; + } + + reference front() { + DCHECK_NE(size_, 0u); + return array_[0]; + } + + const_reference front() const { + DCHECK_NE(size_, 0u); + return array_[0]; + } + + reference back() { + DCHECK_NE(size_, 0u); + return array_[size_ - 1u]; + } + + const_reference back() const { + DCHECK_NE(size_, 0u); + return array_[size_ - 1u]; + } + + value_type* data() { return array_; } + const value_type* data() const { return array_; } + + private: + struct tag { }; + friend struct ArrayRefHelper<T, true>; + + T* array_; + size_t size_; +}; + +template <typename T> struct ArrayRefHelper<T, true> { + typedef typename ArrayRef<T>::tag tag; + typedef ArrayRef<T> type; +}; + +template <typename T> struct ArrayRefHelper<T, false> { + // SFINAE: No "tag" or "type" typedef. +}; + +} // namespace art + + +#endif // ART_COMPILER_UTILS_ARRAY_REF_H_ |