mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
This change add's optimization remark in LoopVersioning LICM pass.
Summary: This patch is adding remark messages to the LoopVersioning LICM pass, which will be useful for optimization remark emitter (ORE) infrastructure. Patch by: Deepak Porwal Reviewers: anemet, ashutosh.nema, eastig Subscribers: eastig, vivekvpandya, fhahn, llvm-commits llvm-svn: 323183
This commit is contained in:
parent
00022a2f0a
commit
2a3b64fc69
@ -415,6 +415,7 @@ public:
|
|||||||
Argument(StringRef Key, const Type *T);
|
Argument(StringRef Key, const Type *T);
|
||||||
Argument(StringRef Key, StringRef S);
|
Argument(StringRef Key, StringRef S);
|
||||||
Argument(StringRef Key, int N);
|
Argument(StringRef Key, int N);
|
||||||
|
Argument(StringRef Key, float N);
|
||||||
Argument(StringRef Key, long N);
|
Argument(StringRef Key, long N);
|
||||||
Argument(StringRef Key, long long N);
|
Argument(StringRef Key, long long N);
|
||||||
Argument(StringRef Key, unsigned N);
|
Argument(StringRef Key, unsigned N);
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/Regex.h"
|
#include "llvm/Support/Regex.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/Support/ScopedPrinter.h"
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -167,6 +168,9 @@ DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, StringRef S)
|
|||||||
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, int N)
|
||||||
: Key(Key), Val(itostr(N)) {}
|
: Key(Key), Val(itostr(N)) {}
|
||||||
|
|
||||||
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, float N)
|
||||||
|
: Key(Key), Val(llvm::to_string(N)) {}
|
||||||
|
|
||||||
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
|
DiagnosticInfoOptimizationBase::Argument::Argument(StringRef Key, long N)
|
||||||
: Key(Key), Val(itostr(N)) {}
|
: Key(Key), Val(itostr(N)) {}
|
||||||
|
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
#include "llvm/Analysis/LoopAccessAnalysis.h"
|
#include "llvm/Analysis/LoopAccessAnalysis.h"
|
||||||
#include "llvm/Analysis/LoopInfo.h"
|
#include "llvm/Analysis/LoopInfo.h"
|
||||||
#include "llvm/Analysis/LoopPass.h"
|
#include "llvm/Analysis/LoopPass.h"
|
||||||
|
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
|
||||||
#include "llvm/Analysis/ScalarEvolution.h"
|
#include "llvm/Analysis/ScalarEvolution.h"
|
||||||
#include "llvm/IR/CallSite.h"
|
#include "llvm/IR/CallSite.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
@ -166,6 +167,7 @@ struct LoopVersioningLICM : public LoopPass {
|
|||||||
AU.addRequired<ScalarEvolutionWrapperPass>();
|
AU.addRequired<ScalarEvolutionWrapperPass>();
|
||||||
AU.addPreserved<AAResultsWrapperPass>();
|
AU.addPreserved<AAResultsWrapperPass>();
|
||||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||||
|
AU.addRequired<OptimizationRemarkEmitterWrapperPass>();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef getPassName() const override { return "Loop Versioning for LICM"; }
|
StringRef getPassName() const override { return "Loop Versioning for LICM"; }
|
||||||
@ -178,6 +180,7 @@ struct LoopVersioningLICM : public LoopPass {
|
|||||||
LoadAndStoreCounter = 0;
|
LoadAndStoreCounter = 0;
|
||||||
InvariantCounter = 0;
|
InvariantCounter = 0;
|
||||||
IsReadOnlyLoop = true;
|
IsReadOnlyLoop = true;
|
||||||
|
ORE = nullptr;
|
||||||
CurAST.reset();
|
CurAST.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +210,7 @@ private:
|
|||||||
Loop *CurLoop = nullptr;
|
Loop *CurLoop = nullptr;
|
||||||
|
|
||||||
// AliasSet information for the current loop.
|
// AliasSet information for the current loop.
|
||||||
std::unique_ptr<AliasSetTracker> CurAST;
|
std::unique_ptr<AliasSetTracker> CurAST;
|
||||||
|
|
||||||
// Maximum loop nest threshold
|
// Maximum loop nest threshold
|
||||||
unsigned LoopDepthThreshold;
|
unsigned LoopDepthThreshold;
|
||||||
@ -224,6 +227,9 @@ private:
|
|||||||
// Read only loop marker.
|
// Read only loop marker.
|
||||||
bool IsReadOnlyLoop = true;
|
bool IsReadOnlyLoop = true;
|
||||||
|
|
||||||
|
// OptimizationRemarkEmitter
|
||||||
|
OptimizationRemarkEmitter *ORE;
|
||||||
|
|
||||||
bool isLegalForVersioning();
|
bool isLegalForVersioning();
|
||||||
bool legalLoopStructure();
|
bool legalLoopStructure();
|
||||||
bool legalLoopInstructions();
|
bool legalLoopInstructions();
|
||||||
@ -403,13 +409,19 @@ bool LoopVersioningLICM::legalLoopInstructions() {
|
|||||||
LoadAndStoreCounter = 0;
|
LoadAndStoreCounter = 0;
|
||||||
InvariantCounter = 0;
|
InvariantCounter = 0;
|
||||||
IsReadOnlyLoop = true;
|
IsReadOnlyLoop = true;
|
||||||
|
using namespace ore;
|
||||||
// Iterate over loop blocks and instructions of each block and check
|
// Iterate over loop blocks and instructions of each block and check
|
||||||
// instruction safety.
|
// instruction safety.
|
||||||
for (auto *Block : CurLoop->getBlocks())
|
for (auto *Block : CurLoop->getBlocks())
|
||||||
for (auto &Inst : *Block) {
|
for (auto &Inst : *Block) {
|
||||||
// If instruction is unsafe just return false.
|
// If instruction is unsafe just return false.
|
||||||
if (!instructionSafeForVersioning(&Inst))
|
if (!instructionSafeForVersioning(&Inst)) {
|
||||||
|
ORE->emit([&]() {
|
||||||
|
return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopInst", &Inst)
|
||||||
|
<< " Unsafe Loop Instruction";
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Get LoopAccessInfo from current loop.
|
// Get LoopAccessInfo from current loop.
|
||||||
LAI = &LAA->getInfo(CurLoop);
|
LAI = &LAA->getInfo(CurLoop);
|
||||||
@ -422,6 +434,15 @@ bool LoopVersioningLICM::legalLoopInstructions() {
|
|||||||
if (LAI->getNumRuntimePointerChecks() >
|
if (LAI->getNumRuntimePointerChecks() >
|
||||||
VectorizerParams::RuntimeMemoryCheckThreshold) {
|
VectorizerParams::RuntimeMemoryCheckThreshold) {
|
||||||
DEBUG(dbgs() << " LAA: Runtime checks are more than threshold !!\n");
|
DEBUG(dbgs() << " LAA: Runtime checks are more than threshold !!\n");
|
||||||
|
ORE->emit([&]() {
|
||||||
|
return OptimizationRemarkMissed(DEBUG_TYPE, "RuntimeCheck",
|
||||||
|
CurLoop->getStartLoc(),
|
||||||
|
CurLoop->getHeader())
|
||||||
|
<< "Number of runtime checks "
|
||||||
|
<< NV("RuntimeChecks", LAI->getNumRuntimePointerChecks())
|
||||||
|
<< " exceeds threshold "
|
||||||
|
<< NV("Threshold", VectorizerParams::RuntimeMemoryCheckThreshold);
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Loop should have at least one invariant load or store instruction.
|
// Loop should have at least one invariant load or store instruction.
|
||||||
@ -443,6 +464,16 @@ bool LoopVersioningLICM::legalLoopInstructions() {
|
|||||||
<< ((InvariantCounter * 100) / LoadAndStoreCounter) << "%\n");
|
<< ((InvariantCounter * 100) / LoadAndStoreCounter) << "%\n");
|
||||||
DEBUG(dbgs() << " Invariant loads & store threshold: "
|
DEBUG(dbgs() << " Invariant loads & store threshold: "
|
||||||
<< InvariantThreshold << "%\n");
|
<< InvariantThreshold << "%\n");
|
||||||
|
ORE->emit([&]() {
|
||||||
|
return OptimizationRemarkMissed(DEBUG_TYPE, "InvariantThreshold",
|
||||||
|
CurLoop->getStartLoc(),
|
||||||
|
CurLoop->getHeader())
|
||||||
|
<< "Invariant load & store "
|
||||||
|
<< NV("LoadAndStoreCounter",
|
||||||
|
((InvariantCounter * 100) / LoadAndStoreCounter))
|
||||||
|
<< " are less then defined threshold "
|
||||||
|
<< NV("Threshold", InvariantThreshold);
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -464,6 +495,7 @@ bool LoopVersioningLICM::isLoopAlreadyVisited() {
|
|||||||
/// c) loop memory access legality.
|
/// c) loop memory access legality.
|
||||||
/// Return true if legal else returns false.
|
/// Return true if legal else returns false.
|
||||||
bool LoopVersioningLICM::isLegalForVersioning() {
|
bool LoopVersioningLICM::isLegalForVersioning() {
|
||||||
|
using namespace ore;
|
||||||
DEBUG(dbgs() << "Loop: " << *CurLoop);
|
DEBUG(dbgs() << "Loop: " << *CurLoop);
|
||||||
// Make sure not re-visiting same loop again.
|
// Make sure not re-visiting same loop again.
|
||||||
if (isLoopAlreadyVisited()) {
|
if (isLoopAlreadyVisited()) {
|
||||||
@ -475,6 +507,12 @@ bool LoopVersioningLICM::isLegalForVersioning() {
|
|||||||
if (!legalLoopStructure()) {
|
if (!legalLoopStructure()) {
|
||||||
DEBUG(
|
DEBUG(
|
||||||
dbgs() << " Loop structure not suitable for LoopVersioningLICM\n\n");
|
dbgs() << " Loop structure not suitable for LoopVersioningLICM\n\n");
|
||||||
|
ORE->emit([&]() {
|
||||||
|
return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopStruct",
|
||||||
|
CurLoop->getStartLoc(),
|
||||||
|
CurLoop->getHeader())
|
||||||
|
<< " Unsafe Loop structure";
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check loop instruction leagality.
|
// Check loop instruction leagality.
|
||||||
@ -487,10 +525,23 @@ bool LoopVersioningLICM::isLegalForVersioning() {
|
|||||||
if (!legalLoopMemoryAccesses()) {
|
if (!legalLoopMemoryAccesses()) {
|
||||||
DEBUG(dbgs()
|
DEBUG(dbgs()
|
||||||
<< " Loop memory access not suitable for LoopVersioningLICM\n\n");
|
<< " Loop memory access not suitable for LoopVersioningLICM\n\n");
|
||||||
|
ORE->emit([&]() {
|
||||||
|
return OptimizationRemarkMissed(DEBUG_TYPE, "IllegalLoopMemoryAccess",
|
||||||
|
CurLoop->getStartLoc(),
|
||||||
|
CurLoop->getHeader())
|
||||||
|
<< " Unsafe Loop memory access";
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Loop versioning is feasible, return true.
|
// Loop versioning is feasible, return true.
|
||||||
DEBUG(dbgs() << " Loop Versioning found to be beneficial\n\n");
|
DEBUG(dbgs() << " Loop Versioning found to be beneficial\n\n");
|
||||||
|
ORE->emit([&]() {
|
||||||
|
return OptimizationRemark(DEBUG_TYPE, "IsLegalForVersioning",
|
||||||
|
CurLoop->getStartLoc(), CurLoop->getHeader())
|
||||||
|
<< " Versioned loop for LICM."
|
||||||
|
<< " Number of runtime checks we had to insert "
|
||||||
|
<< NV("RuntimeChecks", LAI->getNumRuntimePointerChecks());
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,6 +593,7 @@ bool LoopVersioningLICM::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||||||
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
|
||||||
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
|
||||||
LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
|
LAA = &getAnalysis<LoopAccessLegacyAnalysis>();
|
||||||
|
ORE = &getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE();
|
||||||
LAI = nullptr;
|
LAI = nullptr;
|
||||||
// Set Current Loop
|
// Set Current Loop
|
||||||
CurLoop = L;
|
CurLoop = L;
|
||||||
@ -592,6 +644,7 @@ INITIALIZE_PASS_DEPENDENCY(LoopAccessLegacyAnalysis)
|
|||||||
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
|
||||||
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
|
||||||
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
|
||||||
|
INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass)
|
||||||
INITIALIZE_PASS_END(LoopVersioningLICM, "loop-versioning-licm",
|
INITIALIZE_PASS_END(LoopVersioningLICM, "loop-versioning-licm",
|
||||||
"Loop Versioning For LICM", false, false)
|
"Loop Versioning For LICM", false, false)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user