xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/Scalar/WarnMissedTransforms.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===- LoopTransformWarning.cpp -  ----------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // Emit warnings if forced code transformations have not been performed.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/WarnMissedTransforms.h"
145ffd83dbSDimitry Andric #include "llvm/Analysis/LoopInfo.h"
150b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h"
160b57cec5SDimitry Andric #include "llvm/Transforms/Utils/LoopUtils.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #define DEBUG_TYPE "transform-warning"
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric /// Emit warnings for forced (i.e. user-defined) loop transformations which have
230b57cec5SDimitry Andric /// still not been performed.
warnAboutLeftoverTransformations(Loop * L,OptimizationRemarkEmitter * ORE)240b57cec5SDimitry Andric static void warnAboutLeftoverTransformations(Loop *L,
250b57cec5SDimitry Andric                                              OptimizationRemarkEmitter *ORE) {
260b57cec5SDimitry Andric   if (hasUnrollTransformation(L) == TM_ForcedByUser) {
270b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Leftover unroll transformation\n");
280b57cec5SDimitry Andric     ORE->emit(
290b57cec5SDimitry Andric         DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
300b57cec5SDimitry Andric                                           "FailedRequestedUnrolling",
310b57cec5SDimitry Andric                                           L->getStartLoc(), L->getHeader())
320b57cec5SDimitry Andric         << "loop not unrolled: the optimizer was unable to perform the "
330b57cec5SDimitry Andric            "requested transformation; the transformation might be disabled or "
340b57cec5SDimitry Andric            "specified as part of an unsupported transformation ordering");
350b57cec5SDimitry Andric   }
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric   if (hasUnrollAndJamTransformation(L) == TM_ForcedByUser) {
380b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Leftover unroll-and-jam transformation\n");
390b57cec5SDimitry Andric     ORE->emit(
400b57cec5SDimitry Andric         DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
410b57cec5SDimitry Andric                                           "FailedRequestedUnrollAndJamming",
420b57cec5SDimitry Andric                                           L->getStartLoc(), L->getHeader())
430b57cec5SDimitry Andric         << "loop not unroll-and-jammed: the optimizer was unable to perform "
440b57cec5SDimitry Andric            "the requested transformation; the transformation might be disabled "
450b57cec5SDimitry Andric            "or specified as part of an unsupported transformation ordering");
460b57cec5SDimitry Andric   }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   if (hasVectorizeTransformation(L) == TM_ForcedByUser) {
490b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Leftover vectorization transformation\n");
50*bdd1243dSDimitry Andric     std::optional<ElementCount> VectorizeWidth =
51e8d8bef9SDimitry Andric         getOptionalElementCountLoopAttribute(L);
52*bdd1243dSDimitry Andric     std::optional<int> InterleaveCount =
530b57cec5SDimitry Andric         getOptionalIntLoopAttribute(L, "llvm.loop.interleave.count");
540b57cec5SDimitry Andric 
55e8d8bef9SDimitry Andric     if (!VectorizeWidth || VectorizeWidth->isVector())
560b57cec5SDimitry Andric       ORE->emit(
570b57cec5SDimitry Andric           DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
580b57cec5SDimitry Andric                                             "FailedRequestedVectorization",
590b57cec5SDimitry Andric                                             L->getStartLoc(), L->getHeader())
600b57cec5SDimitry Andric           << "loop not vectorized: the optimizer was unable to perform the "
610b57cec5SDimitry Andric              "requested transformation; the transformation might be disabled "
620b57cec5SDimitry Andric              "or specified as part of an unsupported transformation ordering");
6381ad6265SDimitry Andric     else if (InterleaveCount.value_or(0) != 1)
640b57cec5SDimitry Andric       ORE->emit(
650b57cec5SDimitry Andric           DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
660b57cec5SDimitry Andric                                             "FailedRequestedInterleaving",
670b57cec5SDimitry Andric                                             L->getStartLoc(), L->getHeader())
680b57cec5SDimitry Andric           << "loop not interleaved: the optimizer was unable to perform the "
690b57cec5SDimitry Andric              "requested transformation; the transformation might be disabled "
700b57cec5SDimitry Andric              "or specified as part of an unsupported transformation ordering");
710b57cec5SDimitry Andric   }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   if (hasDistributeTransformation(L) == TM_ForcedByUser) {
740b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Leftover distribute transformation\n");
750b57cec5SDimitry Andric     ORE->emit(
760b57cec5SDimitry Andric         DiagnosticInfoOptimizationFailure(DEBUG_TYPE,
770b57cec5SDimitry Andric                                           "FailedRequestedDistribution",
780b57cec5SDimitry Andric                                           L->getStartLoc(), L->getHeader())
790b57cec5SDimitry Andric         << "loop not distributed: the optimizer was unable to perform the "
800b57cec5SDimitry Andric            "requested transformation; the transformation might be disabled or "
810b57cec5SDimitry Andric            "specified as part of an unsupported transformation ordering");
820b57cec5SDimitry Andric   }
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric 
warnAboutLeftoverTransformations(Function * F,LoopInfo * LI,OptimizationRemarkEmitter * ORE)850b57cec5SDimitry Andric static void warnAboutLeftoverTransformations(Function *F, LoopInfo *LI,
860b57cec5SDimitry Andric                                              OptimizationRemarkEmitter *ORE) {
870b57cec5SDimitry Andric   for (auto *L : LI->getLoopsInPreorder())
880b57cec5SDimitry Andric     warnAboutLeftoverTransformations(L, ORE);
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric // New pass manager boilerplate
920b57cec5SDimitry Andric PreservedAnalyses
run(Function & F,FunctionAnalysisManager & AM)930b57cec5SDimitry Andric WarnMissedTransformationsPass::run(Function &F, FunctionAnalysisManager &AM) {
940b57cec5SDimitry Andric   // Do not warn about not applied transformations if optimizations are
950b57cec5SDimitry Andric   // disabled.
960b57cec5SDimitry Andric   if (F.hasOptNone())
970b57cec5SDimitry Andric     return PreservedAnalyses::all();
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
1000b57cec5SDimitry Andric   auto &LI = AM.getResult<LoopAnalysis>(F);
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   warnAboutLeftoverTransformations(&F, &LI, &ORE);
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   return PreservedAnalyses::all();
1050b57cec5SDimitry Andric }
106