CGLoopInfo.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. //===---- CGLoopInfo.cpp - LLVM CodeGen for loop metadata -*- C++ -*-------===//
  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. #include "CGLoopInfo.h"
  9. #include "clang/AST/ASTContext.h"
  10. #include "clang/AST/Attr.h"
  11. #include "clang/AST/Expr.h"
  12. #include "clang/Basic/CodeGenOptions.h"
  13. #include "llvm/IR/BasicBlock.h"
  14. #include "llvm/IR/CFG.h"
  15. #include "llvm/IR/Constants.h"
  16. #include "llvm/IR/InstrTypes.h"
  17. #include "llvm/IR/Instructions.h"
  18. #include "llvm/IR/Metadata.h"
  19. using namespace clang::CodeGen;
  20. using namespace llvm;
  21. MDNode *
  22. LoopInfo::createLoopPropertiesMetadata(ArrayRef<Metadata *> LoopProperties) {
  23. LLVMContext &Ctx = Header->getContext();
  24. SmallVector<Metadata *, 4> NewLoopProperties;
  25. NewLoopProperties.push_back(nullptr);
  26. NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  27. MDNode *LoopID = MDNode::getDistinct(Ctx, NewLoopProperties);
  28. LoopID->replaceOperandWith(0, LoopID);
  29. return LoopID;
  30. }
  31. MDNode *LoopInfo::createPipeliningMetadata(const LoopAttributes &Attrs,
  32. ArrayRef<Metadata *> LoopProperties,
  33. bool &HasUserTransforms) {
  34. LLVMContext &Ctx = Header->getContext();
  35. Optional<bool> Enabled;
  36. if (Attrs.PipelineDisabled)
  37. Enabled = false;
  38. else if (Attrs.PipelineInitiationInterval != 0)
  39. Enabled = true;
  40. if (Enabled != true) {
  41. SmallVector<Metadata *, 4> NewLoopProperties;
  42. if (Enabled == false) {
  43. NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  44. NewLoopProperties.push_back(
  45. MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.pipeline.disable"),
  46. ConstantAsMetadata::get(ConstantInt::get(
  47. llvm::Type::getInt1Ty(Ctx), 1))}));
  48. LoopProperties = NewLoopProperties;
  49. }
  50. return createLoopPropertiesMetadata(LoopProperties);
  51. }
  52. SmallVector<Metadata *, 4> Args;
  53. Args.push_back(nullptr);
  54. Args.append(LoopProperties.begin(), LoopProperties.end());
  55. if (Attrs.PipelineInitiationInterval > 0) {
  56. Metadata *Vals[] = {
  57. MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
  58. ConstantAsMetadata::get(ConstantInt::get(
  59. llvm::Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
  60. Args.push_back(MDNode::get(Ctx, Vals));
  61. }
  62. // No follow-up: This is the last transformation.
  63. MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
  64. LoopID->replaceOperandWith(0, LoopID);
  65. HasUserTransforms = true;
  66. return LoopID;
  67. }
  68. MDNode *
  69. LoopInfo::createPartialUnrollMetadata(const LoopAttributes &Attrs,
  70. ArrayRef<Metadata *> LoopProperties,
  71. bool &HasUserTransforms) {
  72. LLVMContext &Ctx = Header->getContext();
  73. Optional<bool> Enabled;
  74. if (Attrs.UnrollEnable == LoopAttributes::Disable)
  75. Enabled = false;
  76. else if (Attrs.UnrollEnable == LoopAttributes::Full)
  77. Enabled = None;
  78. else if (Attrs.UnrollEnable != LoopAttributes::Unspecified ||
  79. Attrs.UnrollCount != 0)
  80. Enabled = true;
  81. if (Enabled != true) {
  82. // createFullUnrollMetadata will already have added llvm.loop.unroll.disable
  83. // if unrolling is disabled.
  84. return createPipeliningMetadata(Attrs, LoopProperties, HasUserTransforms);
  85. }
  86. SmallVector<Metadata *, 4> FollowupLoopProperties;
  87. // Apply all loop properties to the unrolled loop.
  88. FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  89. // Don't unroll an already unrolled loop.
  90. FollowupLoopProperties.push_back(
  91. MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
  92. bool FollowupHasTransforms = false;
  93. MDNode *Followup = createPipeliningMetadata(Attrs, FollowupLoopProperties,
  94. FollowupHasTransforms);
  95. SmallVector<Metadata *, 4> Args;
  96. Args.push_back(nullptr);
  97. Args.append(LoopProperties.begin(), LoopProperties.end());
  98. // Setting unroll.count
  99. if (Attrs.UnrollCount > 0) {
  100. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.count"),
  101. ConstantAsMetadata::get(ConstantInt::get(
  102. llvm::Type::getInt32Ty(Ctx), Attrs.UnrollCount))};
  103. Args.push_back(MDNode::get(Ctx, Vals));
  104. }
  105. // Setting unroll.full or unroll.disable
  106. if (Attrs.UnrollEnable == LoopAttributes::Enable) {
  107. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll.enable")};
  108. Args.push_back(MDNode::get(Ctx, Vals));
  109. }
  110. if (FollowupHasTransforms)
  111. Args.push_back(MDNode::get(
  112. Ctx, {MDString::get(Ctx, "llvm.loop.unroll.followup_all"), Followup}));
  113. MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
  114. LoopID->replaceOperandWith(0, LoopID);
  115. HasUserTransforms = true;
  116. return LoopID;
  117. }
  118. MDNode *
  119. LoopInfo::createUnrollAndJamMetadata(const LoopAttributes &Attrs,
  120. ArrayRef<Metadata *> LoopProperties,
  121. bool &HasUserTransforms) {
  122. LLVMContext &Ctx = Header->getContext();
  123. Optional<bool> Enabled;
  124. if (Attrs.UnrollAndJamEnable == LoopAttributes::Disable)
  125. Enabled = false;
  126. else if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable ||
  127. Attrs.UnrollAndJamCount != 0)
  128. Enabled = true;
  129. if (Enabled != true) {
  130. SmallVector<Metadata *, 4> NewLoopProperties;
  131. if (Enabled == false) {
  132. NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  133. NewLoopProperties.push_back(MDNode::get(
  134. Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
  135. LoopProperties = NewLoopProperties;
  136. }
  137. return createPartialUnrollMetadata(Attrs, LoopProperties,
  138. HasUserTransforms);
  139. }
  140. SmallVector<Metadata *, 4> FollowupLoopProperties;
  141. FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  142. FollowupLoopProperties.push_back(
  143. MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll_and_jam.disable")));
  144. bool FollowupHasTransforms = false;
  145. MDNode *Followup = createPartialUnrollMetadata(Attrs, FollowupLoopProperties,
  146. FollowupHasTransforms);
  147. SmallVector<Metadata *, 4> Args;
  148. Args.push_back(nullptr);
  149. Args.append(LoopProperties.begin(), LoopProperties.end());
  150. // Setting unroll_and_jam.count
  151. if (Attrs.UnrollAndJamCount > 0) {
  152. Metadata *Vals[] = {
  153. MDString::get(Ctx, "llvm.loop.unroll_and_jam.count"),
  154. ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
  155. Attrs.UnrollAndJamCount))};
  156. Args.push_back(MDNode::get(Ctx, Vals));
  157. }
  158. if (Attrs.UnrollAndJamEnable == LoopAttributes::Enable) {
  159. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.unroll_and_jam.enable")};
  160. Args.push_back(MDNode::get(Ctx, Vals));
  161. }
  162. if (FollowupHasTransforms)
  163. Args.push_back(MDNode::get(
  164. Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_outer"),
  165. Followup}));
  166. if (UnrollAndJamInnerFollowup)
  167. Args.push_back(MDNode::get(
  168. Ctx, {MDString::get(Ctx, "llvm.loop.unroll_and_jam.followup_inner"),
  169. UnrollAndJamInnerFollowup}));
  170. MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
  171. LoopID->replaceOperandWith(0, LoopID);
  172. HasUserTransforms = true;
  173. return LoopID;
  174. }
  175. MDNode *
  176. LoopInfo::createLoopVectorizeMetadata(const LoopAttributes &Attrs,
  177. ArrayRef<Metadata *> LoopProperties,
  178. bool &HasUserTransforms) {
  179. LLVMContext &Ctx = Header->getContext();
  180. Optional<bool> Enabled;
  181. if (Attrs.VectorizeEnable == LoopAttributes::Disable)
  182. Enabled = false;
  183. else if (Attrs.VectorizeEnable != LoopAttributes::Unspecified ||
  184. Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified ||
  185. Attrs.InterleaveCount != 0 || Attrs.VectorizeWidth != 0 ||
  186. Attrs.VectorizeScalable != LoopAttributes::Unspecified)
  187. Enabled = true;
  188. if (Enabled != true) {
  189. SmallVector<Metadata *, 4> NewLoopProperties;
  190. if (Enabled == false) {
  191. NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  192. NewLoopProperties.push_back(
  193. MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
  194. ConstantAsMetadata::get(ConstantInt::get(
  195. llvm::Type::getInt1Ty(Ctx), 0))}));
  196. LoopProperties = NewLoopProperties;
  197. }
  198. return createUnrollAndJamMetadata(Attrs, LoopProperties, HasUserTransforms);
  199. }
  200. // Apply all loop properties to the vectorized loop.
  201. SmallVector<Metadata *, 4> FollowupLoopProperties;
  202. FollowupLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  203. // Don't vectorize an already vectorized loop.
  204. FollowupLoopProperties.push_back(
  205. MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
  206. bool FollowupHasTransforms = false;
  207. MDNode *Followup = createUnrollAndJamMetadata(Attrs, FollowupLoopProperties,
  208. FollowupHasTransforms);
  209. SmallVector<Metadata *, 4> Args;
  210. Args.push_back(nullptr);
  211. Args.append(LoopProperties.begin(), LoopProperties.end());
  212. // Setting vectorize.predicate when it has been specified and vectorization
  213. // has not been disabled.
  214. bool IsVectorPredicateEnabled = false;
  215. if (Attrs.VectorizePredicateEnable != LoopAttributes::Unspecified) {
  216. IsVectorPredicateEnabled =
  217. (Attrs.VectorizePredicateEnable == LoopAttributes::Enable);
  218. Metadata *Vals[] = {
  219. MDString::get(Ctx, "llvm.loop.vectorize.predicate.enable"),
  220. ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt1Ty(Ctx),
  221. IsVectorPredicateEnabled))};
  222. Args.push_back(MDNode::get(Ctx, Vals));
  223. }
  224. // Setting vectorize.width
  225. if (Attrs.VectorizeWidth > 0) {
  226. Metadata *Vals[] = {
  227. MDString::get(Ctx, "llvm.loop.vectorize.width"),
  228. ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
  229. Attrs.VectorizeWidth))};
  230. Args.push_back(MDNode::get(Ctx, Vals));
  231. }
  232. if (Attrs.VectorizeScalable != LoopAttributes::Unspecified) {
  233. bool IsScalable = Attrs.VectorizeScalable == LoopAttributes::Enable;
  234. Metadata *Vals[] = {
  235. MDString::get(Ctx, "llvm.loop.vectorize.scalable.enable"),
  236. ConstantAsMetadata::get(
  237. ConstantInt::get(llvm::Type::getInt1Ty(Ctx), IsScalable))};
  238. Args.push_back(MDNode::get(Ctx, Vals));
  239. }
  240. // Setting interleave.count
  241. if (Attrs.InterleaveCount > 0) {
  242. Metadata *Vals[] = {
  243. MDString::get(Ctx, "llvm.loop.interleave.count"),
  244. ConstantAsMetadata::get(ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
  245. Attrs.InterleaveCount))};
  246. Args.push_back(MDNode::get(Ctx, Vals));
  247. }
  248. // vectorize.enable is set if:
  249. // 1) loop hint vectorize.enable is set, or
  250. // 2) it is implied when vectorize.predicate is set, or
  251. // 3) it is implied when vectorize.width is set to a value > 1
  252. // 4) it is implied when vectorize.scalable.enable is true
  253. // 5) it is implied when vectorize.width is unset (0) and the user
  254. // explicitly requested fixed-width vectorization, i.e.
  255. // vectorize.scalable.enable is false.
  256. if (Attrs.VectorizeEnable != LoopAttributes::Unspecified ||
  257. (IsVectorPredicateEnabled && Attrs.VectorizeWidth != 1) ||
  258. Attrs.VectorizeWidth > 1 ||
  259. Attrs.VectorizeScalable == LoopAttributes::Enable ||
  260. (Attrs.VectorizeScalable == LoopAttributes::Disable &&
  261. Attrs.VectorizeWidth != 1)) {
  262. bool AttrVal = Attrs.VectorizeEnable != LoopAttributes::Disable;
  263. Args.push_back(
  264. MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.vectorize.enable"),
  265. ConstantAsMetadata::get(ConstantInt::get(
  266. llvm::Type::getInt1Ty(Ctx), AttrVal))}));
  267. }
  268. if (FollowupHasTransforms)
  269. Args.push_back(MDNode::get(
  270. Ctx,
  271. {MDString::get(Ctx, "llvm.loop.vectorize.followup_all"), Followup}));
  272. MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
  273. LoopID->replaceOperandWith(0, LoopID);
  274. HasUserTransforms = true;
  275. return LoopID;
  276. }
  277. MDNode *
  278. LoopInfo::createLoopDistributeMetadata(const LoopAttributes &Attrs,
  279. ArrayRef<Metadata *> LoopProperties,
  280. bool &HasUserTransforms) {
  281. LLVMContext &Ctx = Header->getContext();
  282. Optional<bool> Enabled;
  283. if (Attrs.DistributeEnable == LoopAttributes::Disable)
  284. Enabled = false;
  285. if (Attrs.DistributeEnable == LoopAttributes::Enable)
  286. Enabled = true;
  287. if (Enabled != true) {
  288. SmallVector<Metadata *, 4> NewLoopProperties;
  289. if (Enabled == false) {
  290. NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  291. NewLoopProperties.push_back(
  292. MDNode::get(Ctx, {MDString::get(Ctx, "llvm.loop.distribute.enable"),
  293. ConstantAsMetadata::get(ConstantInt::get(
  294. llvm::Type::getInt1Ty(Ctx), 0))}));
  295. LoopProperties = NewLoopProperties;
  296. }
  297. return createLoopVectorizeMetadata(Attrs, LoopProperties,
  298. HasUserTransforms);
  299. }
  300. bool FollowupHasTransforms = false;
  301. MDNode *Followup =
  302. createLoopVectorizeMetadata(Attrs, LoopProperties, FollowupHasTransforms);
  303. SmallVector<Metadata *, 4> Args;
  304. Args.push_back(nullptr);
  305. Args.append(LoopProperties.begin(), LoopProperties.end());
  306. Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.distribute.enable"),
  307. ConstantAsMetadata::get(ConstantInt::get(
  308. llvm::Type::getInt1Ty(Ctx),
  309. (Attrs.DistributeEnable == LoopAttributes::Enable)))};
  310. Args.push_back(MDNode::get(Ctx, Vals));
  311. if (FollowupHasTransforms)
  312. Args.push_back(MDNode::get(
  313. Ctx,
  314. {MDString::get(Ctx, "llvm.loop.distribute.followup_all"), Followup}));
  315. MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
  316. LoopID->replaceOperandWith(0, LoopID);
  317. HasUserTransforms = true;
  318. return LoopID;
  319. }
  320. MDNode *LoopInfo::createFullUnrollMetadata(const LoopAttributes &Attrs,
  321. ArrayRef<Metadata *> LoopProperties,
  322. bool &HasUserTransforms) {
  323. LLVMContext &Ctx = Header->getContext();
  324. Optional<bool> Enabled;
  325. if (Attrs.UnrollEnable == LoopAttributes::Disable)
  326. Enabled = false;
  327. else if (Attrs.UnrollEnable == LoopAttributes::Full)
  328. Enabled = true;
  329. if (Enabled != true) {
  330. SmallVector<Metadata *, 4> NewLoopProperties;
  331. if (Enabled == false) {
  332. NewLoopProperties.append(LoopProperties.begin(), LoopProperties.end());
  333. NewLoopProperties.push_back(
  334. MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.disable")));
  335. LoopProperties = NewLoopProperties;
  336. }
  337. return createLoopDistributeMetadata(Attrs, LoopProperties,
  338. HasUserTransforms);
  339. }
  340. SmallVector<Metadata *, 4> Args;
  341. Args.push_back(nullptr);
  342. Args.append(LoopProperties.begin(), LoopProperties.end());
  343. Args.push_back(MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.unroll.full")));
  344. // No follow-up: there is no loop after full unrolling.
  345. // TODO: Warn if there are transformations after full unrolling.
  346. MDNode *LoopID = MDNode::getDistinct(Ctx, Args);
  347. LoopID->replaceOperandWith(0, LoopID);
  348. HasUserTransforms = true;
  349. return LoopID;
  350. }
  351. MDNode *LoopInfo::createMetadata(
  352. const LoopAttributes &Attrs,
  353. llvm::ArrayRef<llvm::Metadata *> AdditionalLoopProperties,
  354. bool &HasUserTransforms) {
  355. SmallVector<Metadata *, 3> LoopProperties;
  356. // If we have a valid start debug location for the loop, add it.
  357. if (StartLoc) {
  358. LoopProperties.push_back(StartLoc.getAsMDNode());
  359. // If we also have a valid end debug location for the loop, add it.
  360. if (EndLoc)
  361. LoopProperties.push_back(EndLoc.getAsMDNode());
  362. }
  363. LLVMContext &Ctx = Header->getContext();
  364. if (Attrs.MustProgress)
  365. LoopProperties.push_back(
  366. MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.mustprogress")));
  367. assert(!!AccGroup == Attrs.IsParallel &&
  368. "There must be an access group iff the loop is parallel");
  369. if (Attrs.IsParallel) {
  370. LoopProperties.push_back(MDNode::get(
  371. Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
  372. }
  373. LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(),
  374. AdditionalLoopProperties.end());
  375. return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
  376. }
  377. LoopAttributes::LoopAttributes(bool IsParallel)
  378. : IsParallel(IsParallel), VectorizeEnable(LoopAttributes::Unspecified),
  379. UnrollEnable(LoopAttributes::Unspecified),
  380. UnrollAndJamEnable(LoopAttributes::Unspecified),
  381. VectorizePredicateEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
  382. VectorizeScalable(LoopAttributes::Unspecified), InterleaveCount(0),
  383. UnrollCount(0), UnrollAndJamCount(0),
  384. DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
  385. PipelineInitiationInterval(0), MustProgress(false) {}
  386. void LoopAttributes::clear() {
  387. IsParallel = false;
  388. VectorizeWidth = 0;
  389. VectorizeScalable = LoopAttributes::Unspecified;
  390. InterleaveCount = 0;
  391. UnrollCount = 0;
  392. UnrollAndJamCount = 0;
  393. VectorizeEnable = LoopAttributes::Unspecified;
  394. UnrollEnable = LoopAttributes::Unspecified;
  395. UnrollAndJamEnable = LoopAttributes::Unspecified;
  396. VectorizePredicateEnable = LoopAttributes::Unspecified;
  397. DistributeEnable = LoopAttributes::Unspecified;
  398. PipelineDisabled = false;
  399. PipelineInitiationInterval = 0;
  400. MustProgress = false;
  401. }
  402. LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
  403. const llvm::DebugLoc &StartLoc, const llvm::DebugLoc &EndLoc,
  404. LoopInfo *Parent)
  405. : Header(Header), Attrs(Attrs), StartLoc(StartLoc), EndLoc(EndLoc),
  406. Parent(Parent) {
  407. if (Attrs.IsParallel) {
  408. // Create an access group for this loop.
  409. LLVMContext &Ctx = Header->getContext();
  410. AccGroup = MDNode::getDistinct(Ctx, {});
  411. }
  412. if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
  413. Attrs.VectorizeScalable == LoopAttributes::Unspecified &&
  414. Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
  415. Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
  416. Attrs.PipelineInitiationInterval == 0 &&
  417. Attrs.VectorizePredicateEnable == LoopAttributes::Unspecified &&
  418. Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
  419. Attrs.UnrollEnable == LoopAttributes::Unspecified &&
  420. Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
  421. Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
  422. !EndLoc && !Attrs.MustProgress)
  423. return;
  424. TempLoopID = MDNode::getTemporary(Header->getContext(), None);
  425. }
  426. void LoopInfo::finish() {
  427. // We did not annotate the loop body instructions because there are no
  428. // attributes for this loop.
  429. if (!TempLoopID)
  430. return;
  431. MDNode *LoopID;
  432. LoopAttributes CurLoopAttr = Attrs;
  433. LLVMContext &Ctx = Header->getContext();
  434. if (Parent && (Parent->Attrs.UnrollAndJamEnable ||
  435. Parent->Attrs.UnrollAndJamCount != 0)) {
  436. // Parent unroll-and-jams this loop.
  437. // Split the transformations in those that happens before the unroll-and-jam
  438. // and those after.
  439. LoopAttributes BeforeJam, AfterJam;
  440. BeforeJam.IsParallel = AfterJam.IsParallel = Attrs.IsParallel;
  441. BeforeJam.VectorizeWidth = Attrs.VectorizeWidth;
  442. BeforeJam.VectorizeScalable = Attrs.VectorizeScalable;
  443. BeforeJam.InterleaveCount = Attrs.InterleaveCount;
  444. BeforeJam.VectorizeEnable = Attrs.VectorizeEnable;
  445. BeforeJam.DistributeEnable = Attrs.DistributeEnable;
  446. BeforeJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable;
  447. switch (Attrs.UnrollEnable) {
  448. case LoopAttributes::Unspecified:
  449. case LoopAttributes::Disable:
  450. BeforeJam.UnrollEnable = Attrs.UnrollEnable;
  451. AfterJam.UnrollEnable = Attrs.UnrollEnable;
  452. break;
  453. case LoopAttributes::Full:
  454. BeforeJam.UnrollEnable = LoopAttributes::Full;
  455. break;
  456. case LoopAttributes::Enable:
  457. AfterJam.UnrollEnable = LoopAttributes::Enable;
  458. break;
  459. }
  460. AfterJam.VectorizePredicateEnable = Attrs.VectorizePredicateEnable;
  461. AfterJam.UnrollCount = Attrs.UnrollCount;
  462. AfterJam.PipelineDisabled = Attrs.PipelineDisabled;
  463. AfterJam.PipelineInitiationInterval = Attrs.PipelineInitiationInterval;
  464. // If this loop is subject of an unroll-and-jam by the parent loop, and has
  465. // an unroll-and-jam annotation itself, we have to decide whether to first
  466. // apply the parent's unroll-and-jam or this loop's unroll-and-jam. The
  467. // UnrollAndJam pass processes loops from inner to outer, so we apply the
  468. // inner first.
  469. BeforeJam.UnrollAndJamCount = Attrs.UnrollAndJamCount;
  470. BeforeJam.UnrollAndJamEnable = Attrs.UnrollAndJamEnable;
  471. // Set the inner followup metadata to process by the outer loop. Only
  472. // consider the first inner loop.
  473. if (!Parent->UnrollAndJamInnerFollowup) {
  474. // Splitting the attributes into a BeforeJam and an AfterJam part will
  475. // stop 'llvm.loop.isvectorized' (generated by vectorization in BeforeJam)
  476. // to be forwarded to the AfterJam part. We detect the situation here and
  477. // add it manually.
  478. SmallVector<Metadata *, 1> BeforeLoopProperties;
  479. if (BeforeJam.VectorizeEnable != LoopAttributes::Unspecified ||
  480. BeforeJam.VectorizePredicateEnable != LoopAttributes::Unspecified ||
  481. BeforeJam.InterleaveCount != 0 || BeforeJam.VectorizeWidth != 0 ||
  482. BeforeJam.VectorizeScalable == LoopAttributes::Enable)
  483. BeforeLoopProperties.push_back(
  484. MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.isvectorized")));
  485. bool InnerFollowupHasTransform = false;
  486. MDNode *InnerFollowup = createMetadata(AfterJam, BeforeLoopProperties,
  487. InnerFollowupHasTransform);
  488. if (InnerFollowupHasTransform)
  489. Parent->UnrollAndJamInnerFollowup = InnerFollowup;
  490. }
  491. CurLoopAttr = BeforeJam;
  492. }
  493. bool HasUserTransforms = false;
  494. LoopID = createMetadata(CurLoopAttr, {}, HasUserTransforms);
  495. TempLoopID->replaceAllUsesWith(LoopID);
  496. }
  497. void LoopInfoStack::push(BasicBlock *Header, const llvm::DebugLoc &StartLoc,
  498. const llvm::DebugLoc &EndLoc) {
  499. Active.emplace_back(
  500. new LoopInfo(Header, StagedAttrs, StartLoc, EndLoc,
  501. Active.empty() ? nullptr : Active.back().get()));
  502. // Clear the attributes so nested loops do not inherit them.
  503. StagedAttrs.clear();
  504. }
  505. void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
  506. const clang::CodeGenOptions &CGOpts,
  507. ArrayRef<const clang::Attr *> Attrs,
  508. const llvm::DebugLoc &StartLoc,
  509. const llvm::DebugLoc &EndLoc, bool MustProgress) {
  510. // Identify loop hint attributes from Attrs.
  511. for (const auto *Attr : Attrs) {
  512. const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
  513. const OpenCLUnrollHintAttr *OpenCLHint =
  514. dyn_cast<OpenCLUnrollHintAttr>(Attr);
  515. // Skip non loop hint attributes
  516. if (!LH && !OpenCLHint) {
  517. continue;
  518. }
  519. LoopHintAttr::OptionType Option = LoopHintAttr::Unroll;
  520. LoopHintAttr::LoopHintState State = LoopHintAttr::Disable;
  521. unsigned ValueInt = 1;
  522. // Translate opencl_unroll_hint attribute argument to
  523. // equivalent LoopHintAttr enums.
  524. // OpenCL v2.0 s6.11.5:
  525. // 0 - enable unroll (no argument).
  526. // 1 - disable unroll.
  527. // other positive integer n - unroll by n.
  528. if (OpenCLHint) {
  529. ValueInt = OpenCLHint->getUnrollHint();
  530. if (ValueInt == 0) {
  531. State = LoopHintAttr::Enable;
  532. } else if (ValueInt != 1) {
  533. Option = LoopHintAttr::UnrollCount;
  534. State = LoopHintAttr::Numeric;
  535. }
  536. } else if (LH) {
  537. auto *ValueExpr = LH->getValue();
  538. if (ValueExpr) {
  539. llvm::APSInt ValueAPS = ValueExpr->EvaluateKnownConstInt(Ctx);
  540. ValueInt = ValueAPS.getSExtValue();
  541. }
  542. Option = LH->getOption();
  543. State = LH->getState();
  544. }
  545. switch (State) {
  546. case LoopHintAttr::Disable:
  547. switch (Option) {
  548. case LoopHintAttr::Vectorize:
  549. // Disable vectorization by specifying a width of 1.
  550. setVectorizeWidth(1);
  551. setVectorizeScalable(LoopAttributes::Unspecified);
  552. break;
  553. case LoopHintAttr::Interleave:
  554. // Disable interleaving by speciyfing a count of 1.
  555. setInterleaveCount(1);
  556. break;
  557. case LoopHintAttr::Unroll:
  558. setUnrollState(LoopAttributes::Disable);
  559. break;
  560. case LoopHintAttr::UnrollAndJam:
  561. setUnrollAndJamState(LoopAttributes::Disable);
  562. break;
  563. case LoopHintAttr::VectorizePredicate:
  564. setVectorizePredicateState(LoopAttributes::Disable);
  565. break;
  566. case LoopHintAttr::Distribute:
  567. setDistributeState(false);
  568. break;
  569. case LoopHintAttr::PipelineDisabled:
  570. setPipelineDisabled(true);
  571. break;
  572. case LoopHintAttr::UnrollCount:
  573. case LoopHintAttr::UnrollAndJamCount:
  574. case LoopHintAttr::VectorizeWidth:
  575. case LoopHintAttr::InterleaveCount:
  576. case LoopHintAttr::PipelineInitiationInterval:
  577. llvm_unreachable("Options cannot be disabled.");
  578. break;
  579. }
  580. break;
  581. case LoopHintAttr::Enable:
  582. switch (Option) {
  583. case LoopHintAttr::Vectorize:
  584. case LoopHintAttr::Interleave:
  585. setVectorizeEnable(true);
  586. break;
  587. case LoopHintAttr::Unroll:
  588. setUnrollState(LoopAttributes::Enable);
  589. break;
  590. case LoopHintAttr::UnrollAndJam:
  591. setUnrollAndJamState(LoopAttributes::Enable);
  592. break;
  593. case LoopHintAttr::VectorizePredicate:
  594. setVectorizePredicateState(LoopAttributes::Enable);
  595. break;
  596. case LoopHintAttr::Distribute:
  597. setDistributeState(true);
  598. break;
  599. case LoopHintAttr::UnrollCount:
  600. case LoopHintAttr::UnrollAndJamCount:
  601. case LoopHintAttr::VectorizeWidth:
  602. case LoopHintAttr::InterleaveCount:
  603. case LoopHintAttr::PipelineDisabled:
  604. case LoopHintAttr::PipelineInitiationInterval:
  605. llvm_unreachable("Options cannot enabled.");
  606. break;
  607. }
  608. break;
  609. case LoopHintAttr::AssumeSafety:
  610. switch (Option) {
  611. case LoopHintAttr::Vectorize:
  612. case LoopHintAttr::Interleave:
  613. // Apply "llvm.mem.parallel_loop_access" metadata to load/stores.
  614. setParallel(true);
  615. setVectorizeEnable(true);
  616. break;
  617. case LoopHintAttr::Unroll:
  618. case LoopHintAttr::UnrollAndJam:
  619. case LoopHintAttr::VectorizePredicate:
  620. case LoopHintAttr::UnrollCount:
  621. case LoopHintAttr::UnrollAndJamCount:
  622. case LoopHintAttr::VectorizeWidth:
  623. case LoopHintAttr::InterleaveCount:
  624. case LoopHintAttr::Distribute:
  625. case LoopHintAttr::PipelineDisabled:
  626. case LoopHintAttr::PipelineInitiationInterval:
  627. llvm_unreachable("Options cannot be used to assume mem safety.");
  628. break;
  629. }
  630. break;
  631. case LoopHintAttr::Full:
  632. switch (Option) {
  633. case LoopHintAttr::Unroll:
  634. setUnrollState(LoopAttributes::Full);
  635. break;
  636. case LoopHintAttr::UnrollAndJam:
  637. setUnrollAndJamState(LoopAttributes::Full);
  638. break;
  639. case LoopHintAttr::Vectorize:
  640. case LoopHintAttr::Interleave:
  641. case LoopHintAttr::UnrollCount:
  642. case LoopHintAttr::UnrollAndJamCount:
  643. case LoopHintAttr::VectorizeWidth:
  644. case LoopHintAttr::InterleaveCount:
  645. case LoopHintAttr::Distribute:
  646. case LoopHintAttr::PipelineDisabled:
  647. case LoopHintAttr::PipelineInitiationInterval:
  648. case LoopHintAttr::VectorizePredicate:
  649. llvm_unreachable("Options cannot be used with 'full' hint.");
  650. break;
  651. }
  652. break;
  653. case LoopHintAttr::FixedWidth:
  654. case LoopHintAttr::ScalableWidth:
  655. switch (Option) {
  656. case LoopHintAttr::VectorizeWidth:
  657. setVectorizeScalable(State == LoopHintAttr::ScalableWidth
  658. ? LoopAttributes::Enable
  659. : LoopAttributes::Disable);
  660. if (LH->getValue())
  661. setVectorizeWidth(ValueInt);
  662. break;
  663. default:
  664. llvm_unreachable("Options cannot be used with 'scalable' hint.");
  665. break;
  666. }
  667. break;
  668. case LoopHintAttr::Numeric:
  669. switch (Option) {
  670. case LoopHintAttr::InterleaveCount:
  671. setInterleaveCount(ValueInt);
  672. break;
  673. case LoopHintAttr::UnrollCount:
  674. setUnrollCount(ValueInt);
  675. break;
  676. case LoopHintAttr::UnrollAndJamCount:
  677. setUnrollAndJamCount(ValueInt);
  678. break;
  679. case LoopHintAttr::PipelineInitiationInterval:
  680. setPipelineInitiationInterval(ValueInt);
  681. break;
  682. case LoopHintAttr::Unroll:
  683. case LoopHintAttr::UnrollAndJam:
  684. case LoopHintAttr::VectorizePredicate:
  685. case LoopHintAttr::Vectorize:
  686. case LoopHintAttr::VectorizeWidth:
  687. case LoopHintAttr::Interleave:
  688. case LoopHintAttr::Distribute:
  689. case LoopHintAttr::PipelineDisabled:
  690. llvm_unreachable("Options cannot be assigned a value.");
  691. break;
  692. }
  693. break;
  694. }
  695. }
  696. setMustProgress(MustProgress);
  697. if (CGOpts.OptimizationLevel > 0)
  698. // Disable unrolling for the loop, if unrolling is disabled (via
  699. // -fno-unroll-loops) and no pragmas override the decision.
  700. if (!CGOpts.UnrollLoops &&
  701. (StagedAttrs.UnrollEnable == LoopAttributes::Unspecified &&
  702. StagedAttrs.UnrollCount == 0))
  703. setUnrollState(LoopAttributes::Disable);
  704. /// Stage the attributes.
  705. push(Header, StartLoc, EndLoc);
  706. }
  707. void LoopInfoStack::pop() {
  708. assert(!Active.empty() && "No active loops to pop");
  709. Active.back()->finish();
  710. Active.pop_back();
  711. }
  712. void LoopInfoStack::InsertHelper(Instruction *I) const {
  713. if (I->mayReadOrWriteMemory()) {
  714. SmallVector<Metadata *, 4> AccessGroups;
  715. for (const auto &AL : Active) {
  716. // Here we assume that every loop that has an access group is parallel.
  717. if (MDNode *Group = AL->getAccessGroup())
  718. AccessGroups.push_back(Group);
  719. }
  720. MDNode *UnionMD = nullptr;
  721. if (AccessGroups.size() == 1)
  722. UnionMD = cast<MDNode>(AccessGroups[0]);
  723. else if (AccessGroups.size() >= 2)
  724. UnionMD = MDNode::get(I->getContext(), AccessGroups);
  725. I->setMetadata("llvm.access.group", UnionMD);
  726. }
  727. if (!hasInfo())
  728. return;
  729. const LoopInfo &L = getInfo();
  730. if (!L.getLoopID())
  731. return;
  732. if (I->isTerminator()) {
  733. for (BasicBlock *Succ : successors(I))
  734. if (Succ == L.getHeader()) {
  735. I->setMetadata(llvm::LLVMContext::MD_loop, L.getLoopID());
  736. break;
  737. }
  738. return;
  739. }
  740. }