WarnMissedTransforms.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. //===- LoopTransformWarning.cpp - ----------------------------------------===//
  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. // Emit warnings if forced code transformations have not been performed.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
  13. #include "llvm/Analysis/LoopInfo.h"
  14. #include "llvm/Analysis/OptimizationRemarkEmitter.h"
  15. #include "llvm/InitializePasses.h"
  16. #include "llvm/Transforms/Utils/LoopUtils.h"
  17. using namespace llvm;
  18. #define DEBUG_TYPE "transform-warning"
  19. /// Emit warnings for forced (i.e. user-defined) loop transformations which have
  20. /// still not been performed.
  21. static void warnAboutLeftoverTransformations(Loop *L,
  22. OptimizationRemarkEmitter *ORE) {
  23. if (hasUnrollTransformation(L) == TM_ForcedByUser) {
  24. LLVM_DEBUG(dbgs() << "Leftover unroll transformation\n");
  25. ORE->emit(
  26. DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
  27. "FailedRequestedUnrolling",
  28. L->getStartLoc(), L->getHeader())
  29. << "loop not unrolled: the optimizer was unable to perform the "
  30. "requested transformation; the transformation might be disabled or "
  31. "specified as part of an unsupported transformation ordering");
  32. }
  33. if (hasUnrollAndJamTransformation(L) == TM_ForcedByUser) {
  34. LLVM_DEBUG(dbgs() << "Leftover unroll-and-jam transformation\n");
  35. ORE->emit(
  36. DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
  37. "FailedRequestedUnrollAndJamming",
  38. L->getStartLoc(), L->getHeader())
  39. << "loop not unroll-and-jammed: the optimizer was unable to perform "
  40. "the requested transformation; the transformation might be disabled "
  41. "or specified as part of an unsupported transformation ordering");
  42. }
  43. if (hasVectorizeTransformation(L) == TM_ForcedByUser) {
  44. LLVM_DEBUG(dbgs() << "Leftover vectorization transformation\n");
  45. Optional<ElementCount> VectorizeWidth =
  46. getOptionalElementCountLoopAttribute(L);
  47. Optional<int> InterleaveCount =
  48. getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count");
  49. if (!VectorizeWidth || VectorizeWidth->isVector())
  50. ORE->emit(
  51. DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
  52. "FailedRequestedVectorization",
  53. L->getStartLoc(), L->getHeader())
  54. << "loop not vectorized: the optimizer was unable to perform the "
  55. "requested transformation; the transformation might be disabled "
  56. "or specified as part of an unsupported transformation ordering");
  57. else if (InterleaveCount.getValueOr(0) != 1)
  58. ORE->emit(
  59. DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
  60. "FailedRequestedInterleaving",
  61. L->getStartLoc(), L->getHeader())
  62. << "loop not interleaved: the optimizer was unable to perform the "
  63. "requested transformation; the transformation might be disabled "
  64. "or specified as part of an unsupported transformation ordering");
  65. }
  66. if (hasDistributeTransformation(L) == TM_ForcedByUser) {
  67. LLVM_DEBUG(dbgs() << "Leftover distribute transformation\n");
  68. ORE->emit(
  69. DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
  70. "FailedRequestedDistribution",
  71. L->getStartLoc(), L->getHeader())
  72. << "loop not distributed: the optimizer was unable to perform the "
  73. "requested transformation; the transformation might be disabled or "
  74. "specified as part of an unsupported transformation ordering");
  75. }
  76. }
  77. static void warnAboutLeftoverTransformations(Function *F, LoopInfo *LI,
  78. OptimizationRemarkEmitter *ORE) {
  79. for (auto *L : LI->getLoopsInPreorder())
  80. warnAboutLeftoverTransformations(L, ORE);
  81. }
  82. // New pass manager boilerplate
  83. PreservedAnalyses
  84. WarnMissedTransformationsPass::run(Function &F, FunctionAnalysisManager &AM) {
  85. // Do not warn about not applied transformations if optimizations are
  86. // disabled.
  87. if (F.hasOptNone())
  88. return PreservedAnalyses::all();
  89. auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
  90. auto &LI = AM.getResult<LoopAnalysis>(F);
  91. warnAboutLeftoverTransformations(&F, &LI, &ORE);
  92. return PreservedAnalyses::all();
  93. }
  94. // Legacy pass manager boilerplate
  95. namespace {
  96. class WarnMissedTransformationsLegacy : public FunctionPass {
  97. public:
  98. static char ID;
  99. explicit WarnMissedTransformationsLegacy() : FunctionPass(ID) {
  100. initializeWarnMissedTransformationsLegacyPass(
  101. *PassRegistry::getPassRegistry());
  102. }
  103. bool runOnFunction(Function &F) override {
  104. if (skipFunction(F))
  105. return false;
  106. auto &ORE = getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
  107. auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
  108. warnAboutLeftoverTransformations(&F, &LI, &ORE);
  109. return false;
  110. }
  111. void getAnalysisUsage(AnalysisUsage &AU) const override {
  112. AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
  113. AU.addRequired<LoopInfoWrapperPass>();
  114. AU.setPreservesAll();
  115. }
  116. };
  117. } // end anonymous namespace
  118. char WarnMissedTransformationsLegacy::ID = 0;
  119. INITIALIZE_PASS_BEGIN(WarnMissedTransformationsLegacy, "transform-warning",
  120. "Warn about non-applied transformations", false, false)
  121. INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
  122. INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
  123. INITIALIZE_PASS_END(WarnMissedTransformationsLegacy, "transform-warning",
  124. "Warn about non-applied transformations", false, false)
  125. Pass *llvm::createWarnMissedTransformationsPass() {
  126. return new WarnMissedTransformationsLegacy();
  127. }