[LoopInterchange][NewPM] Port -loop-interchange to NPM

Reviewed By: fhahn

Differential Revision: https://reviews.llvm.org/D89058
This commit is contained in:
Arthur Eubanks 2020-09-17 16:19:04 -07:00
parent 1dfbc2ea14
commit 9c21c6c966
7 changed files with 83 additions and 27 deletions

View File

@ -241,7 +241,7 @@ void initializeLoopFuseLegacyPass(PassRegistry&);
void initializeLoopIdiomRecognizeLegacyPassPass(PassRegistry&); void initializeLoopIdiomRecognizeLegacyPassPass(PassRegistry&);
void initializeLoopInfoWrapperPassPass(PassRegistry&); void initializeLoopInfoWrapperPassPass(PassRegistry&);
void initializeLoopInstSimplifyLegacyPassPass(PassRegistry&); void initializeLoopInstSimplifyLegacyPassPass(PassRegistry&);
void initializeLoopInterchangePass(PassRegistry&); void initializeLoopInterchangeLegacyPassPass(PassRegistry &);
void initializeLoopFlattenLegacyPassPass(PassRegistry&); void initializeLoopFlattenLegacyPassPass(PassRegistry&);
void initializeLoopLoadEliminationPass(PassRegistry&); void initializeLoopLoadEliminationPass(PassRegistry&);
void initializeLoopPassPass(PassRegistry&); void initializeLoopPassPass(PassRegistry&);

View File

@ -0,0 +1,24 @@
//===- LoopInterchange.h - Loop interchange pass --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
#define LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H
#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
struct LoopInterchangePass : public PassInfoMixin<LoopInterchangePass> {
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR, LPMUpdater &U);
};
} // end namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPINTERCHANGE_H

View File

@ -154,6 +154,7 @@
#include "llvm/Transforms/Scalar/LoopFuse.h" #include "llvm/Transforms/Scalar/LoopFuse.h"
#include "llvm/Transforms/Scalar/LoopIdiomRecognize.h" #include "llvm/Transforms/Scalar/LoopIdiomRecognize.h"
#include "llvm/Transforms/Scalar/LoopInstSimplify.h" #include "llvm/Transforms/Scalar/LoopInstSimplify.h"
#include "llvm/Transforms/Scalar/LoopInterchange.h"
#include "llvm/Transforms/Scalar/LoopLoadElimination.h" #include "llvm/Transforms/Scalar/LoopLoadElimination.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Scalar/LoopPredication.h" #include "llvm/Transforms/Scalar/LoopPredication.h"

View File

@ -358,6 +358,7 @@ LOOP_PASS("invalidate<all>", InvalidateAllAnalysesPass())
LOOP_PASS("licm", LICMPass()) LOOP_PASS("licm", LICMPass())
LOOP_PASS("loop-idiom", LoopIdiomRecognizePass()) LOOP_PASS("loop-idiom", LoopIdiomRecognizePass())
LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass()) LOOP_PASS("loop-instsimplify", LoopInstSimplifyPass())
LOOP_PASS("loop-interchange", LoopInterchangePass())
LOOP_PASS("loop-rotate", LoopRotatePass()) LOOP_PASS("loop-rotate", LoopRotatePass())
LOOP_PASS("no-op-loop", NoOpLoopPass()) LOOP_PASS("no-op-loop", NoOpLoopPass())
LOOP_PASS("print", PrintLoopPass(dbgs())) LOOP_PASS("print", PrintLoopPass(dbgs()))

View File

@ -12,6 +12,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar/LoopInterchange.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
@ -428,9 +429,7 @@ private:
const LoopInterchangeLegality &LIL; const LoopInterchangeLegality &LIL;
}; };
// Main LoopInterchange Pass. struct LoopInterchange {
struct LoopInterchange : public LoopPass {
static char ID;
ScalarEvolution *SE = nullptr; ScalarEvolution *SE = nullptr;
LoopInfo *LI = nullptr; LoopInfo *LI = nullptr;
DependenceInfo *DI = nullptr; DependenceInfo *DI = nullptr;
@ -439,27 +438,14 @@ struct LoopInterchange : public LoopPass {
/// Interface to emit optimization remarks. /// Interface to emit optimization remarks.
OptimizationRemarkEmitter *ORE; OptimizationRemarkEmitter *ORE;
LoopInterchange() : LoopPass(ID) { LoopInterchange(ScalarEvolution *SE, LoopInfo *LI, DependenceInfo *DI,
initializeLoopInterchangePass(*PassRegistry::getPassRegistry()); DominatorTree *DT, OptimizationRemarkEmitter *ORE)
} : SE(SE), LI(LI), DI(DI), DT(DT), ORE(ORE) {}
void getAnalysisUsage(AnalysisUsage &AU) const override { bool run(Loop *L) {
AU.addRequired<DependenceAnalysisWrapperPass>(); if (L->getParentLoop())
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
getLoopAnalysisUsage(AU);
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
if (skipLoop(L) || L->getParentLoop())
return false; return false;
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
DI = &getAnalysis<DependenceAnalysisWrapperPass>().getDI();
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
return processLoopList(populateWorklist(*L)); return processLoopList(populateWorklist(*L));
} }
@ -1645,15 +1631,58 @@ bool LoopInterchangeTransform::adjustLoopLinks() {
return Changed; return Changed;
} }
char LoopInterchange::ID = 0; /// Main LoopInterchange Pass.
struct LoopInterchangeLegacyPass : public LoopPass {
static char ID;
INITIALIZE_PASS_BEGIN(LoopInterchange, "loop-interchange", LoopInterchangeLegacyPass() : LoopPass(ID) {
initializeLoopInterchangeLegacyPassPass(*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<DependenceAnalysisWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
getLoopAnalysisUsage(AU);
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override {
if (skipLoop(L))
return false;
auto *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
auto *DI = &getAnalysis<DependenceAnalysisWrapperPass>().getDI();
auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto *ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
return LoopInterchange(SE, LI, DI, DT, ORE).run(L);
}
};
char LoopInterchangeLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(LoopInterchangeLegacyPass, "loop-interchange",
"Interchanges loops for cache reuse", false, false) "Interchanges loops for cache reuse", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopPass) INITIALIZE_PASS_DEPENDENCY(LoopPass)
INITIALIZE_PASS_DEPENDENCY(DependenceAnalysisWrapperPass) INITIALIZE_PASS_DEPENDENCY(DependenceAnalysisWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass) INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
INITIALIZE_PASS_END(LoopInterchange, "loop-interchange", INITIALIZE_PASS_END(LoopInterchangeLegacyPass, "loop-interchange",
"Interchanges loops for cache reuse", false, false) "Interchanges loops for cache reuse", false, false)
Pass *llvm::createLoopInterchangePass() { return new LoopInterchange(); } Pass *llvm::createLoopInterchangePass() {
return new LoopInterchangeLegacyPass();
}
PreservedAnalyses LoopInterchangePass::run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &AR,
LPMUpdater &U) {
Function &F = *L.getHeader()->getParent();
DependenceInfo DI(&F, &AR.AA, &AR.SE, &AR.LI);
OptimizationRemarkEmitter ORE(&F);
if (!LoopInterchange(&AR.SE, &AR.LI, &DI, &AR.DT, &ORE).run(&L))
return PreservedAnalyses::all();
return getLoopPassPreservedAnalyses();
}

View File

@ -66,7 +66,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeLoopDeletionLegacyPassPass(Registry); initializeLoopDeletionLegacyPassPass(Registry);
initializeLoopAccessLegacyAnalysisPass(Registry); initializeLoopAccessLegacyAnalysisPass(Registry);
initializeLoopInstSimplifyLegacyPassPass(Registry); initializeLoopInstSimplifyLegacyPassPass(Registry);
initializeLoopInterchangePass(Registry); initializeLoopInterchangeLegacyPassPass(Registry);
initializeLoopFlattenLegacyPassPass(Registry); initializeLoopFlattenLegacyPassPass(Registry);
initializeLoopPredicationLegacyPassPass(Registry); initializeLoopPredicationLegacyPassPass(Registry);
initializeLoopRotateLegacyPassPass(Registry); initializeLoopRotateLegacyPassPass(Registry);

View File

@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -basic-aa -loop-interchange -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s ; RUN: opt < %s -basic-aa -loop-interchange -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s
; RUN: opt < %s -aa-pipeline=basic-aa -passes=loop-interchange -verify-dom-info -verify-loop-info -verify-scev -verify-loop-lcssa -S | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu" target triple = "x86_64-unknown-linux-gnu"