Index: llvm/include/llvm/Transforms/Scalar/LICM.h =================================================================== --- llvm/include/llvm/Transforms/Scalar/LICM.h +++ llvm/include/llvm/Transforms/Scalar/LICM.h @@ -57,6 +57,22 @@ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U); }; + +/// Performs LoopNest Invariant Code Motion Pass. +class LNICMPass : public PassInfoMixin { + unsigned LicmMssaOptCap; + unsigned LicmMssaNoAccForPromotionCap; + +public: + LNICMPass() + : LicmMssaOptCap(SetLicmMssaOptCap), + LicmMssaNoAccForPromotionCap(SetLicmMssaNoAccForPromotionCap) {} + LNICMPass(unsigned LicmMssaOptCap, unsigned LicmMssaNoAccForPromotionCap) + : LicmMssaOptCap(LicmMssaOptCap), + LicmMssaNoAccForPromotionCap(LicmMssaNoAccForPromotionCap) {} + PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, LPMUpdater &U); +}; } // end namespace llvm #endif // LLVM_TRANSFORMS_SCALAR_LICM_H Index: llvm/lib/Passes/PassRegistry.def =================================================================== --- llvm/lib/Passes/PassRegistry.def +++ llvm/lib/Passes/PassRegistry.def @@ -388,6 +388,7 @@ LOOP_PASS("dot-ddg", DDGDotPrinterPass()) LOOP_PASS("invalidate", InvalidateAllAnalysesPass()) LOOP_PASS("licm", LICMPass()) +LOOP_PASS("lnicm", LNICMPass()) LOOP_PASS("loop-flatten", LoopFlattenPass()) LOOP_PASS("loop-idiom", LoopIdiomRecognizePass()) LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass()) Index: llvm/lib/Transforms/Scalar/LICM.cpp =================================================================== --- llvm/lib/Transforms/Scalar/LICM.cpp +++ llvm/lib/Transforms/Scalar/LICM.cpp @@ -295,6 +295,40 @@ return PA; } +PreservedAnalyses LNICMPass::run(LoopNest &LN, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, + LPMUpdater &) { + // For the new PM, we also can't use OptimizationRemarkEmitter as an analysis + // pass. Function analyses need to be preserved across loop transformations + // but ORE cannot be preserved (see comment before the pass definition). + OptimizationRemarkEmitter ORE(LN.getParent()); + + LoopInvariantCodeMotion LICM(LicmMssaOptCap, LicmMssaNoAccForPromotionCap); + + ArrayRef Loops = LN.getLoops(); + SmallPriorityWorklist Worklist; + appendLoopsToWorklist(Loops, Worklist); + bool Changed = false; + + while (!Worklist.empty()) { + Loop *L = Worklist.pop_back_val(); + Changed |= LICM.runOnLoop(L, &AR.AA, &AR.LI, &AR.DT, AR.BFI, &AR.TLI, + &AR.TTI, &AR.SE, AR.MSSA, &ORE); + } + + if (!Changed) + return PreservedAnalyses::all(); + + auto PA = getLoopPassPreservedAnalyses(); + + PA.preserve(); + PA.preserve(); + if (AR.MSSA) + PA.preserve(); + + return PA; +} + char LegacyLICMPass::ID = 0; INITIALIZE_PASS_BEGIN(LegacyLICMPass, "licm", "Loop Invariant Code Motion", false, false) Index: llvm/test/Transforms/LICM/call-hoisting.ll =================================================================== --- llvm/test/Transforms/LICM/call-hoisting.ll +++ llvm/test/Transforms/LICM/call-hoisting.ll @@ -1,5 +1,6 @@ ; RUN: opt -S -basic-aa -licm %s | FileCheck %s ; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop(licm)' < %s -S | FileCheck %s +; RUN: opt -aa-pipeline=basic-aa -passes='require,require,require,require,loop(lnicm)' < %s -S | FileCheck %s declare i32 @load(i32* %p) argmemonly readonly nounwind Index: llvm/test/Transforms/LICM/hoist-deref-load.ll =================================================================== --- llvm/test/Transforms/LICM/hoist-deref-load.ll +++ llvm/test/Transforms/LICM/hoist-deref-load.ll @@ -1,8 +1,10 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -basic-aa -licm < %s | FileCheck %s ; RUN: opt -aa-pipeline=basic-aa -passes='require,loop(loop-simplifycfg,licm)' -S < %s | FileCheck %s +; RUN: opt -aa-pipeline=basic-aa -passes='require,loop(loop-simplifycfg,lnicm)' -S < %s | FileCheck %s ; RUN: opt -S -basic-aa -licm -enable-mssa-loop-dependency=true -verify-memoryssa < %s | FileCheck %s ; RUN: opt -aa-pipeline=basic-aa -passes='require,loop-mssa(loop-simplifycfg,licm)' -verify-memoryssa -S < %s | FileCheck %s +; RUN: opt -aa-pipeline=basic-aa -passes='require,loop-mssa(loop-simplifycfg,lnicm)' -verify-memoryssa -S < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu"