mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-27 15:57:13 +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);
|
Children.push_back(C);
|
||||||
return C;
|
return C;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getNumChildren() const {
|
size_t getNumChildren() const {
|
||||||
return Children.size();
|
return Children.size();
|
||||||
}
|
}
|
||||||
@ -308,6 +308,43 @@ public:
|
|||||||
// FIXME: Should remove this
|
// FIXME: Should remove this
|
||||||
virtual bool runOnFunction(Function &F) { return false; }
|
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(); }
|
virtual void releaseMemory() { reset(); }
|
||||||
|
|
||||||
/// getNode - return the (Post)DominatorTree node for the specified basic
|
/// getNode - return the (Post)DominatorTree node for the specified basic
|
||||||
@ -697,7 +734,22 @@ public:
|
|||||||
inline DomTreeNode *getRootNode() const {
|
inline DomTreeNode *getRootNode() const {
|
||||||
return DT->getRootNode();
|
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 bool runOnFunction(Function &F);
|
||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
@ -843,8 +895,8 @@ public:
|
|||||||
typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
|
typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
|
||||||
protected:
|
protected:
|
||||||
DomSetMapType Frontiers;
|
DomSetMapType Frontiers;
|
||||||
std::vector<BasicBlock*> Roots;
|
std::vector<BasicBlock*> Roots;
|
||||||
const bool IsPostDominators;
|
const bool IsPostDominators;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DominanceFrontierBase(intptr_t ID, bool isPostDom)
|
DominanceFrontierBase(intptr_t ID, bool isPostDom)
|
||||||
@ -896,6 +948,58 @@ public:
|
|||||||
I->second.erase(Node);
|
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
|
/// print - Convert to human readable form
|
||||||
///
|
///
|
||||||
virtual void print(std::ostream &OS, const Module* = 0) const;
|
virtual void print(std::ostream &OS, const Module* = 0) const;
|
||||||
@ -962,7 +1066,6 @@ public:
|
|||||||
NewDFI->second.erase(BB);
|
NewDFI->second.erase(BB);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
const DomSetType &calculate(const DominatorTree &DT,
|
const DomSetType &calculate(const DominatorTree &DT,
|
||||||
const DomTreeNode *Node);
|
const DomTreeNode *Node);
|
||||||
};
|
};
|
||||||
|
@ -125,7 +125,6 @@ public:
|
|||||||
Resolver = AR;
|
Resolver = AR;
|
||||||
}
|
}
|
||||||
inline AnalysisResolver *getResolver() {
|
inline AnalysisResolver *getResolver() {
|
||||||
assert (Resolver && "Resolver is not set");
|
|
||||||
return Resolver;
|
return Resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +245,9 @@ public:
|
|||||||
/// verifyPreservedAnalysis -- Verify analysis presreved by pass P.
|
/// verifyPreservedAnalysis -- Verify analysis presreved by pass P.
|
||||||
void verifyPreservedAnalysis(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
|
/// Remove Analysis that is not preserved by the pass
|
||||||
void removeNotPreservedAnalysis(Pass *P);
|
void removeNotPreservedAnalysis(Pass *P);
|
||||||
|
|
||||||
|
@ -234,6 +234,9 @@ bool LPPassManager::runOnFunction(Function &F) {
|
|||||||
recordAvailableAnalysis(P);
|
recordAvailableAnalysis(P);
|
||||||
removeDeadPasses(P, "", ON_LOOP_MSG);
|
removeDeadPasses(P, "", ON_LOOP_MSG);
|
||||||
|
|
||||||
|
// Verify dominator information if it is available and preserved.
|
||||||
|
verifyDomInfo(*LP, F);
|
||||||
|
|
||||||
if (skipThisLoop)
|
if (skipThisLoop)
|
||||||
// Do not run other passes on this loop.
|
// Do not run other passes on this loop.
|
||||||
break;
|
break;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/ModuleProvider.h"
|
#include "llvm/ModuleProvider.h"
|
||||||
#include "llvm/Support/Streams.h"
|
#include "llvm/Support/Streams.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
|
#include "llvm/Analysis/Dominators.h"
|
||||||
#include "llvm-c/Core.h"
|
#include "llvm-c/Core.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -41,6 +42,11 @@ enum PassDebugLevel {
|
|||||||
None, Arguments, Structure, Executions, Details
|
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>
|
static cl::opt<enum PassDebugLevel>
|
||||||
PassDebugging("debug-pass", cl::Hidden,
|
PassDebugging("debug-pass", cl::Hidden,
|
||||||
cl::desc("Print PassManager debugging information"),
|
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
|
/// Remove Analyss not preserved by Pass P
|
||||||
void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
|
void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
|
||||||
AnalysisUsage AnUsage;
|
AnalysisUsage AnUsage;
|
||||||
@ -650,7 +696,6 @@ void PMDataManager::removeNotPreservedAnalysis(Pass *P) {
|
|||||||
InheritedAnalysis[Index]->erase(Info);
|
InheritedAnalysis[Index]->erase(Info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove analysis passes that are not used any longer
|
/// Remove analysis passes that are not used any longer
|
||||||
@ -719,6 +764,7 @@ void PMDataManager::add(Pass *P,
|
|||||||
Pass *PRequired = *I;
|
Pass *PRequired = *I;
|
||||||
unsigned RDepth = 0;
|
unsigned RDepth = 0;
|
||||||
|
|
||||||
|
assert (PRequired->getResolver() && "Analysis Resolver is not set");
|
||||||
PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
|
PMDataManager &DM = PRequired->getResolver()->getPMDataManager();
|
||||||
RDepth = DM.getDepth();
|
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.
|
// If that is not the case then it will raise an assert when it is used.
|
||||||
continue;
|
continue;
|
||||||
AnalysisResolver *AR = P->getResolver();
|
AnalysisResolver *AR = P->getResolver();
|
||||||
|
assert (AR && "Analysis Resolver is not set");
|
||||||
AR->addAnalysisImplsPair(*I, Impl);
|
AR->addAnalysisImplsPair(*I, Impl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1202,6 +1249,9 @@ bool FPPassManager::runOnFunction(Function &F) {
|
|||||||
removeNotPreservedAnalysis(FP);
|
removeNotPreservedAnalysis(FP);
|
||||||
recordAvailableAnalysis(FP);
|
recordAvailableAnalysis(FP);
|
||||||
removeDeadPasses(FP, F.getNameStart(), ON_FUNCTION_MSG);
|
removeDeadPasses(FP, F.getNameStart(), ON_FUNCTION_MSG);
|
||||||
|
|
||||||
|
// Verify dominator information if it is available and preserved.
|
||||||
|
verifyDomInfo(*FP, F);
|
||||||
}
|
}
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user