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 "base/value_object.h" 24 #include "dex/reg_storage.h" 25 26 namespace art { 27 28 class ArenaAllocator; 29 30 /** 31 * @brief Resource mask for LIR insn uses or defs. 32 * @detail Def/Use mask used for checking dependencies between LIR insns in local 33 * optimizations such as load hoisting. 34 */ 35 class ResourceMask { 36 private: 37 constexpr ResourceMask(uint64_t mask1, uint64_t mask2) 38 : masks_{ mask1, mask2 } { // NOLINT 39 } 40 41 public: 42 /* 43 * Def/Use encoding in 128-bit use_mask/def_mask. Low positions used for target-specific 44 * registers (and typically use the register number as the position). High positions 45 * reserved for common and abstract resources. 46 */ 47 enum ResourceBit { 48 kMustNotAlias = 127, 49 kHeapRef = 126, // Default memory reference type. 50 kLiteral = 125, // Literal pool memory reference. 51 kDalvikReg = 124, // Dalvik v_reg memory reference. 52 kFPStatus = 123, 53 kCCode = 122, 54 kLowestCommonResource = kCCode, 55 kHighestCommonResource = kMustNotAlias 56 }; 57 58 // Default-constructible. 59 constexpr ResourceMask() 60 : masks_ { 0u, 0u } { 61 } 62 63 // Copy-constructible and copyable. 64 ResourceMask(const ResourceMask& other) = default; 65 ResourceMask& operator=(const ResourceMask& other) = default; 66 67 // Comparable by content. 68 bool operator==(const ResourceMask& other) { 69 return masks_[0] == other.masks_[0] && masks_[1] == other.masks_[1]; 70 } 71 72 static constexpr ResourceMask RawMask(uint64_t mask1, uint64_t mask2) { 73 return ResourceMask(mask1, mask2); 74 } 75 76 static constexpr ResourceMask Bit(size_t bit) { 77 return ResourceMask(bit >= 64u ? 0u : UINT64_C(1) << bit, 78 bit >= 64u ? UINT64_C(1) << (bit - 64u) : 0u); 79 } 80 81 // Two consecutive bits. The start_bit must be even. 82 static constexpr ResourceMask TwoBits(size_t start_bit) { 83 return 84 DCHECK_CONSTEXPR((start_bit & 1u) == 0u, << start_bit << " isn't even", Bit(0)) 85 ResourceMask(start_bit >= 64u ? 0u : UINT64_C(3) << start_bit, 86 start_bit >= 64u ? UINT64_C(3) << (start_bit - 64u) : 0u); 87 } 88 89 static constexpr ResourceMask NoBits() { 90 return ResourceMask(UINT64_C(0), UINT64_C(0)); 91 } 92 93 static constexpr ResourceMask AllBits() { 94 return ResourceMask(~UINT64_C(0), ~UINT64_C(0)); 95 } 96 97 constexpr ResourceMask Union(const ResourceMask& other) const { 98 return ResourceMask(masks_[0] | other.masks_[0], masks_[1] | other.masks_[1]); 99 } 100 101 constexpr ResourceMask Intersection(const ResourceMask& other) const { 102 return ResourceMask(masks_[0] & other.masks_[0], masks_[1] & other.masks_[1]); 103 } 104 105 constexpr ResourceMask Without(const ResourceMask& other) const { 106 return ResourceMask(masks_[0] & ~other.masks_[0], masks_[1] & ~other.masks_[1]); 107 } 108 109 constexpr bool Equals(const ResourceMask& other) const { 110 return masks_[0] == other.masks_[0] && masks_[1] == other.masks_[1]; 111 } 112 113 constexpr bool Intersects(const ResourceMask& other) const { 114 return (masks_[0] & other.masks_[0]) != 0u || (masks_[1] & other.masks_[1]) != 0u; 115 } 116 117 void SetBit(size_t bit); 118 119 constexpr bool HasBit(size_t bit) const { 120 return (masks_[bit / 64u] & (UINT64_C(1) << (bit & 63u))) != 0u; 121 } 122 123 ResourceMask& SetBits(const ResourceMask& other) { 124 masks_[0] |= other.masks_[0]; 125 masks_[1] |= other.masks_[1]; 126 return *this; 127 } 128 129 ResourceMask& ClearBits(const ResourceMask& other) { 130 masks_[0] &= ~other.masks_[0]; 131 masks_[1] &= ~other.masks_[1]; 132 return *this; 133 } 134 135 private: 136 uint64_t masks_[2]; 137 138 friend class ResourceMaskCache; 139 }; 140 std::ostream& operator<<(std::ostream& os, const ResourceMask::ResourceBit& rhs); 141 142 inline void ResourceMask::SetBit(size_t bit) { 143 DCHECK_LE(bit, kHighestCommonResource); 144 masks_[bit / 64u] |= UINT64_C(1) << (bit & 63u); 145 } 146 147 constexpr ResourceMask kEncodeNone = ResourceMask::NoBits(); 148 constexpr ResourceMask kEncodeAll = ResourceMask::AllBits(); 149 constexpr ResourceMask kEncodeHeapRef = ResourceMask::Bit(ResourceMask::kHeapRef); 150 constexpr ResourceMask kEncodeLiteral = ResourceMask::Bit(ResourceMask::kLiteral); 151 constexpr ResourceMask kEncodeDalvikReg = ResourceMask::Bit(ResourceMask::kDalvikReg); 152 constexpr ResourceMask kEncodeMem = kEncodeLiteral.Union(kEncodeDalvikReg).Union( 153 kEncodeHeapRef).Union(ResourceMask::Bit(ResourceMask::kMustNotAlias)); 154 155 class ResourceMaskCache { 156 public: 157 explicit ResourceMaskCache(ArenaAllocator* allocator) 158 : allocator_(allocator) { 159 } 160 161 const ResourceMask* GetMask(const ResourceMask& mask); 162 163 private: 164 ArenaAllocator* allocator_; 165 }; 166 167 } // namespace art 168 169 #endif // ART_COMPILER_DEX_QUICK_RESOURCE_MASK_H_ 170