Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:48:20

0001 //===------ Support/ScopHelper.h -- Some Helper Functions for Scop. -------===//
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 // Small functions that help with LLVM-IR.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef POLLY_SUPPORT_IRHELPER_H
0014 #define POLLY_SUPPORT_IRHELPER_H
0015 
0016 #include "llvm/ADT/SetVector.h"
0017 #include "llvm/IR/Instructions.h"
0018 #include "llvm/IR/IntrinsicInst.h"
0019 #include "llvm/IR/ValueHandle.h"
0020 #include "isl/isl-noexceptions.h"
0021 #include <optional>
0022 
0023 namespace llvm {
0024 class LoopInfo;
0025 class Loop;
0026 class ScalarEvolution;
0027 class SCEV;
0028 class Region;
0029 class Pass;
0030 class DominatorTree;
0031 class RegionInfo;
0032 class RegionNode;
0033 } // namespace llvm
0034 
0035 namespace polly {
0036 class Scop;
0037 class ScopStmt;
0038 
0039 /// Same as llvm/Analysis/ScalarEvolutionExpressions.h
0040 using LoopToScevMapT = llvm::DenseMap<const llvm::Loop *, const llvm::SCEV *>;
0041 
0042 /// Enumeration of assumptions Polly can take.
0043 enum AssumptionKind {
0044   ALIASING,
0045   INBOUNDS,
0046   WRAPPING,
0047   UNSIGNED,
0048   PROFITABLE,
0049   ERRORBLOCK,
0050   COMPLEXITY,
0051   INFINITELOOP,
0052   INVARIANTLOAD,
0053   DELINEARIZATION,
0054 };
0055 
0056 /// Enum to distinguish between assumptions and restrictions.
0057 enum AssumptionSign { AS_ASSUMPTION, AS_RESTRICTION };
0058 
0059 /// Helper struct to remember assumptions.
0060 struct Assumption {
0061   /// The kind of the assumption (e.g., WRAPPING).
0062   AssumptionKind Kind;
0063 
0064   /// Flag to distinguish assumptions and restrictions.
0065   AssumptionSign Sign;
0066 
0067   /// The valid/invalid context if this is an assumption/restriction.
0068   isl::set Set;
0069 
0070   /// The location that caused this assumption.
0071   llvm::DebugLoc Loc;
0072 
0073   /// An optional block whose domain can simplify the assumption.
0074   llvm::BasicBlock *BB;
0075 
0076   // Whether the assumption must be checked at runtime.
0077   bool RequiresRTC;
0078 };
0079 
0080 using RecordedAssumptionsTy = llvm::SmallVector<Assumption, 8>;
0081 
0082 /// Record an assumption for later addition to the assumed context.
0083 ///
0084 /// This function will add the assumption to the RecordedAssumptions. This
0085 /// collection will be added (@see addAssumption) to the assumed context once
0086 /// all parameters are known and the context is fully built.
0087 ///
0088 /// @param RecordedAssumption container which keeps all recorded assumptions.
0089 /// @param Kind The assumption kind describing the underlying cause.
0090 /// @param Set  The relations between parameters that are assumed to hold.
0091 /// @param Loc  The location in the source that caused this assumption.
0092 /// @param Sign Enum to indicate if the assumptions in @p Set are positive
0093 ///             (needed/assumptions) or negative (invalid/restrictions).
0094 /// @param BB   The block in which this assumption was taken. If it is
0095 ///             set, the domain of that block will be used to simplify the
0096 ///             actual assumption in @p Set once it is added. This is useful
0097 ///             if the assumption was created prior to the domain.
0098 /// @param RTC  Does the assumption require a runtime check?
0099 void recordAssumption(RecordedAssumptionsTy *RecordedAssumptions,
0100                       AssumptionKind Kind, isl::set Set, llvm::DebugLoc Loc,
0101                       AssumptionSign Sign, llvm::BasicBlock *BB = nullptr,
0102                       bool RTC = true);
0103 
0104 /// Type to remap values.
0105 using ValueMapT = llvm::DenseMap<llvm::AssertingVH<llvm::Value>,
0106                                  llvm::AssertingVH<llvm::Value>>;
0107 
0108 /// Type for a set of invariant loads.
0109 using InvariantLoadsSetTy = llvm::SetVector<llvm::AssertingVH<llvm::LoadInst>>;
0110 
0111 /// Set type for parameters.
0112 using ParameterSetTy = llvm::SetVector<const llvm::SCEV *>;
0113 
0114 /// Set of loops (used to remember loops in non-affine subregions).
0115 using BoxedLoopsSetTy = llvm::SetVector<const llvm::Loop *>;
0116 
0117 /// Utility proxy to wrap the common members of LoadInst and StoreInst.
0118 ///
0119 /// This works like the LLVM utility class CallSite, ie. it forwards all calls
0120 /// to either a LoadInst, StoreInst, MemIntrinsic or MemTransferInst.
0121 /// It is similar to LLVM's utility classes IntrinsicInst, MemIntrinsic,
0122 /// MemTransferInst, etc. in that it offers a common interface, but does not act
0123 /// as a fake base class.
0124 /// It is similar to StringRef and ArrayRef in that it holds a pointer to the
0125 /// referenced object and should be passed by-value as it is small enough.
0126 ///
0127 /// This proxy can either represent a LoadInst instance, a StoreInst instance,
0128 /// a MemIntrinsic instance (memset, memmove, memcpy), a CallInst instance or a
0129 /// nullptr (only creatable using the default constructor); never an Instruction
0130 /// that is neither of the above mentioned. When representing a nullptr, only
0131 /// the following methods are defined:
0132 /// isNull(), isInstruction(), isLoad(), isStore(), ..., isMemTransferInst(),
0133 /// operator bool(), operator!()
0134 ///
0135 /// The functions isa, cast, cast_or_null, dyn_cast are modeled to resemble
0136 /// those from llvm/Support/Casting.h. Partial template function specialization
0137 /// is currently not supported in C++ such that those cannot be used directly.
0138 /// (llvm::isa could, but then llvm:cast etc. would not have the expected
0139 /// behavior)
0140 class MemAccInst final {
0141 private:
0142   llvm::Instruction *I;
0143 
0144 public:
0145   MemAccInst() : I(nullptr) {}
0146   MemAccInst(const MemAccInst &Inst) : I(Inst.I) {}
0147   /* implicit */ MemAccInst(llvm::LoadInst &LI) : I(&LI) {}
0148   /* implicit */ MemAccInst(llvm::LoadInst *LI) : I(LI) {}
0149   /* implicit */ MemAccInst(llvm::StoreInst &SI) : I(&SI) {}
0150   /* implicit */ MemAccInst(llvm::StoreInst *SI) : I(SI) {}
0151   /* implicit */ MemAccInst(llvm::MemIntrinsic *MI) : I(MI) {}
0152   /* implicit */ MemAccInst(llvm::CallInst *CI) : I(CI) {}
0153   explicit MemAccInst(llvm::Instruction &I) : I(&I) { assert(isa(I)); }
0154   explicit MemAccInst(llvm::Instruction *I) : I(I) { assert(isa(I)); }
0155 
0156   static bool isa(const llvm::Value &V) {
0157     return llvm::isa<llvm::LoadInst>(V) || llvm::isa<llvm::StoreInst>(V) ||
0158            llvm::isa<llvm::CallInst>(V) || llvm::isa<llvm::MemIntrinsic>(V);
0159   }
0160   static bool isa(const llvm::Value *V) {
0161     return llvm::isa<llvm::LoadInst>(V) || llvm::isa<llvm::StoreInst>(V) ||
0162            llvm::isa<llvm::CallInst>(V) || llvm::isa<llvm::MemIntrinsic>(V);
0163   }
0164   static MemAccInst cast(llvm::Value &V) {
0165     return MemAccInst(llvm::cast<llvm::Instruction>(V));
0166   }
0167   static MemAccInst cast(llvm::Value *V) {
0168     return MemAccInst(llvm::cast<llvm::Instruction>(V));
0169   }
0170   static MemAccInst cast_or_null(llvm::Value &V) {
0171     return MemAccInst(llvm::cast<llvm::Instruction>(V));
0172   }
0173   static MemAccInst cast_or_null(llvm::Value *V) {
0174     if (!V)
0175       return MemAccInst();
0176     return MemAccInst(llvm::cast<llvm::Instruction>(V));
0177   }
0178   static MemAccInst dyn_cast(llvm::Value &V) {
0179     if (isa(V))
0180       return MemAccInst(llvm::cast<llvm::Instruction>(V));
0181     return MemAccInst();
0182   }
0183   static MemAccInst dyn_cast(llvm::Value *V) {
0184     assert(V);
0185     if (isa(V))
0186       return MemAccInst(llvm::cast<llvm::Instruction>(V));
0187     return MemAccInst();
0188   }
0189 
0190   MemAccInst &operator=(const MemAccInst &Inst) {
0191     I = Inst.I;
0192     return *this;
0193   }
0194   MemAccInst &operator=(llvm::LoadInst &LI) {
0195     I = &LI;
0196     return *this;
0197   }
0198   MemAccInst &operator=(llvm::LoadInst *LI) {
0199     I = LI;
0200     return *this;
0201   }
0202   MemAccInst &operator=(llvm::StoreInst &SI) {
0203     I = &SI;
0204     return *this;
0205   }
0206   MemAccInst &operator=(llvm::StoreInst *SI) {
0207     I = SI;
0208     return *this;
0209   }
0210   MemAccInst &operator=(llvm::MemIntrinsic &MI) {
0211     I = &MI;
0212     return *this;
0213   }
0214   MemAccInst &operator=(llvm::MemIntrinsic *MI) {
0215     I = MI;
0216     return *this;
0217   }
0218   MemAccInst &operator=(llvm::CallInst &CI) {
0219     I = &CI;
0220     return *this;
0221   }
0222   MemAccInst &operator=(llvm::CallInst *CI) {
0223     I = CI;
0224     return *this;
0225   }
0226 
0227   llvm::Instruction *get() const {
0228     assert(I && "Unexpected nullptr!");
0229     return I;
0230   }
0231   operator llvm::Instruction *() const { return asInstruction(); }
0232   llvm::Instruction *operator->() const { return get(); }
0233 
0234   explicit operator bool() const { return isInstruction(); }
0235   bool operator!() const { return isNull(); }
0236 
0237   llvm::Value *getValueOperand() const {
0238     if (isLoad())
0239       return asLoad();
0240     if (isStore())
0241       return asStore()->getValueOperand();
0242     if (isMemIntrinsic())
0243       return nullptr;
0244     if (isCallInst())
0245       return nullptr;
0246     llvm_unreachable("Operation not supported on nullptr");
0247   }
0248   llvm::Value *getPointerOperand() const {
0249     if (isLoad())
0250       return asLoad()->getPointerOperand();
0251     if (isStore())
0252       return asStore()->getPointerOperand();
0253     if (isMemIntrinsic())
0254       return asMemIntrinsic()->getRawDest();
0255     if (isCallInst())
0256       return nullptr;
0257     llvm_unreachable("Operation not supported on nullptr");
0258   }
0259   bool isVolatile() const {
0260     if (isLoad())
0261       return asLoad()->isVolatile();
0262     if (isStore())
0263       return asStore()->isVolatile();
0264     if (isMemIntrinsic())
0265       return asMemIntrinsic()->isVolatile();
0266     if (isCallInst())
0267       return false;
0268     llvm_unreachable("Operation not supported on nullptr");
0269   }
0270   bool isSimple() const {
0271     if (isLoad())
0272       return asLoad()->isSimple();
0273     if (isStore())
0274       return asStore()->isSimple();
0275     if (isMemIntrinsic())
0276       return !asMemIntrinsic()->isVolatile();
0277     if (isCallInst())
0278       return true;
0279     llvm_unreachable("Operation not supported on nullptr");
0280   }
0281   llvm::AtomicOrdering getOrdering() const {
0282     if (isLoad())
0283       return asLoad()->getOrdering();
0284     if (isStore())
0285       return asStore()->getOrdering();
0286     if (isMemIntrinsic())
0287       return llvm::AtomicOrdering::NotAtomic;
0288     if (isCallInst())
0289       return llvm::AtomicOrdering::NotAtomic;
0290     llvm_unreachable("Operation not supported on nullptr");
0291   }
0292   bool isUnordered() const {
0293     if (isLoad())
0294       return asLoad()->isUnordered();
0295     if (isStore())
0296       return asStore()->isUnordered();
0297     // Copied from the Load/Store implementation of isUnordered:
0298     if (isMemIntrinsic())
0299       return !asMemIntrinsic()->isVolatile();
0300     if (isCallInst())
0301       return true;
0302     llvm_unreachable("Operation not supported on nullptr");
0303   }
0304 
0305   bool isNull() const { return !I; }
0306   bool isInstruction() const { return I; }
0307 
0308   llvm::Instruction *asInstruction() const { return I; }
0309 
0310   bool isLoad() const { return I && llvm::isa<llvm::LoadInst>(I); }
0311   bool isStore() const { return I && llvm::isa<llvm::StoreInst>(I); }
0312   bool isCallInst() const { return I && llvm::isa<llvm::CallInst>(I); }
0313   bool isMemIntrinsic() const { return I && llvm::isa<llvm::MemIntrinsic>(I); }
0314   bool isMemSetInst() const { return I && llvm::isa<llvm::MemSetInst>(I); }
0315   bool isMemTransferInst() const {
0316     return I && llvm::isa<llvm::MemTransferInst>(I);
0317   }
0318 
0319   llvm::LoadInst *asLoad() const { return llvm::cast<llvm::LoadInst>(I); }
0320   llvm::StoreInst *asStore() const { return llvm::cast<llvm::StoreInst>(I); }
0321   llvm::CallInst *asCallInst() const { return llvm::cast<llvm::CallInst>(I); }
0322   llvm::MemIntrinsic *asMemIntrinsic() const {
0323     return llvm::cast<llvm::MemIntrinsic>(I);
0324   }
0325   llvm::MemSetInst *asMemSetInst() const {
0326     return llvm::cast<llvm::MemSetInst>(I);
0327   }
0328   llvm::MemTransferInst *asMemTransferInst() const {
0329     return llvm::cast<llvm::MemTransferInst>(I);
0330   }
0331 };
0332 } // namespace polly
0333 
0334 namespace llvm {
0335 /// Specialize simplify_type for MemAccInst to enable dyn_cast and cast
0336 ///        from a MemAccInst object.
0337 template <> struct simplify_type<polly::MemAccInst> {
0338   typedef Instruction *SimpleType;
0339   static SimpleType getSimplifiedValue(polly::MemAccInst &I) {
0340     return I.asInstruction();
0341   }
0342 };
0343 } // namespace llvm
0344 
0345 namespace polly {
0346 
0347 /// Simplify the region to have a single unconditional entry edge and a
0348 /// single exit edge.
0349 ///
0350 /// Although this function allows DT and RI to be null, regions only work
0351 /// properly if the DominatorTree (for Region::contains) and RegionInfo are kept
0352 /// up-to-date.
0353 ///
0354 /// @param R  The region to be simplified
0355 /// @param DT DominatorTree to be updated.
0356 /// @param LI LoopInfo to be updated.
0357 /// @param RI RegionInfo to be updated.
0358 void simplifyRegion(llvm::Region *R, llvm::DominatorTree *DT,
0359                     llvm::LoopInfo *LI, llvm::RegionInfo *RI);
0360 
0361 /// Split the entry block of a function to store the newly inserted
0362 ///        allocations outside of all Scops.
0363 ///
0364 /// @param EntryBlock The entry block of the current function.
0365 /// @param P          The pass that currently running.
0366 ///
0367 void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P);
0368 
0369 /// Split the entry block of a function to store the newly inserted
0370 ///        allocations outside of all Scops.
0371 ///
0372 /// @param DT DominatorTree to be updated.
0373 /// @param LI LoopInfo to be updated.
0374 /// @param RI RegionInfo to be updated.
0375 void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock,
0376                               llvm::DominatorTree *DT, llvm::LoopInfo *LI,
0377                               llvm::RegionInfo *RI);
0378 
0379 /// Wrapper for SCEVExpander extended to all Polly features.
0380 ///
0381 /// This wrapper will internally call the SCEVExpander but also makes sure that
0382 /// all additional features not represented in SCEV (e.g., SDiv/SRem are not
0383 /// black boxes but can be part of the function) will be expanded correctly.
0384 ///
0385 /// The parameters are the same as for the creation of a SCEVExpander as well
0386 /// as the call to SCEVExpander::expandCodeFor:
0387 ///
0388 /// @param S     The current Scop.
0389 /// @param SE    The Scalar Evolution pass used by @p S.
0390 /// @param GenFn The function to generate code in. Can be the same as @p SE.
0391 /// @param GenSE The Scalar Evolution pass for @p GenFn.
0392 /// @param DL    The module data layout.
0393 /// @param Name  The suffix added to the new instruction names.
0394 /// @param E     The expression for which code is actually generated.
0395 /// @param Ty    The type of the resulting code.
0396 /// @param IP    The insertion point for the new code.
0397 /// @param VMap  A remapping of values used in @p E.
0398 /// @param LoopMap A remapping of loops used in @p E.
0399 /// @param RTCBB The last block of the RTC. Used to insert loop-invariant
0400 ///              instructions in rare cases.
0401 llvm::Value *expandCodeFor(Scop &S, llvm::ScalarEvolution &SE,
0402                            llvm::Function *GenFn, llvm::ScalarEvolution &GenSE,
0403                            const llvm::DataLayout &DL, const char *Name,
0404                            const llvm::SCEV *E, llvm::Type *Ty,
0405                            llvm::Instruction *IP, ValueMapT *VMap,
0406                            LoopToScevMapT *LoopMap, llvm::BasicBlock *RTCBB);
0407 
0408 /// Return the condition for the terminator @p TI.
0409 ///
0410 /// For unconditional branches the "i1 true" condition will be returned.
0411 ///
0412 /// @param TI The terminator to get the condition from.
0413 ///
0414 /// @return The condition of @p TI and nullptr if none could be extracted.
0415 llvm::Value *getConditionFromTerminator(llvm::Instruction *TI);
0416 
0417 /// Get the smallest loop that contains @p S but is not in @p S.
0418 llvm::Loop *getLoopSurroundingScop(Scop &S, llvm::LoopInfo &LI);
0419 
0420 /// Get the number of blocks in @p L.
0421 ///
0422 /// The number of blocks in a loop are the number of basic blocks actually
0423 /// belonging to the loop, as well as all single basic blocks that the loop
0424 /// exits to and which terminate in an unreachable instruction. We do not
0425 /// allow such basic blocks in the exit of a scop, hence they belong to the
0426 /// scop and represent run-time conditions which we want to model and
0427 /// subsequently speculate away.
0428 ///
0429 /// @see getRegionNodeLoop for additional details.
0430 unsigned getNumBlocksInLoop(llvm::Loop *L);
0431 
0432 /// Get the number of blocks in @p RN.
0433 unsigned getNumBlocksInRegionNode(llvm::RegionNode *RN);
0434 
0435 /// Return the smallest loop surrounding @p RN.
0436 llvm::Loop *getRegionNodeLoop(llvm::RegionNode *RN, llvm::LoopInfo &LI);
0437 
0438 /// Check if @p LInst can be hoisted in @p R.
0439 ///
0440 /// @param LInst The load to check.
0441 /// @param R     The analyzed region.
0442 /// @param LI    The loop info.
0443 /// @param SE    The scalar evolution analysis.
0444 /// @param DT    The dominator tree of the function.
0445 /// @param KnownInvariantLoads The invariant load set.
0446 ///
0447 /// @return True if @p LInst can be hoisted in @p R.
0448 bool isHoistableLoad(llvm::LoadInst *LInst, llvm::Region &R, llvm::LoopInfo &LI,
0449                      llvm::ScalarEvolution &SE, const llvm::DominatorTree &DT,
0450                      const InvariantLoadsSetTy &KnownInvariantLoads);
0451 
0452 /// Return true iff @p V is an intrinsic that we ignore during code
0453 ///        generation.
0454 bool isIgnoredIntrinsic(const llvm::Value *V);
0455 
0456 /// Check whether a value an be synthesized by the code generator.
0457 ///
0458 /// Some value will be recalculated only from information that is code generated
0459 /// from the polyhedral representation. For such instructions we do not need to
0460 /// ensure that their operands are available during code generation.
0461 ///
0462 /// @param V The value to check.
0463 /// @param S The current SCoP.
0464 /// @param SE The scalar evolution database.
0465 /// @param Scope Location where the value would by synthesized.
0466 /// @return If the instruction I can be regenerated from its
0467 ///         scalar evolution representation, return true,
0468 ///         otherwise return false.
0469 bool canSynthesize(const llvm::Value *V, const Scop &S,
0470                    llvm::ScalarEvolution *SE, llvm::Loop *Scope);
0471 
0472 /// Return the block in which a value is used.
0473 ///
0474 /// For normal instructions, this is the instruction's parent block. For PHI
0475 /// nodes, this is the incoming block of that use, because this is where the
0476 /// operand must be defined (i.e. its definition dominates this block).
0477 /// Non-instructions do not use operands at a specific point such that in this
0478 /// case this function returns nullptr.
0479 llvm::BasicBlock *getUseBlock(const llvm::Use &U);
0480 
0481 // If the loop is nonaffine/boxed, return the first non-boxed surrounding loop
0482 // for Polly. If the loop is affine, return the loop itself.
0483 //
0484 // @param L             Pointer to the Loop object to analyze.
0485 // @param LI            Reference to the LoopInfo.
0486 // @param BoxedLoops    Set of Boxed Loops we get from the SCoP.
0487 llvm::Loop *getFirstNonBoxedLoopFor(llvm::Loop *L, llvm::LoopInfo &LI,
0488                                     const BoxedLoopsSetTy &BoxedLoops);
0489 
0490 // If the Basic Block belongs to a loop that is nonaffine/boxed, return the
0491 // first non-boxed surrounding loop for Polly. If the loop is affine, return
0492 // the loop itself.
0493 //
0494 // @param BB            Pointer to the Basic Block to analyze.
0495 // @param LI            Reference to the LoopInfo.
0496 // @param BoxedLoops    Set of Boxed Loops we get from the SCoP.
0497 llvm::Loop *getFirstNonBoxedLoopFor(llvm::BasicBlock *BB, llvm::LoopInfo &LI,
0498                                     const BoxedLoopsSetTy &BoxedLoops);
0499 
0500 /// Is the given instruction a call to a debug function?
0501 ///
0502 /// A debug function can be used to insert output in Polly-optimized code which
0503 /// normally does not allow function calls with side-effects. For instance, a
0504 /// printf can be inserted to check whether a value still has the expected value
0505 /// after Polly generated code:
0506 ///
0507 ///     int sum = 0;
0508 ///     for (int i = 0; i < 16; i+=1) {
0509 ///       sum += i;
0510 ///       printf("The value of sum at i=%d is %d\n", sum, i);
0511 ///     }
0512 bool isDebugCall(llvm::Instruction *Inst);
0513 
0514 /// Does the statement contain a call to a debug function?
0515 ///
0516 /// Such a statement must not be removed, even if has no side-effects.
0517 bool hasDebugCall(ScopStmt *Stmt);
0518 
0519 /// Find a property value in a LoopID.
0520 ///
0521 /// Generally, a property MDNode has the format
0522 ///
0523 ///   !{ !"Name", value }
0524 ///
0525 /// In which case the value is returned.
0526 ///
0527 /// If the property is just
0528 ///
0529 ///   !{ !"Name" }
0530 ///
0531 /// Then `nullptr` is set to mark the property is existing, but does not carry
0532 /// any value. If the property does not exist, `std::nullopt` is returned.
0533 std::optional<llvm::Metadata *> findMetadataOperand(llvm::MDNode *LoopMD,
0534                                                     llvm::StringRef Name);
0535 
0536 /// Find a boolean property value in a LoopID. The value not being defined is
0537 /// interpreted as a false value.
0538 bool getBooleanLoopAttribute(llvm::MDNode *LoopID, llvm::StringRef Name);
0539 
0540 /// Find an integers property value in a LoopID.
0541 std::optional<int> getOptionalIntLoopAttribute(llvm::MDNode *LoopID,
0542                                                llvm::StringRef Name);
0543 
0544 /// Does the loop's LoopID contain a 'llvm.loop.disable_heuristics' property?
0545 ///
0546 /// This is equivalent to llvm::hasDisableAllTransformsHint(Loop*), but
0547 /// including the LoopUtils.h header indirectly also declares llvm::MemoryAccess
0548 /// which clashes with polly::MemoryAccess. Declaring this alias here avoid
0549 /// having to include LoopUtils.h in other files.
0550 bool hasDisableAllTransformsHint(llvm::Loop *L);
0551 bool hasDisableAllTransformsHint(llvm::MDNode *LoopID);
0552 
0553 /// Represent the attributes of a loop.
0554 struct BandAttr {
0555   /// LoopID which stores the properties of the loop, such as transformations to
0556   /// apply and the metadata of followup-loops.
0557   ///
0558   /// Cannot be used to identify a loop. Two different loops can have the same
0559   /// metadata.
0560   llvm::MDNode *Metadata = nullptr;
0561 
0562   /// The LoopInfo reference for this loop.
0563   ///
0564   /// Only loops from the original IR are represented by LoopInfo. Loops that
0565   /// were generated by Polly are not tracked by LoopInfo.
0566   llvm::Loop *OriginalLoop = nullptr;
0567 };
0568 
0569 /// Get an isl::id representing a loop.
0570 ///
0571 /// This takes the ownership of the BandAttr and will be free'd when the
0572 /// returned isl::Id is free'd.
0573 isl::id getIslLoopAttr(isl::ctx Ctx, BandAttr *Attr);
0574 
0575 /// Create an isl::id that identifies an original loop.
0576 ///
0577 /// Return nullptr if the loop does not need a BandAttr (i.e. has no
0578 /// properties);
0579 ///
0580 /// This creates a BandAttr which must be unique per loop and therefore this
0581 /// must not be called multiple times on the same loop as their id would be
0582 /// different.
0583 isl::id createIslLoopAttr(isl::ctx Ctx, llvm::Loop *L);
0584 
0585 /// Is @p Id representing a loop?
0586 ///
0587 /// Such ids contain a polly::BandAttr as its user pointer.
0588 bool isLoopAttr(const isl::id &Id);
0589 
0590 /// Return the BandAttr of a loop's isl::id.
0591 BandAttr *getLoopAttr(const isl::id &Id);
0592 
0593 } // namespace polly
0594 #endif