• 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_BE_TRY_CATCH_H
17 #define MAPLEBE_INCLUDE_BE_TRY_CATCH_H
18 #include "bbt.h"
19 /* MapleIR headers. */
20 #include "mir_nodes.h"
21 #include "mir_lower.h"
22 
23 namespace maplebe {
24 using namespace maple;
25 class TryEndTryBlock {
26 public:
TryEndTryBlock(MemPool & memPool)27     explicit TryEndTryBlock(MemPool &memPool)
28         : allocator(&memPool),
29           enclosedBBs(allocator.Adapter()),
30           labeledBBsInTry(allocator.Adapter()),
31           bbsToRelocate(allocator.Adapter())
32     {
33     }
34 
35     ~TryEndTryBlock() = default;
36 
Init()37     void Init()
38     {
39         startTryBB = nullptr;
40         endTryBB = nullptr;
41         tryStmt = nullptr;
42         enclosedBBs.clear();
43         labeledBBsInTry.clear();
44         bbsToRelocate.clear();
45     }
46 
Reset(BBT & startBB)47     void Reset(BBT &startBB)
48     {
49         startTryBB = &startBB;
50         CHECK_NULL_FATAL(startTryBB->GetKeyStmt());
51         tryStmt = startTryBB->GetKeyStmt();
52         CHECK_FATAL(tryStmt->GetOpCode() == OP_try, "expect OPT_try");
53         endTryBB = nullptr;
54         enclosedBBs.clear();
55         labeledBBsInTry.clear();
56         bbsToRelocate.clear();
57     }
58 
SetStartTryBB(BBT * bb)59     void SetStartTryBB(BBT *bb)
60     {
61         startTryBB = bb;
62     }
63 
GetStartTryBB()64     BBT *GetStartTryBB()
65     {
66         return startTryBB;
67     }
68 
SetEndTryBB(BBT * bb)69     void SetEndTryBB(BBT *bb)
70     {
71         endTryBB = bb;
72     }
73 
GetEndTryBB()74     BBT *GetEndTryBB()
75     {
76         return endTryBB;
77     }
78 
GetTryStmtNode()79     StmtNode *GetTryStmtNode()
80     {
81         return tryStmt;
82     }
83 
GetEnclosedBBs()84     MapleVector<BBT *> &GetEnclosedBBs()
85     {
86         return enclosedBBs;
87     }
88 
GetEnclosedBBsSize()89     size_t GetEnclosedBBsSize() const
90     {
91         return enclosedBBs.size();
92     }
93 
GetEnclosedBBsElem(size_t index)94     const BBT *GetEnclosedBBsElem(size_t index) const
95     {
96         DEBUG_ASSERT(index < enclosedBBs.size(), "out of range");
97         return enclosedBBs[index];
98     }
99 
PushToEnclosedBBs(BBT & bb)100     void PushToEnclosedBBs(BBT &bb)
101     {
102         enclosedBBs.emplace_back(&bb);
103     }
104 
GetLabeledBBsInTry()105     MapleVector<BBT *> &GetLabeledBBsInTry()
106     {
107         return labeledBBsInTry;
108     }
109 
GetBBsToRelocate()110     MapleVector<BBT *> &GetBBsToRelocate()
111     {
112         return bbsToRelocate;
113     }
114 
115 private:
116     MapleAllocator allocator;
117     BBT *startTryBB = nullptr;
118     BBT *endTryBB = nullptr;
119     StmtNode *tryStmt = nullptr;
120     MapleVector<BBT *> enclosedBBs;
121     MapleVector<BBT *> labeledBBsInTry;
122     MapleVector<BBT *> bbsToRelocate;
123 };
124 
125 class TryCatchBlocksLower {
126 public:
TryCatchBlocksLower(MemPool & memPool,BlockNode & body,MIRModule & mirModule)127     TryCatchBlocksLower(MemPool &memPool, BlockNode &body, MIRModule &mirModule)
128         : memPool(memPool),
129           allocator(&memPool),
130           body(body),
131           mirModule(mirModule),
132           tryEndTryBlock(memPool),
133           bbList(allocator.Adapter()),
134           prevBBOfTry(allocator.Adapter()),
135           firstStmtToBBMap(allocator.Adapter()),
136           catchesSeenSoFar(allocator.Adapter())
137     {
138     }
139 
140     ~TryCatchBlocksLower() = default;
141     void CheckTryCatchPattern() const;
142 
SetGenerateEHCode(bool val)143     void SetGenerateEHCode(bool val)
144     {
145         generateEHCode = val;
146     }
147 
148 private:
149     MemPool &memPool;
150     MapleAllocator allocator;
151     BlockNode &body;
152     MIRModule &mirModule;
153     TryEndTryBlock tryEndTryBlock;
154     bool bodyEndWithEndTry = false;
155     bool generateEHCode = false;
156     MapleVector<BBT *> bbList;
157     MapleUnorderedMap<BBT *, BBT *> prevBBOfTry;
158     MapleUnorderedMap<StmtNode *, BBT *> firstStmtToBBMap;
159     MapleVector<BBT *> catchesSeenSoFar;
160 
161     void ProcessEnclosedBBBetweenTryEndTry();
162     void ConnectRemainBB();
163     BBT *FindInsertAfterBB();
164     void PlaceRelocatedBB(BBT &insertAfter);
165     BBT *CreateNewBB(StmtNode *first, StmtNode *last);
166     BBT *CollectCatchAndFallthruUntilNextCatchBB(BBT *&ebb, uint32 &nextEnclosedIdx, std::vector<BBT *> &currBBThread);
167     void WrapCatchWithTryEndTryBlock(std::vector<BBT *> &currBBThread, BBT *&nextBBThreadHead, uint32 &nextEnclosedIdx,
168                                      bool hasMoveEndTry);
169     void SwapEndTryBBAndCurrBBThread(const std::vector<BBT *> &currBBThread, bool &hasMoveEndTry,
170                                      const BBT *nextBBThreadHead);
171     void ProcessThreadTail(BBT &threadTail, BBT *const &nextBBThreadHead, bool hasMoveEndTry);
172     static StmtNode *MoveCondGotoIntoTry(BBT &jtBB, BBT &condbrBB, const MapleVector<BBT *> &labeledBBsInTry);
173     static BBT *FindTargetBBlock(LabelIdx idx, const std::vector<BBT *> &bbs);
174 };
175 } /* namespace maplebe */
176 
177 #endif /* MAPLEBE_INCLUDE_BE_TRY_CATCH_H */