1
0
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:
Ashutosh Nema 2018-01-23 09:47:28 +00:00
parent 00022a2f0a
commit 2a3b64fc69
3 changed files with 60 additions and 2 deletions

View File

@ -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);

View File

@ -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)) {}

View File

@ -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)