LLVM 20.0.0git
EHUtils.h
Go to the documentation of this file.
1//===-- Analysis/EHUtils.h - Exception handling related utils --*-//C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7
8#ifndef LLVM_ANALYSIS_EHUTILS_H
9#define LLVM_ANALYSIS_EHUTILS_H
10
11#include "llvm/ADT/DenseMap.h"
12#include "llvm/ADT/DenseSet.h"
13
14namespace llvm {
15
16/// Compute a list of blocks that are only reachable via EH paths.
17template <typename FunctionT, typename BlockT>
18static void computeEHOnlyBlocks(FunctionT &F, DenseSet<BlockT *> &EHBlocks) {
19 // A block can be unknown if its not reachable from anywhere
20 // EH if its only reachable from start blocks via some path through EH pads
21 // NonEH if it's reachable from Non EH blocks as well.
22 enum Status { Unknown = 0, EH = 1, NonEH = 2 };
23 DenseSet<BlockT *> WorkList;
25
26 auto GetStatus = [&](BlockT *BB) {
27 auto It = Statuses.find(BB);
28 return It != Statuses.end() ? It->second : Unknown;
29 };
30
31 auto CheckPredecessors = [&](BlockT *BB, Status Stat) {
32 for (auto *PredBB : predecessors(BB)) {
33 Status PredStatus = GetStatus(PredBB);
34 // If status of predecessor block has gone above current block
35 // we update current blocks status.
36 if (PredStatus > Stat)
37 Stat = PredStatus;
38 }
39 return Stat;
40 };
41
42 auto AddSuccesors = [&](BlockT *BB) {
43 for (auto *SuccBB : successors(BB)) {
44 if (!SuccBB->isEHPad())
45 WorkList.insert(SuccBB);
46 }
47 };
48
49 // Insert the successors of start block and landing pads successor.
50 BlockT *StartBlock = &F.front();
51 Statuses[StartBlock] = NonEH;
52 AddSuccesors(StartBlock);
53
54 for (auto &BB : F) {
55 if (BB.isEHPad()) {
56 AddSuccesors(&BB);
57 Statuses[&BB] = EH;
58 }
59 }
60
61 // Worklist iterative algorithm.
62 while (!WorkList.empty()) {
63 auto *BB = *WorkList.begin();
64 WorkList.erase(BB);
65
66 Status OldStatus = GetStatus(BB);
67
68 // Check on predecessors and check for
69 // Status update.
70 Status NewStatus = CheckPredecessors(BB, OldStatus);
71
72 // Did the block status change?
73 bool Changed = OldStatus != NewStatus;
74 if (Changed) {
75 AddSuccesors(BB);
76 Statuses[BB] = NewStatus;
77 }
78 }
79
80 for (auto Entry : Statuses) {
81 if (Entry.second == EH)
82 EHBlocks.insert(Entry.first);
83 }
84}
85} // namespace llvm
86
87#endif
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
#define F(x, y, z)
Definition: MD5.cpp:55
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:156
iterator end()
Definition: DenseMap.h:84
Implements a dense probed hash-table based set.
Definition: DenseSet.h:278
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:213
bool erase(const ValueT &V)
Definition: DenseSet.h:97
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto successors(const MachineBasicBlock *BB)
static void computeEHOnlyBlocks(FunctionT &F, DenseSet< BlockT * > &EHBlocks)
Compute a list of blocks that are only reachable via EH paths.
Definition: EHUtils.h:18
auto predecessors(const MachineBasicBlock *BB)