//===- 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/InstructionPrecedenceTracking.h" #include "llvm/IR/EHPersonalities.h" #include "llvm/IR/PassManager.h" namespace llvm { namespace { GetterTy; } class BasicBlock; class DominatorTree; 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 { … }; /// 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 { … }; /// 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 mayContainIrreducibleControl(const Function &F, const LoopInfo *LI); struct MustBeExecutedContextExplorer; /// Enum that allows us to spell out the direction. enum class ExplorationDirection { … }; /// 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 { … }; /// 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 { … }; class MustExecutePrinterPass : public PassInfoMixin<MustExecutePrinterPass> { … }; class MustBeExecutedContextPrinterPass : public PassInfoMixin<MustBeExecutedContextPrinterPass> { … }; } // namespace llvm #endif