CGLoopInfo.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. //===---- CGLoopInfo.cpp - 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. #include "CGLoopInfo.h"
  10. #include "clang/AST/ASTContext.h"
  11. #include "clang/AST/Attr.h"
  12. #include "clang/Sema/LoopHint.h"
  13. #include "llvm/IR/BasicBlock.h"
  14. #include "llvm/IR/Constants.h"
  15. #include "llvm/IR/InstrTypes.h"
  16. #include "llvm/IR/Instructions.h"
  17. #include "llvm/IR/Metadata.h"
  18. using namespace clang::CodeGen;
  19. using namespace llvm;
  20. static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs,
  21. llvm::DebugLoc Location) {
  22. if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
  23. Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
  24. Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
  25. Attrs.UnrollEnable == LoopAttributes::Unspecified &&
  26. Attrs.DistributeEnable == LoopAttributes::Unspecified &&
  27. !Location)
  28. return nullptr;
  29. SmallVector<Metadata *, 4> Args;
  30. // Reserve operand 0 for loop id self reference.
  31. auto TempNode = MDNode::getTemporary(Ctx, None);
  32. Args.push_back(TempNode.get());
  33. // If we have a valid debug location for the loop, add it.
  34. if (Location)
  35. Args.push_back(Location.getAsMDNode());
  36. // Setting vectorize.width
  37. if (Attrs.VectorizeWidth > 0) {
  38. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"),
  39. ConstantAsMetadata::get(ConstantInt::get(
  40. Type::getInt32Ty(Ctx), Attrs.VectorizeWidth))};
  41. Args.push_back(MDNode::get(Ctx, Vals));
  42. }
  43. // Setting interleave.count
  44. if (Attrs.InterleaveCount > 0) {
  45. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.interleave.count"),
  46. ConstantAsMetadata::get(ConstantInt::get(
  47. Type::getInt32Ty(Ctx), Attrs.InterleaveCount))};
  48. Args.push_back(MDNode::get(Ctx, Vals));
  49. }
  50. // Setting interleave.count
  51. if (Attrs.UnrollCount > 0) {
  52. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"),
  53. ConstantAsMetadata::get(ConstantInt::get(
  54. Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
  55. Args.push_back(MDNode::get(Ctx, Vals));
  56. }
  57. // Setting vectorize.enable
  58. if (Attrs.VectorizeEnable != LoopAttributes::Unspecified) {
  59. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
  60. ConstantAsMetadata::get(ConstantInt::get(
  61. Type::getInt1Ty(Ctx), (Attrs.VectorizeEnable ==
  62. LoopAttributes::Enable)))};
  63. Args.push_back(MDNode::get(Ctx, Vals));
  64. }
  65. // Setting unroll.full or unroll.disable
  66. if (Attrs.UnrollEnable != LoopAttributes::Unspecified) {
  67. std::string Name;
  68. if (Attrs.UnrollEnable == LoopAttributes::Enable)
  69. Name = "llvm.loop.unroll.enable";
  70. else if (Attrs.UnrollEnable == LoopAttributes::Full)
  71. Name = "llvm.loop.unroll.full";
  72. else
  73. Name = "llvm.loop.unroll.disable";
  74. Metadata *Vals[] = {MDString::get(Ctx, Name)};
  75. Args.push_back(MDNode::get(Ctx, Vals));
  76. }
  77. if (Attrs.DistributeEnable != LoopAttributes::Unspecified) {
  78. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
  79. ConstantAsMetadata::get(ConstantInt::get(
  80. Type::getInt1Ty(Ctx), (Attrs.DistributeEnable ==
  81. LoopAttributes::Enable)))};
  82. Args.push_back(MDNode::get(Ctx, Vals));
  83. }
  84. // Set the first operand to itself.
  85. MDNode *LoopID = MDNode::get(Ctx, Args);
  86. LoopID->replaceOperandWith(0, LoopID);
  87. return LoopID;
  88. }
  89. LoopAttributes::LoopAttributes(bool IsParallel)
  90. : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
  91. UnrollEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
  92. InterleaveCount(0), UnrollCount(0),
  93. DistributeEnable(LoopAttributes::Unspecified) {}
  94. void LoopAttributes::clear() {
  95. IsParallel = false;
  96. VectorizeWidth = 0;
  97. InterleaveCount = 0;
  98. UnrollCount = 0;
  99. VectorizeEnable = LoopAttributes::Unspecified;
  100. UnrollEnable = LoopAttributes::Unspecified;
  101. }
  102. LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
  103. llvm::DebugLoc Location)
  104. : LoopID(nullptr), Header(Header), Attrs(Attrs) {
  105. LoopID = createMetadata(Header->getContext(), Attrs, Location);
  106. }
  107. void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc Location) {
  108. Active.push_back(LoopInfo(Header, StagedAttrs, Location));
  109. // Clear the attributes so nested loops do not inherit them.
  110. StagedAttrs.clear();
  111. }
  112. void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
  113. ArrayRef<const clang::Attr *> Attrs,
  114. llvm::DebugLoc Location) {
  115. // Identify loop hint attributes from Attrs.
  116. for (const auto *Attr : Attrs) {
  117. const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
  118. const OpenCLUnrollHintAttr *OpenCLHint =
  119. dyn_cast<OpenCLUnrollHintAttr>(Attr);
  120. // Skip non loop hint attributes
  121. if (!LH && !OpenCLHint) {
  122. continue;
  123. }
  124. LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
  125. LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
  126. unsigned ValueInt = 1;
  127. // Translate opencl_unroll_hint attribute argument to
  128. // equivalent LoopHintAttr enums.
  129. // OpenCL v2.0 s6.11.5:
  130. // 0 - full unroll (no argument).
  131. // 1 - disable unroll.
  132. // other positive integer n - unroll by n.
  133. if (OpenCLHint) {
  134. ValueInt = OpenCLHint->getUnrollHint();
  135. if (ValueInt == 0) {
  136. State = LoopHintAttr::Full;
  137. } else if (ValueInt != 1) {
  138. Option = LoopHintAttr::UnrollCount;
  139. State = LoopHintAttr::Numeric;
  140. }
  141. } else if (LH) {
  142. auto *ValueExpr = LH->getValue();
  143. if (ValueExpr) {
  144. llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
  145. ValueInt = ValueAPS.getSExtValue();
  146. }
  147. Option = LH->getOption();
  148. State = LH->getState();
  149. }
  150. switch (State) {
  151. case LoopHintAttr::Disable:
  152. switch (Option) {
  153. case LoopHintAttr::Vectorize:
  154. // Disable vectorization by specifying a width of 1.
  155. setVectorizeWidth(1);
  156. break;
  157. case LoopHintAttr::Interleave:
  158. // Disable interleaving by speciyfing a count of 1.
  159. setInterleaveCount(1);
  160. break;
  161. case LoopHintAttr::Unroll:
  162. setUnrollState(LoopAttributes::Disable);
  163. break;
  164. case LoopHintAttr::Distribute:
  165. setDistributeState(false);
  166. break;
  167. case LoopHintAttr::UnrollCount:
  168. case LoopHintAttr::VectorizeWidth:
  169. case LoopHintAttr::InterleaveCount:
  170. llvm_unreachable("Options cannot be disabled.");
  171. break;
  172. }
  173. break;
  174. case LoopHintAttr::Enable:
  175. switch (Option) {
  176. case LoopHintAttr::Vectorize:
  177. case LoopHintAttr::Interleave:
  178. setVectorizeEnable(true);
  179. break;
  180. case LoopHintAttr::Unroll:
  181. setUnrollState(LoopAttributes::Enable);
  182. break;
  183. case LoopHintAttr::Distribute:
  184. setDistributeState(true);
  185. break;
  186. case LoopHintAttr::UnrollCount:
  187. case LoopHintAttr::VectorizeWidth:
  188. case LoopHintAttr::InterleaveCount:
  189. llvm_unreachable("Options cannot enabled.");
  190. break;
  191. }
  192. break;
  193. case LoopHintAttr::AssumeSafety:
  194. switch (Option) {
  195. case LoopHintAttr::Vectorize:
  196. case LoopHintAttr::Interleave:
  197. // Apply "llvm.mem.parallel_loop_access" metadata to load/stores.
  198. setParallel(true);
  199. setVectorizeEnable(true);
  200. break;
  201. case LoopHintAttr::Unroll:
  202. case LoopHintAttr::UnrollCount:
  203. case LoopHintAttr::VectorizeWidth:
  204. case LoopHintAttr::InterleaveCount:
  205. case LoopHintAttr::Distribute:
  206. llvm_unreachable("Options cannot be used to assume mem safety.");
  207. break;
  208. }
  209. break;
  210. case LoopHintAttr::Full:
  211. switch (Option) {
  212. case LoopHintAttr::Unroll:
  213. setUnrollState(LoopAttributes::Full);
  214. break;
  215. case LoopHintAttr::Vectorize:
  216. case LoopHintAttr::Interleave:
  217. case LoopHintAttr::UnrollCount:
  218. case LoopHintAttr::VectorizeWidth:
  219. case LoopHintAttr::InterleaveCount:
  220. case LoopHintAttr::Distribute:
  221. llvm_unreachable("Options cannot be used with 'full' hint.");
  222. break;
  223. }
  224. break;
  225. case LoopHintAttr::Numeric:
  226. switch (Option) {
  227. case LoopHintAttr::VectorizeWidth:
  228. setVectorizeWidth(ValueInt);
  229. break;
  230. case LoopHintAttr::InterleaveCount:
  231. setInterleaveCount(ValueInt);
  232. break;
  233. case LoopHintAttr::UnrollCount:
  234. setUnrollCount(ValueInt);
  235. break;
  236. case LoopHintAttr::Unroll:
  237. case LoopHintAttr::Vectorize:
  238. case LoopHintAttr::Interleave:
  239. case LoopHintAttr::Distribute:
  240. llvm_unreachable("Options cannot be assigned a value.");
  241. break;
  242. }
  243. break;
  244. }
  245. }
  246. /// Stage the attributes.
  247. push(Header, Location);
  248. }
  249. void LoopInfoStack::pop() {
  250. assert(!Active.empty() && "No active loops to pop");
  251. Active.pop_back();
  252. }
  253. void LoopInfoStack::InsertHelper(Instruction *I) const {
  254. if (!hasInfo())
  255. return;
  256. const LoopInfo &L = getInfo();
  257. if (!L.getLoopID())
  258. return;
  259. if (TerminatorInst *TI = dyn_cast<TerminatorInst>(I)) {
  260. for (unsigned i = 0, ie = TI->getNumSuccessors(); i < ie; ++i)
  261. if (TI->getSuccessor(i) == L.getHeader()) {
  262. TI->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID());
  263. break;
  264. }
  265. return;
  266. }
  267. if (L.getAttributes().IsParallel && I->mayReadOrWriteMemory())
  268. I->setMetadata("llvm.mem.parallel_loop_access", L.getLoopID());
  269. }