diff options
author | Anna Thomas <anna@azul.com> | 2017-03-22 19:27:12 +0000 |
---|---|---|
committer | Anna Thomas <anna@azul.com> | 2017-03-22 19:27:12 +0000 |
commit | e27b39a9766da2c9880488fc99bf0f0b247d9588 (patch) | |
tree | ce30ff5512261dfac768831b7adf2ca9f45145b2 /llvm/lib/Analysis/LazyValueInfo.cpp | |
parent | 4c103f1f616557567d09c8d4a95dcbf187acde0f (diff) | |
download | bcm5719-llvm-e27b39a9766da2c9880488fc99bf0f0b247d9588.tar.gz bcm5719-llvm-e27b39a9766da2c9880488fc99bf0f0b247d9588.zip |
[LVI] Add an LVI printer pass to capture test LVI cache after transformations
Summary:
Adding a printer pass for printing the LVI cache values after transformations
that use LVI.
This will help us in identifying cases where LVI
invariants are violated, or transforms that leave LVI in an incorrect state.
Right now, I have added two test cases to show that the printer pass is working.
I will be adding more test cases in a later change, once this change is
checked in upstream.
Reviewers: reames, dberlin, sanjoy, apilipenko
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D30790
llvm-svn: 298542
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r-- | llvm/lib/Analysis/LazyValueInfo.cpp | 102 |
1 files changed, 96 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 7a740e9b3db..05820529363 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/CFG.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Constants.h" @@ -31,6 +32,7 @@ #include "llvm/IR/PatternMatch.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h" #include <map> #include <stack> @@ -362,6 +364,7 @@ namespace { /// This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { + friend class LazyValueInfoAnnotatedWriter; /// This is all of the cached block information for exactly one Value*. /// The entries are sorted by the BasicBlock* of the /// entries, allowing us to do a lookup with a binary search. @@ -373,20 +376,21 @@ namespace { SmallDenseMap<PoisoningVH<BasicBlock>, LVILatticeVal, 4> BlockVals; }; - /// This is all of the cached information for all values, - /// mapped from Value* to key information. - DenseMap<Value *, std::unique_ptr<ValueCacheEntryTy>> ValueCache; - /// This tracks, on a per-block basis, the set of values that are /// over-defined at the end of that block. typedef DenseMap<PoisoningVH<BasicBlock>, SmallPtrSet<Value *, 4>> OverDefinedCacheTy; - OverDefinedCacheTy OverDefinedCache; - /// Keep track of all blocks that we have ever seen, so we /// don't spend time removing unused blocks from our caches. DenseSet<PoisoningVH<BasicBlock> > SeenBlocks; + protected: + /// This is all of the cached information for all values, + /// mapped from Value* to key information. + DenseMap<Value *, std::unique_ptr<ValueCacheEntryTy>> ValueCache; + OverDefinedCacheTy OverDefinedCache; + + public: void insertResult(Value *Val, BasicBlock *BB, const LVILatticeVal &Result) { SeenBlocks.insert(BB); @@ -439,6 +443,7 @@ namespace { return BBI->second; } + void printCache(Function &F, raw_ostream &OS); /// clear - Empty the cache. void clear() { SeenBlocks.clear(); @@ -462,6 +467,49 @@ namespace { }; } + +namespace { + + /// An assembly annotator class to print LazyValueCache information in + /// comments. + class LazyValueInfoAnnotatedWriter : public AssemblyAnnotationWriter { + const LazyValueInfoCache* LVICache; + + public: + LazyValueInfoAnnotatedWriter(const LazyValueInfoCache *L) : LVICache(L) {} + + virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, + formatted_raw_ostream &OS) { + auto ODI = LVICache->OverDefinedCache.find(const_cast<BasicBlock*>(BB)); + if (ODI == LVICache->OverDefinedCache.end()) + return; + OS << "; OverDefined values for block are: \n"; + for (auto *V : ODI->second) + OS << ";" << *V << "\n"; + } + + virtual void emitInstructionAnnot(const Instruction *I, + formatted_raw_ostream &OS) { + + auto VI = LVICache->ValueCache.find_as(const_cast<Instruction *>(I)); + if (VI == LVICache->ValueCache.end()) + return; + OS << "; CachedLatticeValues for: '" << *VI->first << "'\n"; + for (auto &BV : VI->second->BlockVals) { + OS << "; at beginning of BasicBlock: '"; + BV.first->printAsOperand(OS, false); + OS << "' LatticeVal: '" << BV.second << "' \n"; + } + } +}; +} + +void LazyValueInfoCache::printCache(Function &F, raw_ostream &OS) { + LazyValueInfoAnnotatedWriter Writer(this); + F.print(OS, &Writer); + +} + void LazyValueInfoCache::eraseValue(Value *V) { for (auto I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E;) { // Copy and increment the iterator immediately so we can erase behind @@ -633,6 +681,11 @@ namespace { TheCache.clear(); } + /// Printing the LazyValueInfoCache. + void printCache(Function &F, raw_ostream &OS) { + TheCache.printCache(F, OS); + } + /// This is part of the update interface to inform the cache /// that a block has been deleted. void eraseBlock(BasicBlock *BB) { @@ -1824,3 +1877,40 @@ void LazyValueInfo::eraseBlock(BasicBlock *BB) { getImpl(PImpl, AC, &DL, DT).eraseBlock(BB); } } + + +void LazyValueInfo::printCache(Function &F, raw_ostream &OS) { + if (PImpl) { + getImpl(PImpl, AC, DL, DT).printCache(F, OS); + } +} + +namespace { +// Printer class for LazyValueInfo results. +class LazyValueInfoPrinter : public FunctionPass { +public: + static char ID; // Pass identification, replacement for typeid + LazyValueInfoPrinter() : FunctionPass(ID) { + initializeLazyValueInfoPrinterPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired<LazyValueInfoWrapperPass>(); + } + + bool runOnFunction(Function &F) override { + dbgs() << "LVI for function '" << F.getName() << "':\n"; + auto &LVI = getAnalysis<LazyValueInfoWrapperPass>().getLVI(); + LVI.printCache(F, dbgs()); + return false; + } +}; +} + +char LazyValueInfoPrinter::ID = 0; +INITIALIZE_PASS_BEGIN(LazyValueInfoPrinter, "print-lazy-value-info", + "Lazy Value Info Printer Pass", false, false) +INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) +INITIALIZE_PASS_END(LazyValueInfoPrinter, "print-lazy-value-info", + "Lazy Value Info Printer Pass", false, false) |