• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */