Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:12

0001 //===-- Analysis/EHUtils.h - Exception handling related utils --*-//C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 
0008 #ifndef LLVM_ANALYSIS_EHUTILS_H
0009 #define LLVM_ANALYSIS_EHUTILS_H
0010 
0011 #include "llvm/ADT/DenseMap.h"
0012 #include "llvm/ADT/DenseSet.h"
0013 
0014 namespace llvm {
0015 
0016 /// Compute a list of blocks that are only reachable via EH paths.
0017 template <typename FunctionT, typename BlockT>
0018 static void computeEHOnlyBlocks(FunctionT &F, DenseSet<BlockT *> &EHBlocks) {
0019   // A block can be unknown if its not reachable from anywhere
0020   // EH if its only reachable from start blocks via some path through EH pads
0021   // NonEH if it's reachable from Non EH blocks as well.
0022   enum Status { Unknown = 0, EH = 1, NonEH = 2 };
0023   DenseSet<BlockT *> WorkList;
0024   DenseMap<BlockT *, Status> Statuses;
0025 
0026   auto GetStatus = [&](BlockT *BB) {
0027     auto It = Statuses.find(BB);
0028     return It != Statuses.end() ? It->second : Unknown;
0029   };
0030 
0031   auto CheckPredecessors = [&](BlockT *BB, Status Stat) {
0032     for (auto *PredBB : predecessors(BB)) {
0033       Status PredStatus = GetStatus(PredBB);
0034       // If status of predecessor block has gone above current block
0035       // we update current blocks status.
0036       if (PredStatus > Stat)
0037         Stat = PredStatus;
0038     }
0039     return Stat;
0040   };
0041 
0042   auto AddSuccesors = [&](BlockT *BB) {
0043     for (auto *SuccBB : successors(BB)) {
0044       if (!SuccBB->isEHPad())
0045         WorkList.insert(SuccBB);
0046     }
0047   };
0048 
0049   // Insert the successors of start block and landing pads successor.
0050   BlockT *StartBlock = &F.front();
0051   Statuses[StartBlock] = NonEH;
0052   AddSuccesors(StartBlock);
0053 
0054   for (auto &BB : F) {
0055     if (BB.isEHPad()) {
0056       AddSuccesors(&BB);
0057       Statuses[&BB] = EH;
0058     }
0059   }
0060 
0061   // Worklist iterative algorithm.
0062   while (!WorkList.empty()) {
0063     auto *BB = *WorkList.begin();
0064     WorkList.erase(BB);
0065 
0066     Status OldStatus = GetStatus(BB);
0067 
0068     // Check on predecessors and check for
0069     // Status update.
0070     Status NewStatus = CheckPredecessors(BB, OldStatus);
0071 
0072     // Did the block status change?
0073     bool Changed = OldStatus != NewStatus;
0074     if (Changed) {
0075       AddSuccesors(BB);
0076       Statuses[BB] = NewStatus;
0077     }
0078   }
0079 
0080   for (auto Entry : Statuses) {
0081     if (Entry.second == EH)
0082       EHBlocks.insert(Entry.first);
0083   }
0084 }
0085 } // namespace llvm
0086 
0087 #endif