/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MAPLEBE_INCLUDE_CG_LSDA_H #define MAPLEBE_INCLUDE_CG_LSDA_H #include "types_def.h" #include "mir_nodes.h" #include "cgbb.h" namespace maplebe { using namespace maple; class LabelPair { public: LabelPair() = default; LabelPair(LabelNode *startOffsetLbl, LabelNode *endOffsetLbl) { startOffset = startOffsetLbl; endOffset = endOffsetLbl; } ~LabelPair() = default; const LabelNode *GetStartOffset() const { return startOffset; } void SetStartOffset(LabelNode *lableNode) { startOffset = lableNode; } const LabelNode *GetEndOffset() const { return endOffset; } void SetEndOffsetLabelIdx(LabelIdx index) const { endOffset->SetLabelIdx(index); } void SetEndOffset(LabelNode *labelNode) { endOffset = labelNode; } private: LabelNode *startOffset; LabelNode *endOffset; }; class LSDAHeader { public: const LabelNode *GetLSDALabel() const { return lsdaLabel; } void SetLSDALabel(LabelNode &labelNode) { lsdaLabel = &labelNode; } uint8 GetLPStartEncoding() const { return lpStartEncoding; } void SetLPStartEncoding(uint8 encoding) { lpStartEncoding = encoding; } uint8 GetTTypeEncoding() const { return tTypeEncoding; } void SetTTypeEncoding(uint8 encoding) { tTypeEncoding = encoding; } const LabelPair &GetTTypeOffset() const { return tTypeOffset; } void SetTTypeOffset(LabelNode *start, LabelNode *end) { tTypeOffset.SetStartOffset(start); tTypeOffset.SetEndOffset(end); } uint8 GetCallSiteEncoding() const { return callSiteEncoding; } void SetCallSiteEncoding(uint8 encoding) { callSiteEncoding = encoding; } private: LabelNode *lsdaLabel; uint8 lpStartEncoding; uint8 tTypeEncoding; LabelPair tTypeOffset; uint8 callSiteEncoding; }; struct LSDACallSite { LabelPair csStart; LabelPair csLength; LabelPair csLandingPad; uint32 csAction; public: void Init(const LabelPair &start, const LabelPair &length, const LabelPair &landingPad, uint32 action) { csStart = start; csLength = length; csLandingPad = landingPad; csAction = action; } }; class LSDAAction { public: LSDAAction(uint8 idx, uint8 filter) : actionIndex(idx), actionFilter(filter) {} ~LSDAAction() = default; uint8 GetActionIndex() const { return actionIndex; } uint8 GetActionFilter() const { return actionFilter; } private: uint8 actionIndex; uint8 actionFilter; }; class LSDACallSiteTable { public: explicit LSDACallSiteTable(MapleAllocator &alloc) : callSiteTable(alloc.Adapter()) { csTable.SetStartOffset(nullptr); csTable.SetEndOffset(nullptr); } ~LSDACallSiteTable() = default; const MapleVector &GetCallSiteTable() const { return callSiteTable; } void PushBack(LSDACallSite &lsdaCallSite) { callSiteTable.emplace_back(&lsdaCallSite); } const LabelPair &GetCSTable() const { return csTable; } void SetCSTable(LabelNode *start, LabelNode *end) { csTable.SetStartOffset(start); csTable.SetEndOffset(end); } void UpdateCallSite(const BB &oldBB, const BB &newBB) { for (auto *callSite : callSiteTable) { if (callSite->csStart.GetEndOffset() != nullptr) { if (callSite->csStart.GetEndOffset()->GetLabelIdx() == oldBB.GetLabIdx()) { callSite->csStart.SetEndOffsetLabelIdx(newBB.GetLabIdx()); } } CHECK_NULL_FATAL(callSite->csLength.GetEndOffset()); if (callSite->csLength.GetEndOffset()->GetLabelIdx() == oldBB.GetLabIdx()) { callSite->csLength.SetEndOffsetLabelIdx(newBB.GetLabIdx()); } if (callSite->csLandingPad.GetEndOffset() != nullptr) { if (callSite->csLandingPad.GetEndOffset()->GetLabelIdx() == oldBB.GetLabIdx()) { callSite->csLandingPad.SetEndOffsetLabelIdx(newBB.GetLabIdx()); } } } } void RemoveCallSite(const BB &bb) { for (int32 i = static_cast(callSiteTable.size()) - 1; i > -1; --i) { if (callSiteTable[i]->csStart.GetEndOffset() != nullptr) { if (callSiteTable[i]->csStart.GetEndOffset()->GetLabelIdx() == bb.GetLabIdx()) { callSiteTable.erase(callSiteTable.begin() + i); continue; } } if (callSiteTable[i]->csLandingPad.GetEndOffset() != nullptr) { if (callSiteTable[i]->csLandingPad.GetEndOffset()->GetLabelIdx() == bb.GetLabIdx()) { callSiteTable.erase(callSiteTable.begin() + i); continue; } } } } /* return true if label is in callSiteTable */ bool InCallSiteTable(LabelIdx label) const { for (auto *callSite : callSiteTable) { if (label == callSite->csStart.GetEndOffset()->GetLabelIdx() || label == callSite->csStart.GetStartOffset()->GetLabelIdx()) { return true; } if (label == callSite->csLength.GetEndOffset()->GetLabelIdx() || label == callSite->csLength.GetStartOffset()->GetLabelIdx()) { return true; } if (callSite->csLandingPad.GetStartOffset()) { if (label == callSite->csLandingPad.GetEndOffset()->GetLabelIdx() || label == callSite->csLandingPad.GetStartOffset()->GetLabelIdx()) { return true; } } } return false; } bool IsTryBlock(const BB &bb) const { for (auto *callSite : callSiteTable) { if (callSite->csLength.GetStartOffset()->GetLabelIdx() == bb.GetLabIdx()) { return true; } } return false; } void SortCallSiteTable(std::function const &func) { std::sort(callSiteTable.begin(), callSiteTable.end(), func); } private: MapleVector callSiteTable; LabelPair csTable; }; class LSDAActionTable { public: explicit LSDAActionTable(MapleAllocator &alloc) : actionTable(alloc.Adapter()) {} virtual ~LSDAActionTable() = default; const MapleVector &GetActionTable() const { return actionTable; } void PushBack(LSDAAction &lsdaAction) { actionTable.emplace_back(&lsdaAction); } size_t Size() const { return actionTable.size(); } private: MapleVector actionTable; }; } /* namespace maplebe */ #endif /* MAPLEBE_INCLUDE_CG_LSDA_H */