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 */