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_LSDA_H 17 #define MAPLEBE_INCLUDE_CG_LSDA_H 18 #include "types_def.h" 19 #include "mir_nodes.h" 20 #include "cgbb.h" 21 22 namespace maplebe { 23 using namespace maple; 24 25 class LabelPair { 26 public: 27 LabelPair() = default; LabelPair(LabelNode * startOffsetLbl,LabelNode * endOffsetLbl)28 LabelPair(LabelNode *startOffsetLbl, LabelNode *endOffsetLbl) 29 { 30 startOffset = startOffsetLbl; 31 endOffset = endOffsetLbl; 32 } 33 ~LabelPair() = default; 34 GetStartOffset()35 const LabelNode *GetStartOffset() const 36 { 37 return startOffset; 38 } 39 SetStartOffset(LabelNode * lableNode)40 void SetStartOffset(LabelNode *lableNode) 41 { 42 startOffset = lableNode; 43 } 44 GetEndOffset()45 const LabelNode *GetEndOffset() const 46 { 47 return endOffset; 48 } 49 SetEndOffsetLabelIdx(LabelIdx index)50 void SetEndOffsetLabelIdx(LabelIdx index) const 51 { 52 endOffset->SetLabelIdx(index); 53 } 54 SetEndOffset(LabelNode * labelNode)55 void SetEndOffset(LabelNode *labelNode) 56 { 57 endOffset = labelNode; 58 } 59 60 private: 61 LabelNode *startOffset; 62 LabelNode *endOffset; 63 }; 64 65 class LSDAHeader { 66 public: GetLSDALabel()67 const LabelNode *GetLSDALabel() const 68 { 69 return lsdaLabel; 70 } 71 SetLSDALabel(LabelNode & labelNode)72 void SetLSDALabel(LabelNode &labelNode) 73 { 74 lsdaLabel = &labelNode; 75 } 76 GetLPStartEncoding()77 uint8 GetLPStartEncoding() const 78 { 79 return lpStartEncoding; 80 } 81 SetLPStartEncoding(uint8 encoding)82 void SetLPStartEncoding(uint8 encoding) 83 { 84 lpStartEncoding = encoding; 85 } 86 GetTTypeEncoding()87 uint8 GetTTypeEncoding() const 88 { 89 return tTypeEncoding; 90 } 91 SetTTypeEncoding(uint8 encoding)92 void SetTTypeEncoding(uint8 encoding) 93 { 94 tTypeEncoding = encoding; 95 } 96 GetTTypeOffset()97 const LabelPair &GetTTypeOffset() const 98 { 99 return tTypeOffset; 100 } 101 SetTTypeOffset(LabelNode * start,LabelNode * end)102 void SetTTypeOffset(LabelNode *start, LabelNode *end) 103 { 104 tTypeOffset.SetStartOffset(start); 105 tTypeOffset.SetEndOffset(end); 106 } 107 GetCallSiteEncoding()108 uint8 GetCallSiteEncoding() const 109 { 110 return callSiteEncoding; 111 } 112 SetCallSiteEncoding(uint8 encoding)113 void SetCallSiteEncoding(uint8 encoding) 114 { 115 callSiteEncoding = encoding; 116 } 117 118 private: 119 LabelNode *lsdaLabel; 120 uint8 lpStartEncoding; 121 uint8 tTypeEncoding; 122 LabelPair tTypeOffset; 123 uint8 callSiteEncoding; 124 }; 125 126 struct LSDACallSite { 127 LabelPair csStart; 128 LabelPair csLength; 129 LabelPair csLandingPad; 130 uint32 csAction; 131 132 public: InitLSDACallSite133 void Init(const LabelPair &start, const LabelPair &length, const LabelPair &landingPad, uint32 action) 134 { 135 csStart = start; 136 csLength = length; 137 csLandingPad = landingPad; 138 csAction = action; 139 } 140 }; 141 142 class LSDAAction { 143 public: LSDAAction(uint8 idx,uint8 filter)144 LSDAAction(uint8 idx, uint8 filter) : actionIndex(idx), actionFilter(filter) {} 145 ~LSDAAction() = default; 146 GetActionIndex()147 uint8 GetActionIndex() const 148 { 149 return actionIndex; 150 } 151 GetActionFilter()152 uint8 GetActionFilter() const 153 { 154 return actionFilter; 155 } 156 157 private: 158 uint8 actionIndex; 159 uint8 actionFilter; 160 }; 161 162 class LSDACallSiteTable { 163 public: LSDACallSiteTable(MapleAllocator & alloc)164 explicit LSDACallSiteTable(MapleAllocator &alloc) : callSiteTable(alloc.Adapter()) 165 { 166 csTable.SetStartOffset(nullptr); 167 csTable.SetEndOffset(nullptr); 168 } 169 ~LSDACallSiteTable() = default; 170 GetCallSiteTable()171 const MapleVector<LSDACallSite *> &GetCallSiteTable() const 172 { 173 return callSiteTable; 174 } 175 PushBack(LSDACallSite & lsdaCallSite)176 void PushBack(LSDACallSite &lsdaCallSite) 177 { 178 callSiteTable.emplace_back(&lsdaCallSite); 179 } 180 GetCSTable()181 const LabelPair &GetCSTable() const 182 { 183 return csTable; 184 } 185 SetCSTable(LabelNode * start,LabelNode * end)186 void SetCSTable(LabelNode *start, LabelNode *end) 187 { 188 csTable.SetStartOffset(start); 189 csTable.SetEndOffset(end); 190 } 191 UpdateCallSite(const BB & oldBB,const BB & newBB)192 void UpdateCallSite(const BB &oldBB, const BB &newBB) 193 { 194 for (auto *callSite : callSiteTable) { 195 if (callSite->csStart.GetEndOffset() != nullptr) { 196 if (callSite->csStart.GetEndOffset()->GetLabelIdx() == oldBB.GetLabIdx()) { 197 callSite->csStart.SetEndOffsetLabelIdx(newBB.GetLabIdx()); 198 } 199 } 200 201 CHECK_NULL_FATAL(callSite->csLength.GetEndOffset()); 202 if (callSite->csLength.GetEndOffset()->GetLabelIdx() == oldBB.GetLabIdx()) { 203 callSite->csLength.SetEndOffsetLabelIdx(newBB.GetLabIdx()); 204 } 205 206 if (callSite->csLandingPad.GetEndOffset() != nullptr) { 207 if (callSite->csLandingPad.GetEndOffset()->GetLabelIdx() == oldBB.GetLabIdx()) { 208 callSite->csLandingPad.SetEndOffsetLabelIdx(newBB.GetLabIdx()); 209 } 210 } 211 } 212 } 213 RemoveCallSite(const BB & bb)214 void RemoveCallSite(const BB &bb) 215 { 216 for (int32 i = static_cast<int32>(callSiteTable.size()) - 1; i > -1; --i) { 217 if (callSiteTable[i]->csStart.GetEndOffset() != nullptr) { 218 if (callSiteTable[i]->csStart.GetEndOffset()->GetLabelIdx() == bb.GetLabIdx()) { 219 callSiteTable.erase(callSiteTable.begin() + i); 220 continue; 221 } 222 } 223 if (callSiteTable[i]->csLandingPad.GetEndOffset() != nullptr) { 224 if (callSiteTable[i]->csLandingPad.GetEndOffset()->GetLabelIdx() == bb.GetLabIdx()) { 225 callSiteTable.erase(callSiteTable.begin() + i); 226 continue; 227 } 228 } 229 } 230 } 231 232 /* return true if label is in callSiteTable */ InCallSiteTable(LabelIdx label)233 bool InCallSiteTable(LabelIdx label) const 234 { 235 for (auto *callSite : callSiteTable) { 236 if (label == callSite->csStart.GetEndOffset()->GetLabelIdx() || 237 label == callSite->csStart.GetStartOffset()->GetLabelIdx()) { 238 return true; 239 } 240 if (label == callSite->csLength.GetEndOffset()->GetLabelIdx() || 241 label == callSite->csLength.GetStartOffset()->GetLabelIdx()) { 242 return true; 243 } 244 if (callSite->csLandingPad.GetStartOffset()) { 245 if (label == callSite->csLandingPad.GetEndOffset()->GetLabelIdx() || 246 label == callSite->csLandingPad.GetStartOffset()->GetLabelIdx()) { 247 return true; 248 } 249 } 250 } 251 return false; 252 } 253 IsTryBlock(const BB & bb)254 bool IsTryBlock(const BB &bb) const 255 { 256 for (auto *callSite : callSiteTable) { 257 if (callSite->csLength.GetStartOffset()->GetLabelIdx() == bb.GetLabIdx()) { 258 return true; 259 } 260 } 261 return false; 262 } 263 SortCallSiteTable(std::function<bool (LSDACallSite * site1,LSDACallSite * site2)> const & func)264 void SortCallSiteTable(std::function<bool(LSDACallSite *site1, LSDACallSite *site2)> const &func) 265 { 266 std::sort(callSiteTable.begin(), callSiteTable.end(), func); 267 } 268 269 private: 270 MapleVector<LSDACallSite *> callSiteTable; 271 LabelPair csTable; 272 }; 273 274 class LSDAActionTable { 275 public: LSDAActionTable(MapleAllocator & alloc)276 explicit LSDAActionTable(MapleAllocator &alloc) : actionTable(alloc.Adapter()) {} 277 virtual ~LSDAActionTable() = default; 278 GetActionTable()279 const MapleVector<LSDAAction *> &GetActionTable() const 280 { 281 return actionTable; 282 } 283 PushBack(LSDAAction & lsdaAction)284 void PushBack(LSDAAction &lsdaAction) 285 { 286 actionTable.emplace_back(&lsdaAction); 287 } 288 Size()289 size_t Size() const 290 { 291 return actionTable.size(); 292 } 293 294 private: 295 MapleVector<LSDAAction *> actionTable; 296 }; 297 } /* namespace maplebe */ 298 299 #endif /* MAPLEBE_INCLUDE_CG_LSDA_H */