mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
Add dom info verifier.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52967 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
605041e5a8
commit
5b57e720c8
@ -102,7 +102,7 @@ public:
|
||||
Children.push_back(C);
|
||||
return C;
|
||||
}
|
||||
|
||||
|
||||
size_t getNumChildren() const {
|
||||
return Children.size();
|
||||
}
|
||||
@ -308,6 +308,43 @@ public:
|
||||
// FIXME: Should remove this
|
||||
virtual bool runOnFunction(Function &F) { return false; }
|
||||
|
||||
/// compare - Return false if the other dominator tree base maches this
|
||||
/// dominator tree base. Otherwise return true.
|
||||
bool compare(DominatorTreeBase &Other) const {
|
||||
|
||||
// Collect nodes.
|
||||
SmallPtrSet<const NodeT *,4> MyBBs;
|
||||
for (typename DomTreeNodeMapType::const_iterator
|
||||
I = this->DomTreeNodes.begin(),
|
||||
E = this->DomTreeNodes.end(); I != E; ++I) {
|
||||
const NodeT *BB = I->first;
|
||||
MyBBs.insert(BB);
|
||||
}
|
||||
|
||||
SmallPtrSet<const NodeT *,4> OtherBBs;
|
||||
const DomTreeNodeMapType &OtherDomTreeNodes = Other.DomTreeNodes;
|
||||
for (typename DomTreeNodeMapType::const_iterator
|
||||
I = OtherDomTreeNodes.begin(),
|
||||
E = OtherDomTreeNodes.end(); I != E; ++I) {
|
||||
const NodeT *BB = I->first;
|
||||
OtherBBs.insert(BB);
|
||||
}
|
||||
|
||||
if (OtherBBs.size() != MyBBs.size())
|
||||
return true;
|
||||
|
||||
// Compare node sets.
|
||||
for (typename SmallPtrSet<const NodeT *,4>::const_iterator I = MyBBs.begin(),
|
||||
E = MyBBs.end(); I != E; ++I) {
|
||||
const NodeT *BB = *I;
|
||||
if (OtherBBs.erase(BB) == 0)
|
||||
return true;
|
||||
}
|
||||
if (!OtherBBs.empty())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void releaseMemory() { reset(); }
|
||||
|
||||
/// getNode - return the (Post)DominatorTree node for the specified basic
|
||||
@ -697,7 +734,22 @@ public:
|
||||
inline DomTreeNode *getRootNode() const {
|
||||
return DT->getRootNode();
|
||||
}
|
||||
|
||||
|
||||
/// compare - Return false if the other dominator tree maches this
|
||||
/// dominator tree. Otherwise return true.
|
||||
inline bool compare(DominatorTree &Other) const {
|
||||
DomTreeNode *R = getRootNode();
|
||||
DomTreeNode *OtherR = Other.getRootNode();
|
||||
|
||||
if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
|
||||
return true;
|
||||
|
||||
if (DT->compare(Other.getBase()))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
@ -843,8 +895,8 @@ public:
|
||||
typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
|
||||
protected:
|
||||
DomSetMapType Frontiers;
|
||||
std::vector<BasicBlock*> Roots;
|
||||
const bool IsPostDominators;
|
||||
std::vector<BasicBlock*> Roots;
|
||||
const bool IsPostDominators;
|
||||
|
||||
public:
|
||||
DominanceFrontierBase(intptr_t ID, bool isPostDom)
|
||||
@ -896,6 +948,58 @@ public:
|
||||
I->second.erase(Node);
|
||||
}
|
||||
|
||||
/// compareDomSet - Return false if two domsets match. Otherwise
|
||||
/// return ture;
|
||||
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
|
||||
std::set<BasicBlock *> tmpSet;
|
||||
for (DomSetType::const_iterator I = DS2.begin(),
|
||||
E = DS2.end(); I != E; ++I)
|
||||
tmpSet.insert(*I);
|
||||
|
||||
for (DomSetType::const_iterator I = DS1.begin(),
|
||||
E = DS1.end(); I != E; ++I) {
|
||||
BasicBlock *Node = *I;
|
||||
|
||||
if (tmpSet.erase(Node) == 0)
|
||||
// Node is in DS1 but not in DS2.
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!tmpSet.empty())
|
||||
// There are nodes that are in DS2 but not in DS1.
|
||||
return true;
|
||||
|
||||
// DS1 and DS2 matches.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// compare - Return true if the other dominance frontier base matches
|
||||
/// this dominance frontier base. Otherwise return false.
|
||||
bool compare(DominanceFrontierBase &Other) const {
|
||||
DomSetMapType tmpFrontiers;
|
||||
for (DomSetMapType::const_iterator I = Other.begin(),
|
||||
E = Other.end(); I != E; ++I)
|
||||
tmpFrontiers.insert(std::make_pair(I->first, I->second));
|
||||
|
||||
for (DomSetMapType::iterator I = tmpFrontiers.begin(),
|
||||
E = tmpFrontiers.end(); I != E; ++I) {
|
||||
BasicBlock *Node = I->first;
|
||||
const_iterator DFI = find(Node);
|
||||
if (DFI == end())
|
||||
return true;
|
||||
|
||||
if (compareDomSet(I->second, DFI->second))
|
||||
return true;
|
||||
|
||||
tmpFrontiers.erase(Node);
|
||||
}
|
||||
|
||||
if (!tmpFrontiers.empty())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// print - Convert to human readable form
|
||||
///
|
||||
virtual void print(std::ostream &OS, const Module* = 0) const;
|
||||
@ -962,7 +1066,6 @@ public:
|
||||
NewDFI->second.erase(BB);
|
||||
}
|
||||
|
||||
private:
|
||||
const DomSetType &calculate(const DominatorTree &DT,
|
||||
const DomTreeNode *Node);
|
||||
};
|
||||
|
@ -125,7 +125,6 @@ public:
|
||||
Resolver = AR;
|
||||
}
|
||||
inline AnalysisResolver *getResolver() {
|
||||
assert (Resolver && "Resolver is not set");
|
||||
return Resolver;
|
||||
}
|
||||
|
||||
|
@ -245,6 +245,9 @@ public:
|
||||
/// verifyPreservedAnalysis -- Verify analysis presreved by pass P.
|
||||
void verifyPreservedAnalysis(Pass *P);
|
||||
|
||||
/// verifyDomInfo -- Verify dominator information if it is available.
|
||||
void verifyDomInfo(Pass &P, Function &F);
|
||||
|
||||
/// Remove Analysis that is not preserved by the pass
|
||||
void removeNotPreservedAnalysis(Pass *P);
|
||||
|
||||
|
@ -234,6 +234,9 @@ bool LPPassManager::runOnFunction(Function &F) {
|
||||
recordAvailableAnalysis(P);
|
||||
removeDeadPasses(P, "", ON_LOOP_MSG);
|
||||
|
||||
// Verify dominator information if it is available and preserved.
|
||||
verifyDomInfo(*LP, F);
|
||||
|
||||
if (skipThisLoop)
|
||||
// Do not run other passes on this loop.
|
||||
break;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "llvm/ModuleProvider.h"
|
||||
#include "llvm/Support/Streams.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm-c/Core.h"
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
@ -41,6 +42,11 @@ enum PassDebugLevel {
|
||||
None, Arguments, Structure, Executions, Details
|
||||
};
|
||||
|
||||
bool VerifyDomInfo = false;
|
||||
static cl::opt<bool,true>
|
||||
VerifyDomInfoX("verify-dom-info", cl::location(VerifyDomInfo),
|
||||
cl::desc("Verify dominator info (time consuming)"));
|
||||
|
||||
static cl::opt<enum PassDebugLevel>
|
||||
PassDebugging("debug-pass", cl::Hidden,
|
||||
cl::desc("Print PassManager debugging information"),
|
||||
@ -608,6 +614,46 @@ void PMDataManager::verifyPreservedAnalysis(Pass *P) {
|
||||
}
|
||||
}
|
||||
|
||||
/// verifyDomInfo - Verify dominator information if it is available.
|
||||
void PMDataManager::verifyDomInfo(Pass &P, Function &F) {
|
||||
|
||||
if (!VerifyDomInfo || !P.getResolver())
|
||||
return;
|
||||
|
||||
DominatorTree *DT = P.getAnalysisToUpdate<DominatorTree>();
|
||||
if (!DT)
|
||||
return;
|
||||
|
||||
DominatorTree OtherDT;
|
||||
OtherDT.getBase().recalculate(F);
|
||||
if (DT->compare(OtherDT)) {
|
||||
cerr << "Dominator Information for " << F.getNameStart() << "\n";
|
||||
cerr << "Pass " << P.getPassName() << "\n";
|
||||
cerr << "----- Valid -----\n";
|
||||
OtherDT.dump();
|
||||
cerr << "----- InValid -----\n";
|
||||
DT->dump();
|
||||
assert (0 && "Invalid dominator info");
|
||||
}
|
||||
|
||||
DominanceFrontier *DF = P.getAnalysisToUpdate<DominanceFrontier>();
|
||||
if (!DF)
|
||||
return;
|
||||
|
||||
DominanceFrontier OtherDF;
|
||||
std::vector<BasicBlock*> DTRoots = DT->getRoots();
|
||||
OtherDF.calculate(*DT, DT->getNode(DTRoots[0]));
|
||||
if (DF->compare(OtherDF)) {
|
||||
cerr << "Dominator Information for " << F.getNameStart() << "\n";
|
||||
cerr << "Pass " << P.getPassName() << "\n";
|
||||
cerr << "----- Valid -----\n";
|
||||
OtherDF.dump();
|
||||
cerr << "----- InValid -----\n";
|
||||
DF->dump();
|
||||
assert (0 && "Invalid dominator info");
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove Analyss not preserved by Pass P
|
||||
void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
|
||||
AnalysisUsage AnUsage;
|
||||
@ -650,7 +696,6 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
|
||||
InheritedAnalysis[Index]->erase(Info);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Remove analysis passes that are not used any longer
|
||||
@ -719,6 +764,7 @@ void PMDataManager::add(Pass *P,
|
||||
Pass *PRequired = *I;
|
||||
unsigned RDepth = 0;
|
||||
|
||||
assert (PRequired->getResolver() && "Analysis Resolver is not set");
|
||||
PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
|
||||
RDepth = DM.getDepth();
|
||||
|
||||
@ -813,6 +859,7 @@ void PMDataManager::initializeAnalysisImpl(Pass *P) {
|
||||
// If that is not the case then it will raise an assert when it is used.
|
||||
continue;
|
||||
AnalysisResolver *AR = P->getResolver();
|
||||
assert (AR && "Analysis Resolver is not set");
|
||||
AR->addAnalysisImplsPair(*I, Impl);
|
||||
}
|
||||
}
|
||||
@ -1202,6 +1249,9 @@ bool FPPassManager::runOnFunction(Function &F) {
|
||||
removeNotPreservedAnalysis(FP);
|
||||
recordAvailableAnalysis(FP);
|
||||
removeDeadPasses(FP, F.getNameStart(), ON_FUNCTION_MSG);
|
||||
|
||||
// Verify dominator information if it is available and preserved.
|
||||
verifyDomInfo(*FP, F);
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user