1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_COMPILER_DEX_QUICK_RESOURCE_MASK_H_ 18 #define ART_COMPILER_DEX_QUICK_RESOURCE_MASK_H_ 19 20 #include <stdint.h> 21 22 #include "base/logging.h" 23 #include "dex/reg_storage.h" 24 25 namespace art { 26 27 class ArenaAllocator; 28 29 /** 30 * @brief Resource mask for LIR insn uses or defs. 31 * @detail Def/Use mask used for checking dependencies between LIR insns in local 32 * optimizations such as load hoisting. 33 */ 34 class ResourceMask { 35 private: ResourceMask(uint64_t mask1,uint64_t mask2)36 constexpr ResourceMask(uint64_t mask1, uint64_t mask2) 37 : masks_{ mask1, mask2 } { // NOLINT 38 } 39 40 public: 41 /* 42 * Def/Use encoding in 128-bit use_mask/def_mask. Low positions used for target-specific 43 * registers (and typically use the register number as the position). High positions 44 * reserved for common and abstract resources. 45 */ 46 enum ResourceBit { 47 kMustNotAlias = 127, 48 kHeapRef = 126, // Default memory reference type. 49 kLiteral = 125, // Literal pool memory reference. 50 kDalvikReg = 124, // Dalvik v_reg memory reference. 51 kFPStatus = 123, 52 kCCode = 122, 53 kLowestCommonResource = kCCode, 54 kHighestCommonResource = kMustNotAlias 55 }; 56 57 // Default-constructible. ResourceMask()58 constexpr ResourceMask() 59 : masks_ { 0u, 0u } { 60 } 61 62 // Copy-constructible and copyable. 63 ResourceMask(const ResourceMask& other) = default; 64 ResourceMask& operator=(const ResourceMask& other) = default; 65 66 // Comparable by content. 67 bool operator==(const ResourceMask& other) { 68 return masks_[0] == other.masks_[0] && masks_[1] == other.masks_[1]; 69 } 70 RawMask(uint64_t mask1,uint64_t mask2)71 static constexpr ResourceMask RawMask(uint64_t mask1, uint64_t mask2) { 72 return ResourceMask(mask1, mask2); 73 } 74 Bit(size_t bit)75 static constexpr ResourceMask Bit(size_t bit) { 76 return ResourceMask(bit >= 64u ? 0u : UINT64_C(1) << bit, 77 bit >= 64u ? UINT64_C(1) << (bit - 64u) : 0u); 78 } 79 80 // Two consecutive bits. The start_bit must be even. TwoBits(size_t start_bit)81 static constexpr ResourceMask TwoBits(size_t start_bit) { 82 return 83 DCHECK_CONSTEXPR((start_bit & 1u) == 0u, << start_bit << " isn't even", Bit(0)) 84 ResourceMask(start_bit >= 64u ? 0u : UINT64_C(3) << start_bit, 85 start_bit >= 64u ? UINT64_C(3) << (start_bit - 64u) : 0u); 86 } 87 NoBits()88 static constexpr ResourceMask NoBits() { 89 return ResourceMask(UINT64_C(0), UINT64_C(0)); 90 } 91 AllBits()92 static constexpr ResourceMask AllBits() { 93 return ResourceMask(~UINT64_C(0), ~UINT64_C(0)); 94 } 95 Union(const ResourceMask & other)96 constexpr ResourceMask Union(const ResourceMask& other) const { 97 return ResourceMask(masks_[0] | other.masks_[0], masks_[1] | other.masks_[1]); 98 } 99 Intersection(const ResourceMask & other)100 constexpr ResourceMask Intersection(const ResourceMask& other) const { 101 return ResourceMask(masks_[0] & other.masks_[0], masks_[1] & other.masks_[1]); 102 } 103 Without(const ResourceMask & other)104 constexpr ResourceMask Without(const ResourceMask& other) const { 105 return ResourceMask(masks_[0] & ~other.masks_[0], masks_[1] & ~other.masks_[1]); 106 } 107 Equals(const ResourceMask & other)108 constexpr bool Equals(const ResourceMask& other) const { 109 return masks_[0] == other.masks_[0] && masks_[1] == other.masks_[1]; 110 } 111 Intersects(const ResourceMask & other)112 constexpr bool Intersects(const ResourceMask& other) const { 113 return (masks_[0] & other.masks_[0]) != 0u || (masks_[1] & other.masks_[1]) != 0u; 114 } 115 SetBit(size_t bit)116 void SetBit(size_t bit) { 117 DCHECK_LE(bit, kHighestCommonResource); 118 masks_[bit / 64u] |= UINT64_C(1) << (bit & 63u); 119 } 120 HasBit(size_t bit)121 constexpr bool HasBit(size_t bit) const { 122 return (masks_[bit / 64u] & (UINT64_C(1) << (bit & 63u))) != 0u; 123 } 124 SetBits(const ResourceMask & other)125 ResourceMask& SetBits(const ResourceMask& other) { 126 masks_[0] |= other.masks_[0]; 127 masks_[1] |= other.masks_[1]; 128 return *this; 129 } 130 ClearBits(const ResourceMask & other)131 ResourceMask& ClearBits(const ResourceMask& other) { 132 masks_[0] &= ~other.masks_[0]; 133 masks_[1] &= ~other.masks_[1]; 134 return *this; 135 } 136 137 private: 138 uint64_t masks_[2]; 139 140 friend class ResourceMaskCache; 141 }; 142 143 constexpr ResourceMask kEncodeNone = ResourceMask::NoBits(); 144 constexpr ResourceMask kEncodeAll = ResourceMask::AllBits(); 145 constexpr ResourceMask kEncodeHeapRef = ResourceMask::Bit(ResourceMask::kHeapRef); 146 constexpr ResourceMask kEncodeLiteral = ResourceMask::Bit(ResourceMask::kLiteral); 147 constexpr ResourceMask kEncodeDalvikReg = ResourceMask::Bit(ResourceMask::kDalvikReg); 148 constexpr ResourceMask kEncodeMem = kEncodeLiteral.Union(kEncodeDalvikReg).Union( 149 kEncodeHeapRef).Union(ResourceMask::Bit(ResourceMask::kMustNotAlias)); 150 151 class ResourceMaskCache { 152 public: ResourceMaskCache(ArenaAllocator * allocator)153 explicit ResourceMaskCache(ArenaAllocator* allocator) 154 : allocator_(allocator) { 155 } 156 157 const ResourceMask* GetMask(const ResourceMask& mask); 158 159 private: 160 ArenaAllocator* allocator_; 161 }; 162 163 } // namespace art 164 165 #endif // ART_COMPILER_DEX_QUICK_RESOURCE_MASK_H_ 166