How to write a Loop pass using new pass manager

Hi
Thanking you in advance.I am a beginner trying to implement a loop pass using new pass manager [using LLVM 16].The following is the code skeleton I wrote.Actually I want to modify the code inside the loop and return that.We have chosen out of source tree implementation.
$LLVM/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp

namespace {

struct LoopHandle : public PassInfoMixin<LoopHandle> {

  // The first argument of the run() function defines on what level
  // of granularity your pass will run (e.g. Module, Function).
  // The second argument is the corresponding AnalysisManager
  // (e.g ModuleAnalysisManager, FunctionAnalysisManager)
  
  PreservedAnalyses run(Loop &L, LoopAnalysisManager &LAM) {
  }
	PreservedAnalyses LoopHandle::run(Loop *L, LoopAnalysisManager &LAM,LoopStandardAnalysisResults &LSAR) {
   std::cout << "MyPass in loop: "  << std::endl;
     return PreservedAnalyses::all();
}


};

}


// This part is the new way of registering your pass
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
  return {
    LLVM_PLUGIN_API_VERSION, "LoopHandle", "v0.1",
    [](PassBuilder &PB) {
      PB.registerPipelineParsingCallback(
        [](StringRef Name, FunctionPassManager &FPM,
        ArrayRef<PassBuilder::PipelineElement>) {
          if(Name == "loop-handle"){
            FPM.addPass(LoopHandle());
            return true;
          }
          return false;
        }
      );
    }
  };
}

$LLVM/llvm/lib/Transforms/LoopHandle/CMakeLists.txt

add_llvm_library( LoopHandle MODULE
    LoopHandle.cpp

    PLUGIN_TOOL
    opt
)

I got the following error.

FAILED: lib/Transforms/LoopHandle/CMakeFiles/LoopHandle.dir/LoopHandle.cpp.o 
/usr/bin/c++  -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib/Transforms/LoopHandle -I/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle -Iinclude -I/home/cpslab/Documents/llvm-14-origin/llvm/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wsuggest-override -Wno-comment -Wno-misleading-indentation -fdiagnostics-color -g -fPIC    -fno-exceptions -fno-rtti -std=c++17 -MD -MT lib/Transforms/LoopHandle/CMakeFiles/LoopHandle.dir/LoopHandle.cpp.o -MF lib/Transforms/LoopHandle/CMakeFiles/LoopHandle.dir/LoopHandle.cpp.o.d -o lib/Transforms/LoopHandle/CMakeFiles/LoopHandle.dir/LoopHandle.cpp.o -c /home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp
/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp:42:20: error: extra qualification ‘{anonymous}::LoopHandle::’ on member ‘run’ [-fpermissive]
   42 |  PreservedAnalyses LoopHandle::run(Loop *L, LoopAnalysisManager &LAM,LoopStandardAnalysisResults &LSAR) {
      |                    ^~~~~~~~~~
/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp: In member function ‘llvm::PreservedAnalyses {anonymous}::LoopHandle::run(llvm::Loop&, llvm::LoopAnalysisManager&)’:
/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp:41:3: warning: no return statement in function returning non-void [-Wreturn-type]
   41 |   }
      |   ^
In file included from /home/cpslab/Documents/llvm-14-origin/llvm/include/llvm/IR/PassManager.h:48,
                 from /home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp:1:
/home/cpslab/Documents/llvm-14-origin/llvm/include/llvm/IR/PassManagerInternal.h: In instantiation of ‘PreservedAnalysesT llvm::detail::PassModel<IRUnitT, PassT, PreservedAnalysesT, AnalysisManagerT, ExtraArgTs>::run(IRUnitT&, AnalysisManagerT&, ExtraArgTs ...) [with IRUnitT = llvm::Function; PassT = {anonymous}::LoopHandle; PreservedAnalysesT = llvm::PreservedAnalyses; AnalysisManagerT = llvm::AnalysisManager<llvm::Function>; ExtraArgTs = {}]’:
/home/cpslab/Documents/llvm-14-origin/llvm/include/llvm/IR/PassManagerInternal.h:87:22:   required from here
/home/cpslab/Documents/llvm-14-origin/llvm/include/llvm/IR/PassManagerInternal.h:89:41: error: no matching function for call to ‘{anonymous}::LoopHandle::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&)’
   89 |     return Pass.run(IR, AM, ExtraArgs...);
      |                                         ^
/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp:40:21: note: candidate: ‘llvm::PreservedAnalyses {anonymous}::LoopHandle::run(llvm::Loop&, llvm::LoopAnalysisManager&)’
   40 |   PreservedAnalyses run(Loop &L, LoopAnalysisManager &LAM) {
      |                     ^~~
/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp:40:31: note:   no known conversion for argument 1 from ‘llvm::Function’ to ‘llvm::Loop&’
   40 |   PreservedAnalyses run(Loop &L, LoopAnalysisManager &LAM) {
      |                         ~~~~~~^
/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp:42:20: note: candidate: ‘llvm::PreservedAnalyses {anonymous}::LoopHandle::run(llvm::Loop*, llvm::LoopAnalysisManager&, llvm::LoopStandardAnalysisResults&)’
   42 |  PreservedAnalyses LoopHandle::run(Loop *L, LoopAnalysisManager &LAM,LoopStandardAnalysisResults &LSAR) {
      |                    ^~~~~~~~~~
/home/cpslab/Documents/llvm-14-origin/llvm/lib/Transforms/LoopHandle/LoopHandle.cpp:42:20: note:   candidate expects 3 arguments, 2 provided
ninja: build stopped: subcommand failed.

How can I get the new pass manager implementation out of source tree implementation for a loop pass?
Please suggest correction to modify this to return new .ll file.

The signature of run on loops is actually

PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U);

See some loop passes such as LoopRotatePass or LoopUnrollAndJamPass for details.

Also, the chosen overload of registerPipelineParsingCallback is for function passes. Try this one for loop passes:

void registerPipelineParsingCallback(
      const std::function<bool(StringRef Name, LoopPassManager &,
                               ArrayRef<PipelineElement>)> &C)

(ie. LoopPassManager instead of FunctionPassManager; unlike the legacy pass manager, with the NPM you cannot (directly) add a loop pass to a FunctionPassManager).

1 Like

I tried using these three arguments and got error like 2 out of 4 arguments are missing for run().
Can I use runOnFunction or runOnLoop() in new pass manager ?(I tried this but that too showed the following error)Could you suggest a rightway to use…My aim is to add a new basic block.

outside class definition

Or
can I lower down to loop from run(Function &F,…)?
Please correct me.