- //===- MustExecute.h - Is an instruction known to execute--------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- /// \file 
- /// Contains a collection of routines for determining if a given instruction is 
- /// guaranteed to execute if a given point in control flow is reached. The most 
- /// common example is an instruction within a loop being provably executed if we 
- /// branch to the header of it's containing loop. 
- /// 
- /// There are two interfaces available to determine if an instruction is 
- /// executed once a given point in the control flow is reached: 
- /// 1) A loop-centric one derived from LoopSafetyInfo. 
- /// 2) A "must be executed context"-based one implemented in the 
- ///    MustBeExecutedContextExplorer. 
- /// Please refer to the class comments for more information. 
- /// 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_ANALYSIS_MUSTEXECUTE_H 
- #define LLVM_ANALYSIS_MUSTEXECUTE_H 
-   
- #include "llvm/ADT/DenseMap.h" 
- #include "llvm/ADT/DenseSet.h" 
- #include "llvm/Analysis/EHPersonalities.h" 
- #include "llvm/Analysis/InstructionPrecedenceTracking.h" 
- #include "llvm/IR/PassManager.h" 
-   
- namespace llvm { 
-   
- namespace { 
- template <typename T> using GetterTy = std::function<T *(const Function &F)>; 
- } 
-   
- class BasicBlock; 
- class DominatorTree; 
- class Instruction; 
- class Loop; 
- class LoopInfo; 
- class PostDominatorTree; 
- class raw_ostream; 
-   
- /// Captures loop safety information. 
- /// It keep information for loop blocks may throw exception or otherwise 
- /// exit abnormally on any iteration of the loop which might actually execute 
- /// at runtime.  The primary way to consume this information is via 
- /// isGuaranteedToExecute below, but some callers bailout or fallback to 
- /// alternate reasoning if a loop contains any implicit control flow. 
- /// NOTE: LoopSafetyInfo contains cached information regarding loops and their 
- /// particular blocks. This information is only dropped on invocation of 
- /// computeLoopSafetyInfo. If the loop or any of its block is deleted, or if 
- /// any thrower instructions have been added or removed from them, or if the 
- /// control flow has changed, or in case of other meaningful modifications, the 
- /// LoopSafetyInfo needs to be recomputed. If a meaningful modifications to the 
- /// loop were made and the info wasn't recomputed properly, the behavior of all 
- /// methods except for computeLoopSafetyInfo is undefined. 
- class LoopSafetyInfo { 
-   // Used to update funclet bundle operands. 
-   DenseMap<BasicBlock *, ColorVector> BlockColors; 
-   
- protected: 
-   /// Computes block colors. 
-   void computeBlockColors(const Loop *CurLoop); 
-   
- public: 
-   /// Returns block colors map that is used to update funclet operand bundles. 
-   const DenseMap<BasicBlock *, ColorVector> &getBlockColors() const; 
-   
-   /// Copy colors of block \p Old into the block \p New. 
-   void copyColors(BasicBlock *New, BasicBlock *Old); 
-   
-   /// Returns true iff the block \p BB potentially may throw exception. It can 
-   /// be false-positive in cases when we want to avoid complex analysis. 
-   virtual bool blockMayThrow(const BasicBlock *BB) const = 0; 
-   
-   /// Returns true iff any block of the loop for which this info is contains an 
-   /// instruction that may throw or otherwise exit abnormally. 
-   virtual bool anyBlockMayThrow() const = 0; 
-   
-   /// Return true if we must reach the block \p BB under assumption that the 
-   /// loop \p CurLoop is entered. 
-   bool allLoopPathsLeadToBlock(const Loop *CurLoop, const BasicBlock *BB, 
-                                const DominatorTree *DT) const; 
-   
-   /// Computes safety information for a loop checks loop body & header for 
-   /// the possibility of may throw exception, it takes LoopSafetyInfo and loop 
-   /// as argument. Updates safety information in LoopSafetyInfo argument. 
-   /// Note: This is defined to clear and reinitialize an already initialized 
-   /// LoopSafetyInfo.  Some callers rely on this fact. 
-   virtual void computeLoopSafetyInfo(const Loop *CurLoop) = 0; 
-   
-   /// Returns true if the instruction in a loop is guaranteed to execute at 
-   /// least once (under the assumption that the loop is entered). 
-   virtual bool isGuaranteedToExecute(const Instruction &Inst, 
-                                      const DominatorTree *DT, 
-                                      const Loop *CurLoop) const = 0; 
-   
-   LoopSafetyInfo() = default; 
-   
-   virtual ~LoopSafetyInfo() = default; 
- }; 
-   
-   
- /// Simple and conservative implementation of LoopSafetyInfo that can give 
- /// false-positive answers to its queries in order to avoid complicated 
- /// analysis. 
- class SimpleLoopSafetyInfo: public LoopSafetyInfo { 
-   bool MayThrow = false;       // The current loop contains an instruction which 
-                                // may throw. 
-   bool HeaderMayThrow = false; // Same as previous, but specific to loop header 
-   
- public: 
-   bool blockMayThrow(const BasicBlock *BB) const override; 
-   
-   bool anyBlockMayThrow() const override; 
-   
-   void computeLoopSafetyInfo(const Loop *CurLoop) override; 
-   
-   bool isGuaranteedToExecute(const Instruction &Inst, 
-                              const DominatorTree *DT, 
-                              const Loop *CurLoop) const override; 
- }; 
-   
- /// This implementation of LoopSafetyInfo use ImplicitControlFlowTracking to 
- /// give precise answers on "may throw" queries. This implementation uses cache 
- /// that should be invalidated by calling the methods insertInstructionTo and 
- /// removeInstruction whenever we modify a basic block's contents by adding or 
- /// removing instructions. 
- class ICFLoopSafetyInfo: public LoopSafetyInfo { 
-   bool MayThrow = false;       // The current loop contains an instruction which 
-                                // may throw. 
-   // Contains information about implicit control flow in this loop's blocks. 
-   mutable ImplicitControlFlowTracking ICF; 
-   // Contains information about instruction that may possibly write memory. 
-   mutable MemoryWriteTracking MW; 
-   
- public: 
-   bool blockMayThrow(const BasicBlock *BB) const override; 
-   
-   bool anyBlockMayThrow() const override; 
-   
-   void computeLoopSafetyInfo(const Loop *CurLoop) override; 
-   
-   bool isGuaranteedToExecute(const Instruction &Inst, 
-                              const DominatorTree *DT, 
-                              const Loop *CurLoop) const override; 
-   
-   /// Returns true if we could not execute a memory-modifying instruction before 
-   /// we enter \p BB under assumption that \p CurLoop is entered. 
-   bool doesNotWriteMemoryBefore(const BasicBlock *BB, const Loop *CurLoop) 
-       const; 
-   
-   /// Returns true if we could not execute a memory-modifying instruction before 
-   /// we execute \p I under assumption that \p CurLoop is entered. 
-   bool doesNotWriteMemoryBefore(const Instruction &I, const Loop *CurLoop) 
-       const; 
-   
-   /// Inform the safety info that we are planning to insert a new instruction 
-   /// \p Inst into the basic block \p BB. It will make all cache updates to keep 
-   /// it correct after this insertion. 
-   void insertInstructionTo(const Instruction *Inst, const BasicBlock *BB); 
-   
-   /// Inform safety info that we are planning to remove the instruction \p Inst 
-   /// from its block. It will make all cache updates to keep it correct after 
-   /// this removal. 
-   void removeInstruction(const Instruction *Inst); 
- }; 
-   
- bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI); 
-   
- struct MustBeExecutedContextExplorer; 
-   
- /// Enum that allows us to spell out the direction. 
- enum class ExplorationDirection { 
-   BACKWARD = 0, 
-   FORWARD = 1, 
- }; 
-   
- /// Must be executed iterators visit stretches of instructions that are 
- /// guaranteed to be executed together, potentially with other instruction 
- /// executed in-between. 
- /// 
- /// Given the following code, and assuming all statements are single 
- /// instructions which transfer execution to the successor (see 
- /// isGuaranteedToTransferExecutionToSuccessor), there are two possible 
- /// outcomes. If we start the iterator at A, B, or E, we will visit only A, B, 
- /// and E. If we start at C or D, we will visit all instructions A-E. 
- /// 
- /// \code 
- ///   A; 
- ///   B; 
- ///   if (...) { 
- ///     C; 
- ///     D; 
- ///   } 
- ///   E; 
- /// \endcode 
- /// 
- /// 
- /// Below is the example extneded with instructions F and G. Now we assume F 
- /// might not transfer execution to it's successor G. As a result we get the 
- /// following visit sets: 
- /// 
- /// Start Instruction   | Visit Set 
- /// A                   | A, B,       E, F 
- ///    B                | A, B,       E, F 
- ///       C             | A, B, C, D, E, F 
- ///          D          | A, B, C, D, E, F 
- ///             E       | A, B,       E, F 
- ///                F    | A, B,       E, F 
- ///                   G | A, B,       E, F, G 
- /// 
- /// 
- /// \code 
- ///   A; 
- ///   B; 
- ///   if (...) { 
- ///     C; 
- ///     D; 
- ///   } 
- ///   E; 
- ///   F;  // Might not transfer execution to its successor G. 
- ///   G; 
- /// \endcode 
- /// 
- /// 
- /// A more complex example involving conditionals, loops, break, and continue 
- /// is shown below. We again assume all instructions will transmit control to 
- /// the successor and we assume we can prove the inner loop to be finite. We 
- /// omit non-trivial branch conditions as the exploration is oblivious to them. 
- /// Constant branches are assumed to be unconditional in the CFG. The resulting 
- /// visist sets are shown in the table below. 
- /// 
- /// \code 
- ///   A; 
- ///   while (true) { 
- ///     B; 
- ///     if (...) 
- ///       C; 
- ///     if (...) 
- ///       continue; 
- ///     D; 
- ///     if (...) 
- ///       break; 
- ///     do { 
- ///       if (...) 
- ///         continue; 
- ///       E; 
- ///     } while (...); 
- ///     F; 
- ///   } 
- ///   G; 
- /// \endcode 
- /// 
- /// Start Instruction    | Visit Set 
- /// A                    | A, B 
- ///    B                 | A, B 
- ///       C              | A, B, C 
- ///          D           | A, B,    D 
- ///             E        | A, B,    D, E, F 
- ///                F     | A, B,    D,    F 
- ///                   G  | A, B,    D,       G 
- /// 
- /// 
- /// Note that the examples show optimal visist sets but not necessarily the ones 
- /// derived by the explorer depending on the available CFG analyses (see 
- /// MustBeExecutedContextExplorer). Also note that we, depending on the options, 
- /// the visit set can contain instructions from other functions. 
- struct MustBeExecutedIterator { 
-   /// Type declarations that make his class an input iterator. 
-   ///{ 
-   typedef const Instruction *value_type; 
-   typedef std::ptrdiff_t difference_type; 
-   typedef const Instruction **pointer; 
-   typedef const Instruction *&reference; 
-   typedef std::input_iterator_tag iterator_category; 
-   ///} 
-   
-   using ExplorerTy = MustBeExecutedContextExplorer; 
-   
-   MustBeExecutedIterator(const MustBeExecutedIterator &Other) = default; 
-   
-   MustBeExecutedIterator(MustBeExecutedIterator &&Other) 
-       : Visited(std::move(Other.Visited)), Explorer(Other.Explorer), 
-         CurInst(Other.CurInst), Head(Other.Head), Tail(Other.Tail) {} 
-   
-   MustBeExecutedIterator &operator=(MustBeExecutedIterator &&Other) { 
-     if (this != &Other) { 
-       std::swap(Visited, Other.Visited); 
-       std::swap(CurInst, Other.CurInst); 
-       std::swap(Head, Other.Head); 
-       std::swap(Tail, Other.Tail); 
-     } 
-     return *this; 
-   } 
-   
-   ~MustBeExecutedIterator() = default; 
-   
-   /// Pre- and post-increment operators. 
-   ///{ 
-   MustBeExecutedIterator &operator++() { 
-     CurInst = advance(); 
-     return *this; 
-   } 
-   
-   MustBeExecutedIterator operator++(int) { 
-     MustBeExecutedIterator tmp(*this); 
-     operator++(); 
-     return tmp; 
-   } 
-   ///} 
-   
-   /// Equality and inequality operators. Note that we ignore the history here. 
-   ///{ 
-   bool operator==(const MustBeExecutedIterator &Other) const { 
-     return CurInst == Other.CurInst && Head == Other.Head && Tail == Other.Tail; 
-   } 
-   
-   bool operator!=(const MustBeExecutedIterator &Other) const { 
-     return !(*this == Other); 
-   } 
-   ///} 
-   
-   /// Return the underlying instruction. 
-   const Instruction *&operator*() { return CurInst; } 
-   const Instruction *getCurrentInst() const { return CurInst; } 
-   
-   /// Return true if \p I was encountered by this iterator already. 
-   bool count(const Instruction *I) const { 
-     return Visited.count({I, ExplorationDirection::FORWARD}) || 
-            Visited.count({I, ExplorationDirection::BACKWARD}); 
-   } 
-   
- private: 
-   using VisitedSetTy = 
-       DenseSet<PointerIntPair<const Instruction *, 1, ExplorationDirection>>; 
-   
-   /// Private constructors. 
-   MustBeExecutedIterator(ExplorerTy &Explorer, const Instruction *I); 
-   
-   /// Reset the iterator to its initial state pointing at \p I. 
-   void reset(const Instruction *I); 
-   
-   /// Reset the iterator to point at \p I, keep cached state. 
-   void resetInstruction(const Instruction *I); 
-   
-   /// Try to advance one of the underlying positions (Head or Tail). 
-   /// 
-   /// \return The next instruction in the must be executed context, or nullptr 
-   ///         if none was found. 
-   const Instruction *advance(); 
-   
-   /// A set to track the visited instructions in order to deal with endless 
-   /// loops and recursion. 
-   VisitedSetTy Visited; 
-   
-   /// A reference to the explorer that created this iterator. 
-   ExplorerTy &Explorer; 
-   
-   /// The instruction we are currently exposing to the user. There is always an 
-   /// instruction that we know is executed with the given program point, 
-   /// initially the program point itself. 
-   const Instruction *CurInst; 
-   
-   /// Two positions that mark the program points where this iterator will look 
-   /// for the next instruction. Note that the current instruction is either the 
-   /// one pointed to by Head, Tail, or both. 
-   const Instruction *Head, *Tail; 
-   
-   friend struct MustBeExecutedContextExplorer; 
- }; 
-   
- /// A "must be executed context" for a given program point PP is the set of 
- /// instructions, potentially before and after PP, that are executed always when 
- /// PP is reached. The MustBeExecutedContextExplorer an interface to explore 
- /// "must be executed contexts" in a module through the use of 
- /// MustBeExecutedIterator. 
- /// 
- /// The explorer exposes "must be executed iterators" that traverse the must be 
- /// executed context. There is little information sharing between iterators as 
- /// the expected use case involves few iterators for "far apart" instructions. 
- /// If that changes, we should consider caching more intermediate results. 
- struct MustBeExecutedContextExplorer { 
-   
-   /// In the description of the parameters we use PP to denote a program point 
-   /// for which the must be executed context is explored, or put differently, 
-   /// for which the MustBeExecutedIterator is created. 
-   /// 
-   /// \param ExploreInterBlock    Flag to indicate if instructions in blocks 
-   ///                             other than the parent of PP should be 
-   ///                             explored. 
-   /// \param ExploreCFGForward    Flag to indicate if instructions located after 
-   ///                             PP in the CFG, e.g., post-dominating PP, 
-   ///                             should be explored. 
-   /// \param ExploreCFGBackward   Flag to indicate if instructions located 
-   ///                             before PP in the CFG, e.g., dominating PP, 
-   ///                             should be explored. 
-   MustBeExecutedContextExplorer( 
-       bool ExploreInterBlock, bool ExploreCFGForward, bool ExploreCFGBackward, 
-       GetterTy<const LoopInfo> LIGetter = 
-           [](const Function &) { return nullptr; }, 
-       GetterTy<const DominatorTree> DTGetter = 
-           [](const Function &) { return nullptr; }, 
-       GetterTy<const PostDominatorTree> PDTGetter = 
-           [](const Function &) { return nullptr; }) 
-       : ExploreInterBlock(ExploreInterBlock), 
-         ExploreCFGForward(ExploreCFGForward), 
-         ExploreCFGBackward(ExploreCFGBackward), LIGetter(LIGetter), 
-         DTGetter(DTGetter), PDTGetter(PDTGetter), EndIterator(*this, nullptr) {} 
-   
-   /// Iterator-based interface. \see MustBeExecutedIterator. 
-   ///{ 
-   using iterator = MustBeExecutedIterator; 
-   using const_iterator = const MustBeExecutedIterator; 
-   
-   /// Return an iterator to explore the context around \p PP. 
-   iterator &begin(const Instruction *PP) { 
-     auto &It = InstructionIteratorMap[PP]; 
-     if (!It) 
-       It.reset(new iterator(*this, PP)); 
-     return *It; 
-   } 
-   
-   /// Return an iterator to explore the cached context around \p PP. 
-   const_iterator &begin(const Instruction *PP) const { 
-     return *InstructionIteratorMap.find(PP)->second; 
-   } 
-   
-   /// Return an universal end iterator. 
-   ///{ 
-   iterator &end() { return EndIterator; } 
-   iterator &end(const Instruction *) { return EndIterator; } 
-   
-   const_iterator &end() const { return EndIterator; } 
-   const_iterator &end(const Instruction *) const { return EndIterator; } 
-   ///} 
-   
-   /// Return an iterator range to explore the context around \p PP. 
-   llvm::iterator_range<iterator> range(const Instruction *PP) { 
-     return llvm::make_range(begin(PP), end(PP)); 
-   } 
-   
-   /// Return an iterator range to explore the cached context around \p PP. 
-   llvm::iterator_range<const_iterator> range(const Instruction *PP) const { 
-     return llvm::make_range(begin(PP), end(PP)); 
-   } 
-   ///} 
-   
-   /// Check \p Pred on all instructions in the context. 
-   /// 
-   /// This method will evaluate \p Pred and return 
-   /// true if \p Pred holds in every instruction. 
-   bool checkForAllContext(const Instruction *PP, 
-                           function_ref<bool(const Instruction *)> Pred) { 
-     for (auto EIt = begin(PP), EEnd = end(PP); EIt != EEnd; ++EIt) 
-       if (!Pred(*EIt)) 
-         return false; 
-     return true; 
-   } 
-   
-   /// Helper to look for \p I in the context of \p PP. 
-   /// 
-   /// The context is expanded until \p I was found or no more expansion is 
-   /// possible. 
-   /// 
-   /// \returns True, iff \p I was found. 
-   bool findInContextOf(const Instruction *I, const Instruction *PP) { 
-     auto EIt = begin(PP), EEnd = end(PP); 
-     return findInContextOf(I, EIt, EEnd); 
-   } 
-   
-   /// Helper to look for \p I in the context defined by \p EIt and \p EEnd. 
-   /// 
-   /// The context is expanded until \p I was found or no more expansion is 
-   /// possible. 
-   /// 
-   /// \returns True, iff \p I was found. 
-   bool findInContextOf(const Instruction *I, iterator &EIt, iterator &EEnd) { 
-     bool Found = EIt.count(I); 
-     while (!Found && EIt != EEnd) 
-       Found = (++EIt).getCurrentInst() == I; 
-     return Found; 
-   } 
-   
-   /// Return the next instruction that is guaranteed to be executed after \p PP. 
-   /// 
-   /// \param It              The iterator that is used to traverse the must be 
-   ///                        executed context. 
-   /// \param PP              The program point for which the next instruction 
-   ///                        that is guaranteed to execute is determined. 
-   const Instruction * 
-   getMustBeExecutedNextInstruction(MustBeExecutedIterator &It, 
-                                    const Instruction *PP); 
-   /// Return the previous instr. that is guaranteed to be executed before \p PP. 
-   /// 
-   /// \param It              The iterator that is used to traverse the must be 
-   ///                        executed context. 
-   /// \param PP              The program point for which the previous instr. 
-   ///                        that is guaranteed to execute is determined. 
-   const Instruction * 
-   getMustBeExecutedPrevInstruction(MustBeExecutedIterator &It, 
-                                    const Instruction *PP); 
-   
-   /// Find the next join point from \p InitBB in forward direction. 
-   const BasicBlock *findForwardJoinPoint(const BasicBlock *InitBB); 
-   
-   /// Find the next join point from \p InitBB in backward direction. 
-   const BasicBlock *findBackwardJoinPoint(const BasicBlock *InitBB); 
-   
-   /// Parameter that limit the performed exploration. See the constructor for 
-   /// their meaning. 
-   ///{ 
-   const bool ExploreInterBlock; 
-   const bool ExploreCFGForward; 
-   const bool ExploreCFGBackward; 
-   ///} 
-   
- private: 
-   /// Getters for common CFG analyses: LoopInfo, DominatorTree, and 
-   /// PostDominatorTree. 
-   ///{ 
-   GetterTy<const LoopInfo> LIGetter; 
-   GetterTy<const DominatorTree> DTGetter; 
-   GetterTy<const PostDominatorTree> PDTGetter; 
-   ///} 
-   
-   /// Map to cache isGuaranteedToTransferExecutionToSuccessor results. 
-   DenseMap<const BasicBlock *, std::optional<bool>> BlockTransferMap; 
-   
-   /// Map to cache containsIrreducibleCFG results. 
-   DenseMap<const Function *, std::optional<bool>> IrreducibleControlMap; 
-   
-   /// Map from instructions to associated must be executed iterators. 
-   DenseMap<const Instruction *, std::unique_ptr<MustBeExecutedIterator>> 
-       InstructionIteratorMap; 
-   
-   /// A unique end iterator. 
-   MustBeExecutedIterator EndIterator; 
- }; 
-   
- class MustExecutePrinterPass : public PassInfoMixin<MustExecutePrinterPass> { 
-   raw_ostream &OS; 
-   
- public: 
-   MustExecutePrinterPass(raw_ostream &OS) : OS(OS) {} 
-   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 
- }; 
-   
- class MustBeExecutedContextPrinterPass 
-     : public PassInfoMixin<MustBeExecutedContextPrinterPass> { 
-   raw_ostream &OS; 
-   
- public: 
-   MustBeExecutedContextPrinterPass(raw_ostream &OS) : OS(OS) {} 
-   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 
- }; 
-   
- } // namespace llvm 
-   
- #endif 
-