1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[NPM] Port -loop-versioning-licm to NPM

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D89371
This commit is contained in:
TaWeiTu 2020-10-24 21:50:33 +08:00
parent 56002e0053
commit 39d46368c8
11 changed files with 107 additions and 30 deletions

View File

@ -255,7 +255,7 @@ void initializeLoopUnrollAndJamPass(PassRegistry&);
void initializeLoopUnrollPass(PassRegistry&);
void initializeLoopUnswitchPass(PassRegistry&);
void initializeLoopVectorizePass(PassRegistry&);
void initializeLoopVersioningLICMPass(PassRegistry&);
void initializeLoopVersioningLICMLegacyPassPass(PassRegistry &);
void initializeLoopVersioningLegacyPassPass(PassRegistry &);
void initializeLowerAtomicLegacyPassPass(PassRegistry&);
void initializeLowerConstantIntrinsicsPass(PassRegistry&);

View File

@ -0,0 +1,25 @@
//===- LoopVersioningLICM.h - LICM Loop Versioning ------------------------===//
//
// 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_LOOPVERSIONINGLICM_H
#define LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H
#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
class LoopVersioningLICMPass : public PassInfoMixin<LoopVersioningLICMPass> {
public:
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &LAR, LPMUpdater &U);
};
} // namespace llvm
#endif // LLVM_TRANSFORMS_SCALAR_LOOPVERSIONINGLICM_H

View File

@ -168,6 +168,7 @@
#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
#include "llvm/Transforms/Scalar/LoopUnrollAndJamPass.h"
#include "llvm/Transforms/Scalar/LoopUnrollPass.h"
#include "llvm/Transforms/Scalar/LoopVersioningLICM.h"
#include "llvm/Transforms/Scalar/LowerAtomic.h"
#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"
#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"

View File

@ -386,6 +386,7 @@ LOOP_PASS("loop-predication", LoopPredicationPass())
LOOP_PASS("guard-widening", GuardWideningPass())
LOOP_PASS("simple-loop-unswitch", SimpleLoopUnswitchPass())
LOOP_PASS("loop-reroll", LoopRerollPass())
LOOP_PASS("loop-versioning-licm", LoopVersioningLICMPass())
#undef LOOP_PASS
#ifndef LOOP_PASS_WITH_PARAMS

View File

@ -59,6 +59,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Scalar/LoopVersioningLICM.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h"
@ -114,17 +115,18 @@ static cl::opt<unsigned> LVLoopDepthThreshold(
namespace {
struct LoopVersioningLICM : public LoopPass {
struct LoopVersioningLICMLegacyPass : public LoopPass {
static char ID;
LoopVersioningLICM()
: LoopPass(ID), LoopDepthThreshold(LVLoopDepthThreshold),
InvariantThreshold(LVInvarThreshold) {
initializeLoopVersioningLICMPass(*PassRegistry::getPassRegistry());
LoopVersioningLICMLegacyPass() : LoopPass(ID) {
initializeLoopVersioningLICMLegacyPassPass(
*PassRegistry::getPassRegistry());
}
bool runOnLoop(Loop *L, LPPassManager &LPM) override;
StringRef getPassName() const override { return "Loop Versioning for LICM"; }
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesCFG();
AU.addRequired<AAResultsWrapperPass>();
@ -138,13 +140,25 @@ struct LoopVersioningLICM : public LoopPass {
AU.addPreserved<GlobalsAAWrapperPass>();
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
}
};
StringRef getPassName() const override { return "Loop Versioning for LICM"; }
struct LoopVersioningLICM {
// We don't explicitly pass in LoopAccessInfo to the constructor since the
// loop versioning might return early due to instructions that are not safe
// for versioning. By passing the proxy instead the construction of
// LoopAccessInfo will take place only when it's necessary.
LoopVersioningLICM(AliasAnalysis *AA, ScalarEvolution *SE,
OptimizationRemarkEmitter *ORE,
function_ref<const LoopAccessInfo &(Loop *)> GetLAI)
: AA(AA), SE(SE), GetLAI(GetLAI),
LoopDepthThreshold(LVLoopDepthThreshold),
InvariantThreshold(LVInvarThreshold), ORE(ORE) {}
bool runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT);
void reset() {
AA = nullptr;
SE = nullptr;
LAA = nullptr;
CurLoop = nullptr;
LoadAndStoreCounter = 0;
InvariantCounter = 0;
@ -169,12 +183,12 @@ private:
// Current ScalarEvolution
ScalarEvolution *SE = nullptr;
// Current LoopAccessAnalysis
LoopAccessLegacyAnalysis *LAA = nullptr;
// Current Loop's LoopAccessInfo
const LoopAccessInfo *LAI = nullptr;
// Proxy for retrieving LoopAccessInfo.
function_ref<const LoopAccessInfo &(Loop *)> GetLAI;
// The current loop we are working on.
Loop *CurLoop = nullptr;
@ -400,8 +414,8 @@ bool LoopVersioningLICM::legalLoopInstructions() {
return false;
}
}
// Get LoopAccessInfo from current loop.
LAI = &LAA->getInfo(CurLoop);
// Get LoopAccessInfo from current loop via the proxy.
LAI = &GetLAI(CurLoop);
// Check LoopAccessInfo for need of runtime check.
if (LAI->getRuntimePointerChecking()->getChecks().empty()) {
LLVM_DEBUG(dbgs() << " LAA: Runtime check not found !!\n");
@ -562,30 +576,38 @@ void LoopVersioningLICM::setNoAliasToLoop(Loop *VerLoop) {
}
}
bool LoopVersioningLICM::runOnLoop(Loop *L, LPPassManager &LPM) {
bool LoopVersioningLICMLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
if (skipLoop(L))
return false;
AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
ScalarEvolution *SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
OptimizationRemarkEmitter *ORE =
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto GetLAI = [&](Loop *L) -> const LoopAccessInfo & {
return getAnalysis<LoopAccessLegacyAnalysis>().getInfo(L);
};
return LoopVersioningLICM(AA, SE, ORE, GetLAI).runOnLoop(L, LI, DT);
}
bool LoopVersioningLICM::runOnLoop(Loop *L, LoopInfo *LI, DominatorTree *DT) {
// This will automatically release all resources hold by the current
// LoopVersioningLICM object.
AutoResetter Resetter(*this);
if (skipLoop(L))
return false;
// Do not do the transformation if disabled by metadata.
if (hasLICMVersioningTransformation(L) & TM_Disable)
return false;
// Get Analysis information.
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
LAI = nullptr;
// Set Current Loop
CurLoop = L;
CurAST.reset(new AliasSetTracker(*AA));
// Loop over the body of this loop, construct AST.
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
for (auto *Block : L->getBlocks()) {
if (LI->getLoopFor(Block) == L) // Ignore blocks in subloop.
CurAST->add(*Block); // Incorporate the specified basic block
@ -600,7 +622,6 @@ bool LoopVersioningLICM::runOnLoop(Loop *L, LPPassManager &LPM) {
// Do loop versioning.
// Create memcheck for memory accessed inside loop.
// Clone original loop, and set blocks properly.
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
LoopVersioning LVer(*LAI, LAI->getRuntimePointerChecking()->getChecks(),
CurLoop, LI, DT, SE);
LVer.versionLoop();
@ -620,9 +641,9 @@ bool LoopVersioningLICM::runOnLoop(Loop *L, LPPassManager &LPM) {
return Changed;
}
char LoopVersioningLICM::ID = 0;
char LoopVersioningLICMLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(LoopVersioningLICM, "loop-versioning-licm",
INITIALIZE_PASS_BEGIN(LoopVersioningLICMLegacyPass, "loop-versioning-licm",
"Loop Versioning For LICM", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
@ -633,7 +654,31 @@ INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
INITIALIZE_PASS_END(LoopVersioningLICM, "loop-versioning-licm",
INITIALIZE_PASS_END(LoopVersioningLICMLegacyPass, "loop-versioning-licm",
"Loop Versioning For LICM", false, false)
Pass *llvm::createLoopVersioningLICMPass() { return new LoopVersioningLICM(); }
Pass *llvm::createLoopVersioningLICMPass() {
return new LoopVersioningLICMLegacyPass();
}
namespace llvm {
PreservedAnalyses LoopVersioningLICMPass::run(Loop &L, LoopAnalysisManager &AM,
LoopStandardAnalysisResults &LAR,
LPMUpdater &U) {
AliasAnalysis *AA = &LAR.AA;
ScalarEvolution *SE = &LAR.SE;
DominatorTree *DT = &LAR.DT;
LoopInfo *LI = &LAR.LI;
const Function *F = L.getHeader()->getParent();
OptimizationRemarkEmitter ORE(F);
auto GetLAI = [&](Loop *L) -> const LoopAccessInfo & {
return AM.getResult<LoopAccessAnalysis>(*L, LAR);
};
if (!LoopVersioningLICM(AA, SE, &ORE, GetLAI).runOnLoop(&L, LI, DT))
return PreservedAnalyses::all();
return getLoopPassPreservedAnalyses();
}
} // namespace llvm

View File

@ -76,7 +76,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeLoopUnrollAndJamPass(Registry);
initializeLoopUnswitchPass(Registry);
initializeWarnMissedTransformationsLegacyPass(Registry);
initializeLoopVersioningLICMPass(Registry);
initializeLoopVersioningLICMLegacyPassPass(Registry);
initializeLoopIdiomRecognizeLegacyPassPass(Registry);
initializeLowerAtomicLegacyPassPass(Registry);
initializeLowerConstantIntrinsicsPass(Registry);

View File

@ -1,4 +1,5 @@
; RUN: opt -S -loop-versioning-licm -licm-versioning-invariant-threshold=0 %s | FileCheck %s
; RUN: opt -S -passes='loop-versioning-licm' -licm-versioning-invariant-threshold=0 %s | FileCheck %s
; Make sure the convergent attribute is respected, and no condition is
; introduced

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -O1 -S -loop-versioning-licm -licm -debug-only=loop-versioning-licm 2>&1 | FileCheck %s
; RUN: opt < %s -S -passes='loop-versioning-licm,licm' --aa-pipeline=default -debug-only=loop-versioning-licm 2>&1 | FileCheck %s
; REQUIRES: asserts
;
; Test to confirm loop is a candidate for LoopVersioningLICM.

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -O1 -S -loop-versioning-licm -licm -debug-only=loop-versioning-licm -disable-loop-unrolling 2>&1 | FileCheck %s
; RUN: opt < %s -S -passes='loop-versioning-licm,licm' --aa-pipeline=default -debug-only=loop-versioning-licm -disable-loop-unrolling 2>&1 | FileCheck %s
; REQUIRES: asserts
;
; Test to confirm loop is a good candidate for LoopVersioningLICM

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -O1 -S -loop-versioning-licm -debug-only=loop-versioning-licm 2>&1 | FileCheck %s
; RUN: opt < %s -S -passes='loop-versioning-licm' -debug-only=loop-versioning-licm 2>&1 | FileCheck %s
; REQUIRES: asserts
;
; Test to confirm loop is not a candidate for LoopVersioningLICM.

View File

@ -1,4 +1,5 @@
; RUN: opt < %s -O1 -S -loop-versioning-licm -licm 2>&1 | FileCheck %s
; RUN: opt < %s -S -passes='loop-versioning-licm,licm' 2>&1 | FileCheck %s
; CHECK-LABEL: @without_metadata(
define i32 @without_metadata(i32* nocapture %var1, i32* nocapture readnone %var2, i32* nocapture %var3, i32 %itr) #0 {