1 /* 2 * Copyright (c) 2023 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 16 #ifndef MAPLEBE_INCLUDE_CG_DATAINFO_H 17 #define MAPLEBE_INCLUDE_CG_DATAINFO_H 18 #include "maple_string.h" 19 #include "common_utils.h" 20 #include "mempool.h" 21 #include "mempool_allocator.h" 22 23 namespace maplebe { 24 class DataInfo { 25 public: DataInfo(uint32 bitNum,MapleAllocator & alloc)26 DataInfo(uint32 bitNum, MapleAllocator &alloc) : info(alloc.Adapter()) 27 { 28 info.resize(bitNum / kWordSize + 1, 0); 29 } DataInfo(const DataInfo & other,MapleAllocator & alloc)30 DataInfo(const DataInfo &other, MapleAllocator &alloc) : info(other.info, alloc.Adapter()) {} Clone(MapleAllocator & alloc)31 DataInfo &Clone(MapleAllocator &alloc) 32 { 33 auto *dataInfo = alloc.New<DataInfo>(*this, alloc); 34 return *dataInfo; 35 } 36 37 ~DataInfo() = default; 38 SetBit(int64 bitNO)39 void SetBit(int64 bitNO) 40 { 41 DEBUG_ASSERT(static_cast<size_t>(bitNO) < info.size() * kWordSize, "Out of Range"); 42 info[static_cast<size_t>(bitNO / kWordSize)] |= (1ULL << static_cast<uint64>((bitNO % kWordSize))); 43 } 44 ResetBit(uint32 bitNO)45 void ResetBit(uint32 bitNO) 46 { 47 info[bitNO / kWordSize] &= (~(1ULL << (bitNO % kWordSize))); 48 } 49 TestBit(uint32 bitNO)50 bool TestBit(uint32 bitNO) const 51 { 52 return (info[bitNO / kWordSize] & (1ULL << (bitNO % kWordSize))) != 0ULL; 53 } 54 GetElem(uint32 index)55 const uint64 &GetElem(uint32 index) const 56 { 57 DEBUG_ASSERT(index < info.size(), "out of range"); 58 return info[index]; 59 } 60 SetElem(uint32 index,uint64 val)61 void SetElem(uint32 index, uint64 val) 62 { 63 DEBUG_ASSERT(index < info.size(), "out of range"); 64 info[index] = val; 65 } 66 NoneBit()67 bool NoneBit() const 68 { 69 for (auto &data : info) { 70 if (data != 0ULL) { 71 return false; 72 } 73 } 74 return true; 75 } 76 Size()77 size_t Size() const 78 { 79 return info.size() * kWordSize; 80 } 81 GetInfo()82 const MapleVector<uint64> &GetInfo() const 83 { 84 return info; 85 } 86 IsEqual(const DataInfo & secondInfo)87 bool IsEqual(const DataInfo &secondInfo) const 88 { 89 auto infoSize = static_cast<const uint32>(info.size()); 90 DEBUG_ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); 91 for (uint32 i = 0; i != infoSize; ++i) { 92 if (info[i] != secondInfo.GetElem(i)) { 93 return false; 94 } 95 } 96 return true; 97 } 98 IsEqual(const MapleVector<uint64> & LiveInfoBak)99 bool IsEqual(const MapleVector<uint64> &LiveInfoBak) const 100 { 101 size_t infoSize = info.size(); 102 DEBUG_ASSERT(infoSize == LiveInfoBak.size(), "two dataInfo's size different"); 103 for (size_t i = 0; i != infoSize; ++i) { 104 if (info[i] != LiveInfoBak[i]) { 105 return false; 106 } 107 } 108 return true; 109 } 110 AndBits(const DataInfo & secondInfo)111 void AndBits(const DataInfo &secondInfo) 112 { 113 auto infoSize = static_cast<const uint32>(info.size()); 114 DEBUG_ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); 115 for (uint32 i = 0; i != infoSize; ++i) { 116 info[i] &= secondInfo.GetElem(i); 117 } 118 } 119 OrBits(const DataInfo & secondInfo)120 void OrBits(const DataInfo &secondInfo) 121 { 122 auto infoSize = static_cast<const uint32>(info.size()); 123 DEBUG_ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); 124 for (uint32 i = 0; i != infoSize; i++) { 125 info[i] |= secondInfo.GetElem(i); 126 } 127 } 128 OrDesignateBits(const DataInfo & secondInfo,uint32 infoIndex)129 void OrDesignateBits(const DataInfo &secondInfo, uint32 infoIndex) 130 { 131 DEBUG_ASSERT(infoIndex < secondInfo.GetInfo().size(), "out of secondInfo's range"); 132 DEBUG_ASSERT(infoIndex < info.size(), "out of secondInfo's range"); 133 info[infoIndex] |= secondInfo.GetElem(infoIndex); 134 } 135 EorBits(const DataInfo & secondInfo)136 void EorBits(const DataInfo &secondInfo) 137 { 138 auto infoSize = static_cast<const uint32>(info.size()); 139 DEBUG_ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); 140 for (uint32 i = 0; i != infoSize; i++) { 141 info[i] ^= secondInfo.GetElem(i); 142 } 143 } 144 145 /* if bit in secondElem is 1, bit in current DataInfo is set 0 */ Difference(const DataInfo & secondInfo)146 void Difference(const DataInfo &secondInfo) 147 { 148 auto infoSize = static_cast<const uint32>(info.size()); 149 DEBUG_ASSERT(infoSize == secondInfo.GetInfo().size(), "two dataInfo's size different"); 150 for (uint32 i = 0; i != infoSize; i++) { 151 info[i] &= (~(secondInfo.GetElem(i))); 152 } 153 } 154 ResetAllBit()155 void ResetAllBit() 156 { 157 for (auto &data : info) { 158 data = 0ULL; 159 } 160 } 161 EnlargeCapacityToAdaptSize(uint32 bitNO)162 void EnlargeCapacityToAdaptSize(uint32 bitNO) 163 { 164 /* add one more size for each enlarge action */ 165 info.resize(bitNO / kWordSize + 1, 0); 166 } 167 GetNonZeroElemsIndex(std::set<uint32> & index)168 void GetNonZeroElemsIndex(std::set<uint32> &index) 169 { 170 auto infoSize = static_cast<const int32>(info.size()); 171 for (int32 i = 0; i < infoSize; i++) { 172 if (info[i] != 0ULL) { 173 (void)index.insert(i); 174 } 175 } 176 } 177 178 template <typename T> GetBitsOfInfo(T & wordRes)179 void GetBitsOfInfo(T &wordRes) const 180 { 181 wordRes.clear(); 182 for (size_t i = 0; i != info.size(); ++i) { 183 uint32 result = 0; 184 uint64 word = info[i]; 185 uint32 offset = 0; 186 uint32 baseWord = 0; 187 bool firstTime = true; 188 while (word) { 189 int32 index = __builtin_ffsll(static_cast<int64>(word)); 190 if (index == 0) { 191 continue; 192 } 193 if (index == k64BitSize) { 194 /* when the highest bit is 1, the shift operation will cause error, need special treatment. */ 195 result = i * kWordSize + (index - 1); 196 (void)wordRes.insert(result); 197 break; 198 } 199 if (firstTime) { 200 offset = static_cast<uint32>(index - 1); 201 baseWord = i * kWordSize; 202 firstTime = false; 203 } else { 204 offset = static_cast<uint32>(index); 205 baseWord = 0; 206 } 207 result += baseWord + offset; 208 (void)wordRes.insert(result); 209 word = word >> static_cast<uint64>(index); 210 } 211 } 212 } 213 ClearDataInfo()214 void ClearDataInfo() 215 { 216 info.clear(); 217 } 218 219 private: 220 /* long type has 8 bytes, 64 bits */ 221 static constexpr int32 kWordSize = 64; 222 MapleVector<uint64> info; 223 }; 224 } /* namespace maplebe */ 225 #endif /* MAPLEBE_INCLUDE_CG_INSN_H */ 226