CGLoopInfo.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. //===---- CGLoopInfo.h - LLVM CodeGen for loop metadata -*- C++ -*---------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This is the internal state used for llvm translation for loop statement
  11. // metadata.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H
  15. #define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H
  16. #include "llvm/ADT/ArrayRef.h"
  17. #include "llvm/ADT/DenseMap.h"
  18. #include "llvm/ADT/SmallVector.h"
  19. #include "llvm/IR/Value.h"
  20. #include "llvm/Support/Compiler.h"
  21. namespace llvm {
  22. class BasicBlock;
  23. class Instruction;
  24. class MDNode;
  25. } // end namespace llvm
  26. namespace clang {
  27. class Attr;
  28. namespace CodeGen {
  29. /// \brief Attributes that may be specified on loops.
  30. struct LoopAttributes {
  31. explicit LoopAttributes(bool IsParallel = false);
  32. void clear();
  33. /// \brief Generate llvm.loop.parallel metadata for loads and stores.
  34. bool IsParallel;
  35. /// \brief Values of llvm.loop.vectorize.enable metadata.
  36. enum LVEnableState { VecUnspecified, VecEnable, VecDisable };
  37. /// \brief llvm.loop.vectorize.enable
  38. LVEnableState VectorizerEnable;
  39. /// \brief llvm.loop.vectorize.width
  40. unsigned VectorizerWidth;
  41. /// \brief llvm.loop.interleave.count
  42. unsigned VectorizerUnroll;
  43. // HLSL Change Begins.
  44. /// \brief hlsl loop unrolling policy based on [loop] and [unroll] attributes
  45. enum HlslUnrollPolicyEnum { HlslAllowUnroll, HlslDisableUnroll, HlslForceUnroll };
  46. /// \brief hlsl unrolling policy
  47. HlslUnrollPolicyEnum HlslUnrollPolicy;
  48. /// \brief argument to hlsl [unroll] attribute, 0 = full unroll
  49. unsigned HlslUnrollCount;
  50. // HLSL Change Ends.
  51. };
  52. /// \brief Information used when generating a structured loop.
  53. class LoopInfo {
  54. public:
  55. /// \brief Construct a new LoopInfo for the loop with entry Header.
  56. LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs);
  57. /// \brief Get the loop id metadata for this loop.
  58. llvm::MDNode *getLoopID() const { return LoopID; }
  59. /// \brief Get the header block of this loop.
  60. llvm::BasicBlock *getHeader() const { return Header; }
  61. /// \brief Get the set of attributes active for this loop.
  62. const LoopAttributes &getAttributes() const { return Attrs; }
  63. private:
  64. /// \brief Loop ID metadata.
  65. llvm::MDNode *LoopID;
  66. /// \brief Header block of this loop.
  67. llvm::BasicBlock *Header;
  68. /// \brief The attributes for this loop.
  69. LoopAttributes Attrs;
  70. };
  71. /// \brief A stack of loop information corresponding to loop nesting levels.
  72. /// This stack can be used to prepare attributes which are applied when a loop
  73. /// is emitted.
  74. class LoopInfoStack {
  75. LoopInfoStack(const LoopInfoStack &) = delete;
  76. void operator=(const LoopInfoStack &) = delete;
  77. public:
  78. LoopInfoStack() {}
  79. /// \brief Begin a new structured loop. The set of staged attributes will be
  80. /// applied to the loop and then cleared.
  81. void push(llvm::BasicBlock *Header,
  82. llvm::ArrayRef<const Attr *> Attrs = llvm::None);
  83. /// \brief End the current loop.
  84. void pop();
  85. /// \brief Return the top loop id metadata.
  86. llvm::MDNode *getCurLoopID() const { return getInfo().getLoopID(); }
  87. /// \brief Return true if the top loop is parallel.
  88. bool getCurLoopParallel() const {
  89. return hasInfo() ? getInfo().getAttributes().IsParallel : false;
  90. }
  91. /// \brief Function called by the CodeGenFunction when an instruction is
  92. /// created.
  93. void InsertHelper(llvm::Instruction *I) const;
  94. /// \brief Set the next pushed loop as parallel.
  95. void setParallel(bool Enable = true) { StagedAttrs.IsParallel = Enable; }
  96. /// \brief Set the next pushed loop 'vectorizer.enable'
  97. void setVectorizerEnable(bool Enable = true) {
  98. StagedAttrs.VectorizerEnable =
  99. Enable ? LoopAttributes::VecEnable : LoopAttributes::VecDisable;
  100. }
  101. /// \brief Set the vectorizer width for the next loop pushed.
  102. void setVectorizerWidth(unsigned W) { StagedAttrs.VectorizerWidth = W; }
  103. /// \brief Set the vectorizer unroll for the next loop pushed.
  104. void setVectorizerUnroll(unsigned U) { StagedAttrs.VectorizerUnroll = U; }
  105. // HLSL Change Begins
  106. /// \brief Set the hlsl unroll count for the next loop pushed.
  107. void setHlslUnroll(unsigned U) {
  108. StagedAttrs.HlslUnrollPolicy = LoopAttributes::HlslForceUnroll;
  109. StagedAttrs.HlslUnrollCount = U;
  110. }
  111. /// \brief Set the hlsl loop for the next loop pushed.
  112. void setHlslLoop() {
  113. StagedAttrs.HlslUnrollPolicy = LoopAttributes::HlslDisableUnroll;
  114. }
  115. // HLSL Chagne Ends
  116. private:
  117. /// \brief Returns true if there is LoopInfo on the stack.
  118. bool hasInfo() const { return !Active.empty(); }
  119. /// \brief Return the LoopInfo for the current loop. HasInfo should be called
  120. /// first to ensure LoopInfo is present.
  121. const LoopInfo &getInfo() const { return Active.back(); }
  122. /// \brief The set of attributes that will be applied to the next pushed loop.
  123. LoopAttributes StagedAttrs;
  124. /// \brief Stack of active loops.
  125. llvm::SmallVector<LoopInfo, 4> Active;
  126. };
  127. } // end namespace CodeGen
  128. } // end namespace clang
  129. #endif