Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:43

0001 //===- LoopConstrainer.h ----------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_TRANSFORMS_UTILS_LOOP_CONSTRAINER_H
0010 #define LLVM_TRANSFORMS_UTILS_LOOP_CONSTRAINER_H
0011 
0012 #include "llvm/Support/Casting.h"
0013 #include "llvm/Transforms/Utils/ValueMapper.h"
0014 #include <optional>
0015 
0016 namespace llvm {
0017 
0018 class BasicBlock;
0019 class BranchInst;
0020 class DominatorTree;
0021 class IntegerType;
0022 class Loop;
0023 class LoopInfo;
0024 class PHINode;
0025 class ScalarEvolution;
0026 class SCEV;
0027 class Value;
0028 
0029 // Keeps track of the structure of a loop.  This is similar to llvm::Loop,
0030 // except that it is more lightweight and can track the state of a loop through
0031 // changing and potentially invalid IR.  This structure also formalizes the
0032 // kinds of loops we can deal with -- ones that have a single latch that is also
0033 // an exiting block *and* have a canonical induction variable.
0034 struct LoopStructure {
0035   const char *Tag = "";
0036 
0037   BasicBlock *Header = nullptr;
0038   BasicBlock *Latch = nullptr;
0039 
0040   // `Latch's terminator instruction is `LatchBr', and it's `LatchBrExitIdx'th
0041   // successor is `LatchExit', the exit block of the loop.
0042   BranchInst *LatchBr = nullptr;
0043   BasicBlock *LatchExit = nullptr;
0044   unsigned LatchBrExitIdx = std::numeric_limits<unsigned>::max();
0045 
0046   // The loop represented by this instance of LoopStructure is semantically
0047   // equivalent to:
0048   //
0049   // intN_ty inc = IndVarIncreasing ? 1 : -1;
0050   // pred_ty predicate = IndVarIncreasing ? ICMP_SLT : ICMP_SGT;
0051   //
0052   // for (intN_ty iv = IndVarStart; predicate(iv, LoopExitAt); iv = IndVarBase)
0053   //   ... body ...
0054 
0055   Value *IndVarBase = nullptr;
0056   Value *IndVarStart = nullptr;
0057   Value *IndVarStep = nullptr;
0058   Value *LoopExitAt = nullptr;
0059   bool IndVarIncreasing = false;
0060   bool IsSignedPredicate = true;
0061   IntegerType *ExitCountTy = nullptr;
0062 
0063   LoopStructure() = default;
0064 
0065   template <typename M> LoopStructure map(M Map) const {
0066     LoopStructure Result;
0067     Result.Tag = Tag;
0068     Result.Header = cast<BasicBlock>(Map(Header));
0069     Result.Latch = cast<BasicBlock>(Map(Latch));
0070     Result.LatchBr = cast<BranchInst>(Map(LatchBr));
0071     Result.LatchExit = cast<BasicBlock>(Map(LatchExit));
0072     Result.LatchBrExitIdx = LatchBrExitIdx;
0073     Result.IndVarBase = Map(IndVarBase);
0074     Result.IndVarStart = Map(IndVarStart);
0075     Result.IndVarStep = Map(IndVarStep);
0076     Result.LoopExitAt = Map(LoopExitAt);
0077     Result.IndVarIncreasing = IndVarIncreasing;
0078     Result.IsSignedPredicate = IsSignedPredicate;
0079     Result.ExitCountTy = ExitCountTy;
0080     return Result;
0081   }
0082 
0083   static std::optional<LoopStructure>
0084   parseLoopStructure(ScalarEvolution &, Loop &, bool, const char *&);
0085 };
0086 
0087 /// This class is used to constrain loops to run within a given iteration space.
0088 /// The algorithm this class implements is given a Loop and a range [Begin,
0089 /// End).  The algorithm then tries to break out a "main loop" out of the loop
0090 /// it is given in a way that the "main loop" runs with the induction variable
0091 /// in a subset of [Begin, End).  The algorithm emits appropriate pre and post
0092 /// loops to run any remaining iterations.  The pre loop runs any iterations in
0093 /// which the induction variable is < Begin, and the post loop runs any
0094 /// iterations in which the induction variable is >= End.
0095 class LoopConstrainer {
0096 public:
0097   // Calculated subranges we restrict the iteration space of the main loop to.
0098   // See the implementation of `calculateSubRanges' for more details on how
0099   // these fields are computed.  `LowLimit` is std::nullopt if there is no
0100   // restriction on low end of the restricted iteration space of the main loop.
0101   // `HighLimit` is std::nullopt if there is no restriction on high end of the
0102   // restricted iteration space of the main loop.
0103 
0104   struct SubRanges {
0105     std::optional<const SCEV *> LowLimit;
0106     std::optional<const SCEV *> HighLimit;
0107   };
0108 
0109 private:
0110   // The representation of a clone of the original loop we started out with.
0111   struct ClonedLoop {
0112     // The cloned blocks
0113     std::vector<BasicBlock *> Blocks;
0114 
0115     // `Map` maps values in the clonee into values in the cloned version
0116     ValueToValueMapTy Map;
0117 
0118     // An instance of `LoopStructure` for the cloned loop
0119     LoopStructure Structure;
0120   };
0121 
0122   // Result of rewriting the range of a loop.  See changeIterationSpaceEnd for
0123   // more details on what these fields mean.
0124   struct RewrittenRangeInfo {
0125     BasicBlock *PseudoExit = nullptr;
0126     BasicBlock *ExitSelector = nullptr;
0127     std::vector<PHINode *> PHIValuesAtPseudoExit;
0128     PHINode *IndVarEnd = nullptr;
0129 
0130     RewrittenRangeInfo() = default;
0131   };
0132 
0133   // Clone `OriginalLoop' and return the result in CLResult.  The IR after
0134   // running `cloneLoop' is well formed except for the PHI nodes in CLResult --
0135   // the PHI nodes say that there is an incoming edge from `OriginalPreheader`
0136   // but there is no such edge.
0137   void cloneLoop(ClonedLoop &CLResult, const char *Tag) const;
0138 
0139   // Create the appropriate loop structure needed to describe a cloned copy of
0140   // `Original`.  The clone is described by `VM`.
0141   Loop *createClonedLoopStructure(Loop *Original, Loop *Parent,
0142                                   ValueToValueMapTy &VM, bool IsSubloop);
0143 
0144   // Rewrite the iteration space of the loop denoted by (LS, Preheader). The
0145   // iteration space of the rewritten loop ends at ExitLoopAt.  The start of the
0146   // iteration space is not changed.  `ExitLoopAt' is assumed to be slt
0147   // `OriginalHeaderCount'.
0148   //
0149   // If there are iterations left to execute, control is made to jump to
0150   // `ContinuationBlock', otherwise they take the normal loop exit.  The
0151   // returned `RewrittenRangeInfo' object is populated as follows:
0152   //
0153   //  .PseudoExit is a basic block that unconditionally branches to
0154   //      `ContinuationBlock'.
0155   //
0156   //  .ExitSelector is a basic block that decides, on exit from the loop,
0157   //      whether to branch to the "true" exit or to `PseudoExit'.
0158   //
0159   //  .PHIValuesAtPseudoExit are PHINodes in `PseudoExit' that compute the value
0160   //      for each PHINode in the loop header on taking the pseudo exit.
0161   //
0162   // After changeIterationSpaceEnd, `Preheader' is no longer a legitimate
0163   // preheader because it is made to branch to the loop header only
0164   // conditionally.
0165   RewrittenRangeInfo
0166   changeIterationSpaceEnd(const LoopStructure &LS, BasicBlock *Preheader,
0167                           Value *ExitLoopAt,
0168                           BasicBlock *ContinuationBlock) const;
0169 
0170   // The loop denoted by `LS' has `OldPreheader' as its preheader.  This
0171   // function creates a new preheader for `LS' and returns it.
0172   BasicBlock *createPreheader(const LoopStructure &LS, BasicBlock *OldPreheader,
0173                               const char *Tag) const;
0174 
0175   // `ContinuationBlockAndPreheader' was the continuation block for some call to
0176   // `changeIterationSpaceEnd' and is the preheader to the loop denoted by `LS'.
0177   // This function rewrites the PHI nodes in `LS.Header' to start with the
0178   // correct value.
0179   void rewriteIncomingValuesForPHIs(
0180       LoopStructure &LS, BasicBlock *ContinuationBlockAndPreheader,
0181       const LoopConstrainer::RewrittenRangeInfo &RRI) const;
0182 
0183   // Even though we do not preserve any passes at this time, we at least need to
0184   // keep the parent loop structure consistent.  The `LPPassManager' seems to
0185   // verify this after running a loop pass.  This function adds the list of
0186   // blocks denoted by BBs to this loops parent loop if required.
0187   void addToParentLoopIfNeeded(ArrayRef<BasicBlock *> BBs);
0188 
0189   // Some global state.
0190   Function &F;
0191   LLVMContext &Ctx;
0192   ScalarEvolution &SE;
0193   DominatorTree &DT;
0194   LoopInfo &LI;
0195   function_ref<void(Loop *, bool)> LPMAddNewLoop;
0196 
0197   // Information about the original loop we started out with.
0198   Loop &OriginalLoop;
0199 
0200   BasicBlock *OriginalPreheader = nullptr;
0201 
0202   // The preheader of the main loop.  This may or may not be different from
0203   // `OriginalPreheader'.
0204   BasicBlock *MainLoopPreheader = nullptr;
0205 
0206   // Type of the range we need to run the main loop in.
0207   Type *RangeTy;
0208 
0209   // The structure of the main loop (see comment at the beginning of this class
0210   // for a definition)
0211   LoopStructure MainLoopStructure;
0212 
0213   SubRanges SR;
0214 
0215 public:
0216   LoopConstrainer(Loop &L, LoopInfo &LI,
0217                   function_ref<void(Loop *, bool)> LPMAddNewLoop,
0218                   const LoopStructure &LS, ScalarEvolution &SE,
0219                   DominatorTree &DT, Type *T, SubRanges SR);
0220 
0221   // Entry point for the algorithm.  Returns true on success.
0222   bool run();
0223 };
0224 } // namespace llvm
0225 
0226 #endif // LLVM_TRANSFORMS_UTILS_LOOP_CONSTRAINER_H