1 //===------ Support/ScopHelper.h -- Some Helper Functions for Scop. -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Small functions that help with LLVM-IR.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef POLLY_SUPPORT_IRHELPER_H
14 #define POLLY_SUPPORT_IRHELPER_H
15 
16 #include "llvm/ADT/SetVector.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/IntrinsicInst.h"
19 #include "llvm/IR/ValueHandle.h"
20 #include "isl/isl-noexceptions.h"
21 
22 namespace llvm {
23 class LoopInfo;
24 class Loop;
25 class ScalarEvolution;
26 class SCEV;
27 class Region;
28 class Pass;
29 class DominatorTree;
30 class RegionInfo;
31 class RegionNode;
32 } // namespace llvm
33 
34 namespace polly {
35 class Scop;
36 class ScopStmt;
37 
38 /// Enumeration of assumptions Polly can take.
39 enum AssumptionKind {
40   ALIASING,
41   INBOUNDS,
42   WRAPPING,
43   UNSIGNED,
44   PROFITABLE,
45   ERRORBLOCK,
46   COMPLEXITY,
47   INFINITELOOP,
48   INVARIANTLOAD,
49   DELINEARIZATION,
50 };
51 
52 /// Enum to distinguish between assumptions and restrictions.
53 enum AssumptionSign { AS_ASSUMPTION, AS_RESTRICTION };
54 
55 /// Helper struct to remember assumptions.
56 struct Assumption {
57   /// The kind of the assumption (e.g., WRAPPING).
58   AssumptionKind Kind;
59 
60   /// Flag to distinguish assumptions and restrictions.
61   AssumptionSign Sign;
62 
63   /// The valid/invalid context if this is an assumption/restriction.
64   isl::set Set;
65 
66   /// The location that caused this assumption.
67   llvm::DebugLoc Loc;
68 
69   /// An optional block whose domain can simplify the assumption.
70   llvm::BasicBlock *BB;
71 
72   // Whether the assumption must be checked at runtime.
73   bool RequiresRTC;
74 };
75 
76 using RecordedAssumptionsTy = llvm::SmallVector<Assumption, 8>;
77 
78 /// Record an assumption for later addition to the assumed context.
79 ///
80 /// This function will add the assumption to the RecordedAssumptions. This
81 /// collection will be added (@see addAssumption) to the assumed context once
82 /// all paramaters are known and the context is fully built.
83 ///
84 /// @param RecordedAssumption container which keeps all recorded assumptions.
85 /// @param Kind The assumption kind describing the underlying cause.
86 /// @param Set  The relations between parameters that are assumed to hold.
87 /// @param Loc  The location in the source that caused this assumption.
88 /// @param Sign Enum to indicate if the assumptions in @p Set are positive
89 ///             (needed/assumptions) or negative (invalid/restrictions).
90 /// @param BB   The block in which this assumption was taken. If it is
91 ///             set, the domain of that block will be used to simplify the
92 ///             actual assumption in @p Set once it is added. This is useful
93 ///             if the assumption was created prior to the domain.
94 /// @param RTC  Does the assumption require a runtime check?
95 void recordAssumption(RecordedAssumptionsTy *RecordedAssumptions,
96                       AssumptionKind Kind, isl::set Set, llvm::DebugLoc Loc,
97                       AssumptionSign Sign, llvm::BasicBlock *BB = nullptr,
98                       bool RTC = true);
99 
100 /// Type to remap values.
101 using ValueMapT = llvm::DenseMap<llvm::AssertingVH<llvm::Value>,
102                                  llvm::AssertingVH<llvm::Value>>;
103 
104 /// Type for a set of invariant loads.
105 using InvariantLoadsSetTy = llvm::SetVector<llvm::AssertingVH<llvm::LoadInst>>;
106 
107 /// Set type for parameters.
108 using ParameterSetTy = llvm::SetVector<const llvm::SCEV *>;
109 
110 /// Set of loops (used to remember loops in non-affine subregions).
111 using BoxedLoopsSetTy = llvm::SetVector<const llvm::Loop *>;
112 
113 /// Utility proxy to wrap the common members of LoadInst and StoreInst.
114 ///
115 /// This works like the LLVM utility class CallSite, ie. it forwards all calls
116 /// to either a LoadInst, StoreInst, MemIntrinsic or MemTransferInst.
117 /// It is similar to LLVM's utility classes IntrinsicInst, MemIntrinsic,
118 /// MemTransferInst, etc. in that it offers a common interface, but does not act
119 /// as a fake base class.
120 /// It is similar to StringRef and ArrayRef in that it holds a pointer to the
121 /// referenced object and should be passed by-value as it is small enough.
122 ///
123 /// This proxy can either represent a LoadInst instance, a StoreInst instance,
124 /// a MemIntrinsic instance (memset, memmove, memcpy), a CallInst instance or a
125 /// nullptr (only creatable using the default constructor); never an Instruction
126 /// that is neither of the above mentioned. When representing a nullptr, only
127 /// the following methods are defined:
128 /// isNull(), isInstruction(), isLoad(), isStore(), ..., isMemTransferInst(),
129 /// operator bool(), operator!()
130 ///
131 /// The functions isa, cast, cast_or_null, dyn_cast are modeled te resemble
132 /// those from llvm/Support/Casting.h. Partial template function specialization
133 /// is currently not supported in C++ such that those cannot be used directly.
134 /// (llvm::isa could, but then llvm:cast etc. would not have the expected
135 /// behavior)
136 class MemAccInst {
137 private:
138   llvm::Instruction *I;
139 
140 public:
MemAccInst()141   MemAccInst() : I(nullptr) {}
MemAccInst(const MemAccInst & Inst)142   MemAccInst(const MemAccInst &Inst) : I(Inst.I) {}
MemAccInst(llvm::LoadInst & LI)143   /* implicit */ MemAccInst(llvm::LoadInst &LI) : I(&LI) {}
MemAccInst(llvm::LoadInst * LI)144   /* implicit */ MemAccInst(llvm::LoadInst *LI) : I(LI) {}
MemAccInst(llvm::StoreInst & SI)145   /* implicit */ MemAccInst(llvm::StoreInst &SI) : I(&SI) {}
MemAccInst(llvm::StoreInst * SI)146   /* implicit */ MemAccInst(llvm::StoreInst *SI) : I(SI) {}
MemAccInst(llvm::MemIntrinsic * MI)147   /* implicit */ MemAccInst(llvm::MemIntrinsic *MI) : I(MI) {}
MemAccInst(llvm::CallInst * CI)148   /* implicit */ MemAccInst(llvm::CallInst *CI) : I(CI) {}
MemAccInst(llvm::Instruction & I)149   explicit MemAccInst(llvm::Instruction &I) : I(&I) { assert(isa(I)); }
MemAccInst(llvm::Instruction * I)150   explicit MemAccInst(llvm::Instruction *I) : I(I) { assert(isa(I)); }
151 
isa(const llvm::Value & V)152   static bool isa(const llvm::Value &V) {
153     return llvm::isa<llvm::LoadInst>(V) || llvm::isa<llvm::StoreInst>(V) ||
154            llvm::isa<llvm::CallInst>(V) || llvm::isa<llvm::MemIntrinsic>(V);
155   }
isa(const llvm::Value * V)156   static bool isa(const llvm::Value *V) {
157     return llvm::isa<llvm::LoadInst>(V) || llvm::isa<llvm::StoreInst>(V) ||
158            llvm::isa<llvm::CallInst>(V) || llvm::isa<llvm::MemIntrinsic>(V);
159   }
cast(llvm::Value & V)160   static MemAccInst cast(llvm::Value &V) {
161     return MemAccInst(llvm::cast<llvm::Instruction>(V));
162   }
cast(llvm::Value * V)163   static MemAccInst cast(llvm::Value *V) {
164     return MemAccInst(llvm::cast<llvm::Instruction>(V));
165   }
cast_or_null(llvm::Value & V)166   static MemAccInst cast_or_null(llvm::Value &V) {
167     return MemAccInst(llvm::cast<llvm::Instruction>(V));
168   }
cast_or_null(llvm::Value * V)169   static MemAccInst cast_or_null(llvm::Value *V) {
170     if (!V)
171       return MemAccInst();
172     return MemAccInst(llvm::cast<llvm::Instruction>(V));
173   }
dyn_cast(llvm::Value & V)174   static MemAccInst dyn_cast(llvm::Value &V) {
175     if (isa(V))
176       return MemAccInst(llvm::cast<llvm::Instruction>(V));
177     return MemAccInst();
178   }
dyn_cast(llvm::Value * V)179   static MemAccInst dyn_cast(llvm::Value *V) {
180     assert(V);
181     if (isa(V))
182       return MemAccInst(llvm::cast<llvm::Instruction>(V));
183     return MemAccInst();
184   }
185 
186   MemAccInst &operator=(const MemAccInst &Inst) {
187     I = Inst.I;
188     return *this;
189   }
190   MemAccInst &operator=(llvm::LoadInst &LI) {
191     I = &LI;
192     return *this;
193   }
194   MemAccInst &operator=(llvm::LoadInst *LI) {
195     I = LI;
196     return *this;
197   }
198   MemAccInst &operator=(llvm::StoreInst &SI) {
199     I = &SI;
200     return *this;
201   }
202   MemAccInst &operator=(llvm::StoreInst *SI) {
203     I = SI;
204     return *this;
205   }
206   MemAccInst &operator=(llvm::MemIntrinsic &MI) {
207     I = &MI;
208     return *this;
209   }
210   MemAccInst &operator=(llvm::MemIntrinsic *MI) {
211     I = MI;
212     return *this;
213   }
214   MemAccInst &operator=(llvm::CallInst &CI) {
215     I = &CI;
216     return *this;
217   }
218   MemAccInst &operator=(llvm::CallInst *CI) {
219     I = CI;
220     return *this;
221   }
222 
get()223   llvm::Instruction *get() const {
224     assert(I && "Unexpected nullptr!");
225     return I;
226   }
227   operator llvm::Instruction *() const { return asInstruction(); }
228   llvm::Instruction *operator->() const { return get(); }
229 
230   explicit operator bool() const { return isInstruction(); }
231   bool operator!() const { return isNull(); }
232 
getValueOperand()233   llvm::Value *getValueOperand() const {
234     if (isLoad())
235       return asLoad();
236     if (isStore())
237       return asStore()->getValueOperand();
238     if (isMemIntrinsic())
239       return nullptr;
240     if (isCallInst())
241       return nullptr;
242     llvm_unreachable("Operation not supported on nullptr");
243   }
getPointerOperand()244   llvm::Value *getPointerOperand() const {
245     if (isLoad())
246       return asLoad()->getPointerOperand();
247     if (isStore())
248       return asStore()->getPointerOperand();
249     if (isMemIntrinsic())
250       return asMemIntrinsic()->getRawDest();
251     if (isCallInst())
252       return nullptr;
253     llvm_unreachable("Operation not supported on nullptr");
254   }
255 
getAlignment()256   unsigned getAlignment() const {
257     if (isLoad())
258       return asLoad()->getAlignment();
259     if (isStore())
260       return asStore()->getAlignment();
261     if (isMemTransferInst())
262       return std::min(asMemTransferInst()->getDestAlignment(),
263                       asMemTransferInst()->getSourceAlignment());
264     if (isMemIntrinsic())
265       return asMemIntrinsic()->getDestAlignment();
266     if (isCallInst())
267       return 0;
268     llvm_unreachable("Operation not supported on nullptr");
269   }
isVolatile()270   bool isVolatile() const {
271     if (isLoad())
272       return asLoad()->isVolatile();
273     if (isStore())
274       return asStore()->isVolatile();
275     if (isMemIntrinsic())
276       return asMemIntrinsic()->isVolatile();
277     if (isCallInst())
278       return false;
279     llvm_unreachable("Operation not supported on nullptr");
280   }
isSimple()281   bool isSimple() const {
282     if (isLoad())
283       return asLoad()->isSimple();
284     if (isStore())
285       return asStore()->isSimple();
286     if (isMemIntrinsic())
287       return !asMemIntrinsic()->isVolatile();
288     if (isCallInst())
289       return true;
290     llvm_unreachable("Operation not supported on nullptr");
291   }
getOrdering()292   llvm::AtomicOrdering getOrdering() const {
293     if (isLoad())
294       return asLoad()->getOrdering();
295     if (isStore())
296       return asStore()->getOrdering();
297     if (isMemIntrinsic())
298       return llvm::AtomicOrdering::NotAtomic;
299     if (isCallInst())
300       return llvm::AtomicOrdering::NotAtomic;
301     llvm_unreachable("Operation not supported on nullptr");
302   }
isUnordered()303   bool isUnordered() const {
304     if (isLoad())
305       return asLoad()->isUnordered();
306     if (isStore())
307       return asStore()->isUnordered();
308     // Copied from the Load/Store implementation of isUnordered:
309     if (isMemIntrinsic())
310       return !asMemIntrinsic()->isVolatile();
311     if (isCallInst())
312       return true;
313     llvm_unreachable("Operation not supported on nullptr");
314   }
315 
isNull()316   bool isNull() const { return !I; }
isInstruction()317   bool isInstruction() const { return I; }
318 
asInstruction()319   llvm::Instruction *asInstruction() const { return I; }
320 
321 private:
isLoad()322   bool isLoad() const { return I && llvm::isa<llvm::LoadInst>(I); }
isStore()323   bool isStore() const { return I && llvm::isa<llvm::StoreInst>(I); }
isCallInst()324   bool isCallInst() const { return I && llvm::isa<llvm::CallInst>(I); }
isMemIntrinsic()325   bool isMemIntrinsic() const { return I && llvm::isa<llvm::MemIntrinsic>(I); }
isMemSetInst()326   bool isMemSetInst() const { return I && llvm::isa<llvm::MemSetInst>(I); }
isMemTransferInst()327   bool isMemTransferInst() const {
328     return I && llvm::isa<llvm::MemTransferInst>(I);
329   }
330 
asLoad()331   llvm::LoadInst *asLoad() const { return llvm::cast<llvm::LoadInst>(I); }
asStore()332   llvm::StoreInst *asStore() const { return llvm::cast<llvm::StoreInst>(I); }
asCallInst()333   llvm::CallInst *asCallInst() const { return llvm::cast<llvm::CallInst>(I); }
asMemIntrinsic()334   llvm::MemIntrinsic *asMemIntrinsic() const {
335     return llvm::cast<llvm::MemIntrinsic>(I);
336   }
asMemSetInst()337   llvm::MemSetInst *asMemSetInst() const {
338     return llvm::cast<llvm::MemSetInst>(I);
339   }
asMemTransferInst()340   llvm::MemTransferInst *asMemTransferInst() const {
341     return llvm::cast<llvm::MemTransferInst>(I);
342   }
343 };
344 } // namespace polly
345 
346 namespace llvm {
347 /// Specialize simplify_type for MemAccInst to enable dyn_cast and cast
348 ///        from a MemAccInst object.
349 template <> struct simplify_type<polly::MemAccInst> {
350   typedef Instruction *SimpleType;
351   static SimpleType getSimplifiedValue(polly::MemAccInst &I) {
352     return I.asInstruction();
353   }
354 };
355 } // namespace llvm
356 
357 namespace polly {
358 
359 /// Simplify the region to have a single unconditional entry edge and a
360 /// single exit edge.
361 ///
362 /// Although this function allows DT and RI to be null, regions only work
363 /// properly if the DominatorTree (for Region::contains) and RegionInfo are kept
364 /// up-to-date.
365 ///
366 /// @param R  The region to be simplified
367 /// @param DT DominatorTree to be updated.
368 /// @param LI LoopInfo to be updated.
369 /// @param RI RegionInfo to be updated.
370 void simplifyRegion(llvm::Region *R, llvm::DominatorTree *DT,
371                     llvm::LoopInfo *LI, llvm::RegionInfo *RI);
372 
373 /// Split the entry block of a function to store the newly inserted
374 ///        allocations outside of all Scops.
375 ///
376 /// @param EntryBlock The entry block of the current function.
377 /// @param P          The pass that currently running.
378 ///
379 void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock, llvm::Pass *P);
380 
381 /// Split the entry block of a function to store the newly inserted
382 ///        allocations outside of all Scops.
383 ///
384 /// @param DT DominatorTree to be updated.
385 /// @param LI LoopInfo to be updated.
386 /// @param RI RegionInfo to be updated.
387 void splitEntryBlockForAlloca(llvm::BasicBlock *EntryBlock,
388                               llvm::DominatorTree *DT, llvm::LoopInfo *LI,
389                               llvm::RegionInfo *RI);
390 
391 /// Wrapper for SCEVExpander extended to all Polly features.
392 ///
393 /// This wrapper will internally call the SCEVExpander but also makes sure that
394 /// all additional features not represented in SCEV (e.g., SDiv/SRem are not
395 /// black boxes but can be part of the function) will be expanded correctly.
396 ///
397 /// The parameters are the same as for the creation of a SCEVExpander as well
398 /// as the call to SCEVExpander::expandCodeFor:
399 ///
400 /// @param S     The current Scop.
401 /// @param SE    The Scalar Evolution pass.
402 /// @param DL    The module data layout.
403 /// @param Name  The suffix added to the new instruction names.
404 /// @param E     The expression for which code is actually generated.
405 /// @param Ty    The type of the resulting code.
406 /// @param IP    The insertion point for the new code.
407 /// @param VMap  A remapping of values used in @p E.
408 /// @param RTCBB The last block of the RTC. Used to insert loop-invariant
409 ///              instructions in rare cases.
410 llvm::Value *expandCodeFor(Scop &S, llvm::ScalarEvolution &SE,
411                            const llvm::DataLayout &DL, const char *Name,
412                            const llvm::SCEV *E, llvm::Type *Ty,
413                            llvm::Instruction *IP, ValueMapT *VMap,
414                            llvm::BasicBlock *RTCBB);
415 
416 /// Check if the block is a error block.
417 ///
418 /// A error block is currently any block that fulfills at least one of
419 /// the following conditions:
420 ///
421 ///  - It is terminated by an unreachable instruction
422 ///  - It contains a call to a non-pure function that is not immediately
423 ///    dominated by a loop header and that does not dominate the region exit.
424 ///    This is a heuristic to pick only error blocks that are conditionally
425 ///    executed and can be assumed to be not executed at all without the domains
426 ///    being available.
427 ///
428 /// @param BB The block to check.
429 /// @param R  The analyzed region.
430 /// @param LI The loop info analysis.
431 /// @param DT The dominator tree of the function.
432 ///
433 /// @return True if the block is a error block, false otherwise.
434 bool isErrorBlock(llvm::BasicBlock &BB, const llvm::Region &R,
435                   llvm::LoopInfo &LI, const llvm::DominatorTree &DT);
436 
437 /// Return the condition for the terminator @p TI.
438 ///
439 /// For unconditional branches the "i1 true" condition will be returned.
440 ///
441 /// @param TI The terminator to get the condition from.
442 ///
443 /// @return The condition of @p TI and nullptr if none could be extracted.
444 llvm::Value *getConditionFromTerminator(llvm::Instruction *TI);
445 
446 /// Get the smallest loop that contains @p S but is not in @p S.
447 llvm::Loop *getLoopSurroundingScop(Scop &S, llvm::LoopInfo &LI);
448 
449 /// Get the number of blocks in @p L.
450 ///
451 /// The number of blocks in a loop are the number of basic blocks actually
452 /// belonging to the loop, as well as all single basic blocks that the loop
453 /// exits to and which terminate in an unreachable instruction. We do not
454 /// allow such basic blocks in the exit of a scop, hence they belong to the
455 /// scop and represent run-time conditions which we want to model and
456 /// subsequently speculate away.
457 ///
458 /// @see getRegionNodeLoop for additional details.
459 unsigned getNumBlocksInLoop(llvm::Loop *L);
460 
461 /// Get the number of blocks in @p RN.
462 unsigned getNumBlocksInRegionNode(llvm::RegionNode *RN);
463 
464 /// Return the smallest loop surrounding @p RN.
465 llvm::Loop *getRegionNodeLoop(llvm::RegionNode *RN, llvm::LoopInfo &LI);
466 
467 /// Check if @p LInst can be hoisted in @p R.
468 ///
469 /// @param LInst The load to check.
470 /// @param R     The analyzed region.
471 /// @param LI    The loop info.
472 /// @param SE    The scalar evolution analysis.
473 /// @param DT    The dominator tree of the function.
474 /// @param KnownInvariantLoads The invariant load set.
475 ///
476 /// @return True if @p LInst can be hoisted in @p R.
477 bool isHoistableLoad(llvm::LoadInst *LInst, llvm::Region &R, llvm::LoopInfo &LI,
478                      llvm::ScalarEvolution &SE, const llvm::DominatorTree &DT,
479                      const InvariantLoadsSetTy &KnownInvariantLoads);
480 
481 /// Return true iff @p V is an intrinsic that we ignore during code
482 ///        generation.
483 bool isIgnoredIntrinsic(const llvm::Value *V);
484 
485 /// Check whether a value an be synthesized by the code generator.
486 ///
487 /// Some value will be recalculated only from information that is code generated
488 /// from the polyhedral representation. For such instructions we do not need to
489 /// ensure that their operands are available during code generation.
490 ///
491 /// @param V The value to check.
492 /// @param S The current SCoP.
493 /// @param SE The scalar evolution database.
494 /// @param Scope Location where the value would by synthesized.
495 /// @return If the instruction I can be regenerated from its
496 ///         scalar evolution representation, return true,
497 ///         otherwise return false.
498 bool canSynthesize(const llvm::Value *V, const Scop &S,
499                    llvm::ScalarEvolution *SE, llvm::Loop *Scope);
500 
501 /// Return the block in which a value is used.
502 ///
503 /// For normal instructions, this is the instruction's parent block. For PHI
504 /// nodes, this is the incoming block of that use, because this is where the
505 /// operand must be defined (i.e. its definition dominates this block).
506 /// Non-instructions do not use operands at a specific point such that in this
507 /// case this function returns nullptr.
508 llvm::BasicBlock *getUseBlock(const llvm::Use &U);
509 
510 // If the loop is nonaffine/boxed, return the first non-boxed surrounding loop
511 // for Polly. If the loop is affine, return the loop itself.
512 //
513 // @param L             Pointer to the Loop object to analyze.
514 // @param LI            Reference to the LoopInfo.
515 // @param BoxedLoops    Set of Boxed Loops we get from the SCoP.
516 llvm::Loop *getFirstNonBoxedLoopFor(llvm::Loop *L, llvm::LoopInfo &LI,
517                                     const BoxedLoopsSetTy &BoxedLoops);
518 
519 // If the Basic Block belongs to a loop that is nonaffine/boxed, return the
520 // first non-boxed surrounding loop for Polly. If the loop is affine, return
521 // the loop itself.
522 //
523 // @param BB            Pointer to the Basic Block to analyze.
524 // @param LI            Reference to the LoopInfo.
525 // @param BoxedLoops    Set of Boxed Loops we get from the SCoP.
526 llvm::Loop *getFirstNonBoxedLoopFor(llvm::BasicBlock *BB, llvm::LoopInfo &LI,
527                                     const BoxedLoopsSetTy &BoxedLoops);
528 
529 /// Is the given instruction a call to a debug function?
530 ///
531 /// A debug function can be used to insert output in Polly-optimized code which
532 /// normally does not allow function calls with side-effects. For instance, a
533 /// printf can be inserted to check whether a value still has the expected value
534 /// after Polly generated code:
535 ///
536 ///     int sum = 0;
537 ///     for (int i = 0; i < 16; i+=1) {
538 ///       sum += i;
539 ///       printf("The value of sum at i=%d is %d\n", sum, i);
540 ///     }
541 bool isDebugCall(llvm::Instruction *Inst);
542 
543 /// Does the statement contain a call to a debug function?
544 ///
545 /// Such a statement must not be removed, even if has no side-effects.
546 bool hasDebugCall(ScopStmt *Stmt);
547 
548 /// Find a property value in a LoopID.
549 ///
550 /// Generally, a property MDNode has the format
551 ///
552 ///   !{ !"Name", value }
553 ///
554 /// In which case the value is returned.
555 ///
556 /// If the property is just
557 ///
558 ///   !{ !"Name" }
559 ///
560 /// Then `nullptr` is set to mark the property is existing, but does not carry
561 /// any value. If the property does not exist, `None` is returned.
562 llvm::Optional<llvm::Metadata *> findMetadataOperand(llvm::MDNode *LoopMD,
563                                                      llvm::StringRef Name);
564 
565 /// Find a boolean property value in a LoopID. The value not being defined is
566 /// interpreted as a false value.
567 bool getBooleanLoopAttribute(llvm::MDNode *LoopID, llvm::StringRef Name);
568 
569 /// Find an integers property value in a LoopID.
570 llvm::Optional<int> getOptionalIntLoopAttribute(llvm::MDNode *LoopID,
571                                                 llvm::StringRef Name);
572 
573 /// Does the loop's LoopID contain a 'llvm.loop.disable_heuristics' property?
574 ///
575 /// This is equivalent to llvm::hasDisableAllTransformsHint(Loop*), but
576 /// including the LoopUtils.h header indirectly also declares llvm::MemoryAccess
577 /// which clashes with polly::MemoryAccess. Declaring this alias here avoid
578 /// having to include LoopUtils.h in other files.
579 bool hasDisableAllTransformsHint(llvm::Loop *L);
580 bool hasDisableAllTransformsHint(llvm::MDNode *LoopID);
581 
582 /// Represent the attributes of a loop.
583 struct BandAttr {
584   /// LoopID which stores the properties of the loop, such as transformations to
585   /// apply and the metadata of followup-loops.
586   ///
587   /// Cannot be used to identify a loop. Two different loops can have the same
588   /// metadata.
589   llvm::MDNode *Metadata = nullptr;
590 
591   /// The LoopInfo reference for this loop.
592   ///
593   /// Only loops from the original IR are represented by LoopInfo. Loops that
594   /// were generated by Polly are not tracked by LoopInfo.
595   llvm::Loop *OriginalLoop = nullptr;
596 };
597 
598 /// Get an isl::id representing a loop.
599 ///
600 /// This takes the ownership of the BandAttr and will be free'd when the
601 /// returned isl::Id is free'd.
602 isl::id getIslLoopAttr(isl::ctx Ctx, BandAttr *Attr);
603 
604 /// Create an isl::id that identifies an original loop.
605 ///
606 /// Return nullptr if the loop does not need a BandAttr (i.e. has no
607 /// properties);
608 ///
609 /// This creates a BandAttr which must be unique per loop and therefore this
610 /// must not be called multiple times on the same loop as their id would be
611 /// different.
612 isl::id createIslLoopAttr(isl::ctx Ctx, llvm::Loop *L);
613 
614 /// Is @p Id representing a loop?
615 ///
616 /// Such ids contain a polly::BandAttr as its user pointer.
617 bool isLoopAttr(const isl::id &Id);
618 
619 /// Return the BandAttr of a loop's isl::id.
620 BandAttr *getLoopAttr(const isl::id &Id);
621 
622 } // namespace polly
623 #endif
624