Index: llvm/include/llvm/Transforms/Scalar/LoopRotation.h =================================================================== --- llvm/include/llvm/Transforms/Scalar/LoopRotation.h +++ llvm/include/llvm/Transforms/Scalar/LoopRotation.h @@ -28,6 +28,9 @@ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U); + void printPipeline(raw_ostream &OS, + function_ref MapClassName2PassName); + private: const bool EnableHeaderDuplication; const bool PrepareForLTO; Index: llvm/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/lib/Passes/PassBuilder.cpp +++ llvm/lib/Passes/PassBuilder.cpp @@ -897,6 +897,26 @@ return Result; } +Expected> parseLoopRotateOptions(StringRef Params) { + std::pair Result = {true, false}; + while (!Params.empty()) { + StringRef ParamName; + std::tie(ParamName, Params) = Params.split(';'); + + bool Enable = !ParamName.consume_front("no-"); + if (ParamName == "header-duplication") { + Result.first = Enable; + } else if (ParamName == "prepare-for-lto") { + Result.second = Enable; + } else { + return make_error( + formatv("invalid LoopRotate pass parameter '{0}' ", ParamName).str(), + inconvertibleErrorCode()); + } + } + return Result; +} + Expected parseMergedLoadStoreMotionOptions(StringRef Params) { bool Result = false; while (!Params.empty()) { Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -565,7 +565,6 @@ LOOP_PASS("invalidate", InvalidateAllAnalysesPass()) LOOP_PASS("loop-idiom", LoopIdiomRecognizePass()) LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass()) -LOOP_PASS("loop-rotate", LoopRotatePass()) LOOP_PASS("no-op-loop", NoOpLoopPass()) LOOP_PASS("print", PrintLoopPass(dbgs())) LOOP_PASS("loop-deletion", LoopDeletionPass()) @@ -608,4 +607,12 @@ }, parseLICMOptions, "allowspeculation"); + +LOOP_PASS_WITH_PARAMS("loop-rotate", + "LoopRotatePass", + [](std::pair Params) { + return LoopRotatePass(Params.first, Params.second); + }, + parseLoopRotateOptions, + "no-header-duplication;header-duplication;no-prepare-for-lto;prepare-for-lto") #undef LOOP_PASS_WITH_PARAMS Index: llvm/lib/Transforms/Scalar/LoopRotation.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LoopRotation.cpp +++ llvm/lib/Transforms/Scalar/LoopRotation.cpp @@ -43,6 +43,21 @@ : EnableHeaderDuplication(EnableHeaderDuplication), PrepareForLTO(PrepareForLTO) {} +void LoopRotatePass::printPipeline( + raw_ostream &OS, function_ref MapClassName2PassName) { + static_cast *>(this)->printPipeline( + OS, MapClassName2PassName); + OS << "<"; + if (!EnableHeaderDuplication) + OS << "no-"; + OS << "header-duplication;"; + + if (!PrepareForLTO) + OS << "no-"; + OS << "prepare-for-lto"; + OS << ">"; +} + PreservedAnalyses LoopRotatePass::run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &) { Index: llvm/test/Other/new-pm-print-pipeline.ll =================================================================== --- llvm/test/Other/new-pm-print-pipeline.ll +++ llvm/test/Other/new-pm-print-pipeline.ll @@ -4,7 +4,7 @@ ; CHECK-0: function(adce),function(adce) ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='module(rpo-function-attrs,require,function(float2int,lower-constant-intrinsics,loop(loop-rotate)),invalidate)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-1 -; CHECK-1: rpo-function-attrs,require,function(float2int,lower-constant-intrinsics,loop(loop-rotate)),invalidate +; CHECK-1: rpo-function-attrs,require,function(float2int,lower-constant-intrinsics,loop(loop-rotate)),invalidate ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='repeat<5>(function(mem2reg)),invalidate' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-2 ; CHECK-2: repeat<5>(function(mem2reg)),invalidate @@ -69,7 +69,7 @@ ;; Test that the loop-nest-pass lnicm is printed with the other loop-passes in the pipeline. ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-mssa(licm,loop-rotate,loop-deletion,lnicm,loop-rotate))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-23 -; CHECK-23: function(loop-mssa(licm,loop-rotate,loop-deletion,lnicm,loop-rotate)) +; CHECK-23: function(loop-mssa(licm,loop-rotate,loop-deletion,lnicm,loop-rotate)) ;; Test that -debugify and -check-debugify is printed correctly. ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='debugify,no-op-function,check-debugify' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-24 @@ -111,3 +111,6 @@ ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='cgscc(function(no-op-function))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-32 ; CHECK-32: cgscc(function(no-op-function)) + +; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop(loop-rotate))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-33 +; CHECK-33: function(loop(loop-rotate))