[llvm] [Analysis] Use CycleInfo for BranchProbabilityInfo (PR #210301)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 21 07:59:53 PDT 2026


================
@@ -165,106 +165,32 @@ namespace {
 class BPIConstruction {
 public:
   BPIConstruction(BranchProbabilityInfo &BPI) : BPI(BPI) {}
-  void calculate(const Function &F, const LoopInfo &LI,
+  void calculate(const Function &F, const CycleInfo &CI,
                  const TargetLibraryInfo *TLI, DominatorTree *DT,
                  PostDominatorTree *PDT);
 
 private:
-  // Data structure to track SCCs for handling irreducible loops.
-  class SccInfo {
-    // Enum of types to classify basic blocks in SCC. Basic block belonging to
-    // SCC is 'Inner' until it is either 'Header' or 'Exiting'. Note that a
-    // basic block can be 'Header' and 'Exiting' at the same time.
-    enum SccBlockType {
-      Inner = 0x0,
-      Header = 0x1,
-      Exiting = 0x2,
-    };
-    // Map of basic blocks to SCC IDs they belong to. If basic block doesn't
-    // belong to any SCC it is not in the map.
-    using SccMap = DenseMap<const BasicBlock *, int>;
-    // Each basic block in SCC is attributed with one or several types from
-    // SccBlockType. Map value has uint32_t type (instead of SccBlockType)
-    // since basic block may be for example "Header" and "Exiting" at the same
-    // time and we need to be able to keep more than one value from
-    // SccBlockType.
-    using SccBlockTypeMap = DenseMap<const BasicBlock *, uint32_t>;
-    // Vector containing classification of basic blocks for all  SCCs where i'th
-    // vector element corresponds to SCC with ID equal to i.
-    using SccBlockTypeMaps = std::vector<SccBlockTypeMap>;
-
-    SccMap SccNums;
-    SccBlockTypeMaps SccBlocks;
-
-  public:
-    explicit SccInfo(const Function &F);
-
-    /// If \p BB belongs to some SCC then ID of that SCC is returned, otherwise
-    /// -1 is returned. If \p BB belongs to more than one SCC at the same time
-    /// result is undefined.
-    int getSCCNum(const BasicBlock *BB) const;
-    /// Returns true if \p BB is a 'header' block in SCC with \p SccNum ID,
-    /// false otherwise.
-    bool isSCCHeader(const BasicBlock *BB, int SccNum) const {
-      return getSccBlockType(BB, SccNum) & Header;
-    }
-    /// Returns true if \p BB is an 'exiting' block in SCC with \p SccNum ID,
-    /// false otherwise.
-    bool isSCCExitingBlock(const BasicBlock *BB, int SccNum) const {
-      return getSccBlockType(BB, SccNum) & Exiting;
-    }
-    /// Fills in \p Enters vector with all such blocks that don't belong to
-    /// SCC with \p SccNum ID but there is an edge to a block belonging to the
-    /// SCC.
-    void getSccEnterBlocks(int SccNum,
-                           SmallVectorImpl<BasicBlock *> &Enters) const;
-    /// Fills in \p Exits vector with all such blocks that don't belong to
-    /// SCC with \p SccNum ID but there is an edge from a block belonging to the
-    /// SCC.
-    void getSccExitBlocks(int SccNum,
-                          SmallVectorImpl<BasicBlock *> &Exits) const;
-
-  private:
-    /// Returns \p BB's type according to classification given by SccBlockType
-    /// enum. Please note that \p BB must belong to SSC with \p SccNum ID.
-    uint32_t getSccBlockType(const BasicBlock *BB, int SccNum) const;
-    /// Calculates \p BB's type and stores it in internal data structures for
-    /// future use. Please note that \p BB must belong to SSC with \p SccNum ID.
-    void calculateSccBlockType(const BasicBlock *BB, int SccNum);
-  };
-
-  /// Pair of Loop and SCC ID number. Used to unify handling of normal and
-  /// SCC based loop representations.
-  using LoopData = std::pair<Loop *, int>;
   /// Helper class to keep basic block along with its loop data information.
   class LoopBlock {
   public:
-    explicit LoopBlock(const BasicBlock *BB, const LoopInfo &LI,
-                       const SccInfo &SccI);
+    explicit LoopBlock(const BasicBlock *BB, const CycleInfo &CI)
+        : BB(BB), C(CI.getCycle(BB)) {}
 
     const BasicBlock *getBlock() const { return BB; }
     BasicBlock *getBlock() { return const_cast<BasicBlock *>(BB); }
-    LoopData getLoopData() const { return LD; }
-    Loop *getLoop() const { return LD.first; }
-    int getSccNum() const { return LD.second; }
-
-    bool belongsToLoop() const { return getLoop() || getSccNum() != -1; }
-    bool belongsToSameLoop(const LoopBlock &LB) const {
-      return (LB.getLoop() && getLoop() == LB.getLoop()) ||
-             (LB.getSccNum() != -1 && getSccNum() == LB.getSccNum());
-    }
+    CycleRef getCycle() const { return C; }
 
   private:
     const BasicBlock *const BB = nullptr;
-    LoopData LD = {nullptr, -1};
+    CycleRef C = CycleRef();
----------------
aengelke wrote:

Changed. I have a follow-up patch that removes LoopBlock entirely.

https://github.com/llvm/llvm-project/pull/210301


More information about the llvm-commits mailing list