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