1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef COMPILER_OPTIMIZER_OPTIMIZATIONS_LOCATION_MASK_H 16 #define COMPILER_OPTIMIZER_OPTIMIZATIONS_LOCATION_MASK_H 17 18 #include "mem/arena_allocator.h" 19 #include "utils/arena_containers.h" 20 21 namespace panda::compiler { 22 /** 23 * Helper-class to hold information about registers and stack slots usage. 24 */ 25 class LocationMask { 26 public: LocationMask(ArenaAllocator * allocator)27 explicit LocationMask(ArenaAllocator *allocator) : mask_(allocator->Adapter()), usage_(allocator->Adapter()) {} 28 ~LocationMask() = default; 29 DEFAULT_COPY_SEMANTIC(LocationMask); 30 DEFAULT_MOVE_SEMANTIC(LocationMask); 31 32 template <typename T> Init(const T & mask)33 void Init(const T &mask) 34 { 35 usage_.resize(mask.size()); 36 mask_.resize(mask.size()); 37 for (size_t idx = 0; idx < mask.size(); idx++) { 38 if (mask.test(idx)) { 39 Set(idx); 40 } else { 41 Reset(idx); 42 } 43 } 44 } 45 Resize(size_t size)46 void Resize(size_t size) 47 { 48 mask_.resize(size, false); 49 usage_.resize(size, false); 50 } 51 Set(size_t position)52 void Set(size_t position) 53 { 54 ASSERT(position < mask_.size()); 55 mask_[position] = true; 56 usage_[position] = true; 57 } 58 Reset(size_t position)59 void Reset(size_t position) 60 { 61 ASSERT(position < mask_.size()); 62 mask_[position] = false; 63 } 64 IsSet(size_t position)65 bool IsSet(size_t position) const 66 { 67 ASSERT(position < mask_.size()); 68 return mask_[position]; 69 } 70 Reserve(size_t reserved_bit)71 void Reserve(size_t reserved_bit) 72 { 73 reserved_bit_ = reserved_bit; 74 Set(reserved_bit); 75 } 76 GetReserved()77 std::optional<size_t> GetReserved() const 78 { 79 return reserved_bit_; 80 } 81 GetVector()82 const auto &GetVector() const 83 { 84 return mask_; 85 } 86 87 std::optional<size_t> GetNextNotSet(size_t first_bit = 0) 88 { 89 for (size_t r = first_bit; r < mask_.size(); r++) { 90 if (!mask_[r]) { 91 Set(r); 92 return r; 93 } 94 } 95 for (size_t r = 0; r < first_bit; r++) { 96 if (!mask_[r]) { 97 Set(r); 98 return r; 99 } 100 } 101 return std::nullopt; 102 } 103 AllSet()104 bool AllSet() const 105 { 106 return std::all_of(mask_.begin(), mask_.end(), [](bool v) { return v; }); 107 } 108 GetUsedCount()109 size_t GetUsedCount() const 110 { 111 return std::count(usage_.begin(), usage_.end(), true); 112 } 113 GetSize()114 size_t GetSize() const 115 { 116 return mask_.size(); 117 } 118 Empty()119 bool Empty() const 120 { 121 return mask_.empty(); 122 } 123 Dump(std::ostream * out)124 void Dump(std::ostream *out) const 125 { 126 for (bool val : mask_) { 127 (*out) << val; 128 } 129 (*out) << "\n"; 130 } 131 132 private: 133 ArenaVector<bool> mask_; 134 ArenaVector<bool> usage_; 135 std::optional<size_t> reserved_bit_ {std::nullopt}; 136 }; 137 } // namespace panda::compiler 138 #endif // COMPILER_OPTIMIZER_OPTIMIZATIONS_LOCATION_MASK_H