| //===--- TransitivelyUnreachableBlocks.h ------------------------*- C++ -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SWIFT_SIL_TRANSITIVELYUNREACHABLEBLOCKS_H |
| #define SWIFT_SIL_TRANSITIVELYUNREACHABLEBLOCKS_H |
| |
| #include "swift/SIL/PostOrder.h" |
| #include "swift/SIL/SILBasicBlock.h" |
| #include "llvm/ADT/SmallPtrSet.h" |
| |
| namespace swift { |
| |
| /// This is a simple unreachable dataflow analysis that determines all blocks |
| /// that are post-dominated by no-return functions, no-return builtins and |
| /// unreachables. It is needed to determine if the a value definition can have a |
| /// lack of users ignored along a specific path. |
| class TransitivelyUnreachableBlocksInfo { |
| llvm::SmallPtrSet<const SILBasicBlock *, 32> UnreachableBlocks; |
| |
| public: |
| TransitivelyUnreachableBlocksInfo(const PostOrderFunctionInfo &POFI) { |
| for (SILBasicBlock *Block : POFI.getPostOrder()) { |
| if (isa<UnreachableInst>(Block->getTerminator())) { |
| UnreachableBlocks.insert(Block); |
| continue; |
| } |
| |
| if (Block->succ_empty()) { |
| continue; |
| } |
| |
| if (any_of(Block->getSuccessorBlocks(), |
| [this](SILBasicBlock *SuccBlock) -> bool { |
| return !UnreachableBlocks.count(SuccBlock); |
| })) { |
| continue; |
| } |
| |
| UnreachableBlocks.insert(Block); |
| } |
| } |
| |
| bool isUnreachable(const SILBasicBlock *BB) const { |
| return UnreachableBlocks.count(BB); |
| } |
| }; |
| |
| } // namespace swift |
| |
| #endif |