Make ProfileEstimator even more robust on general CFGs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81516 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/ProfileVerifierPass.cpp b/lib/Analysis/ProfileVerifierPass.cpp
index 0be4de4..d534829 100644
--- a/lib/Analysis/ProfileVerifierPass.cpp
+++ b/lib/Analysis/ProfileVerifierPass.cpp
@@ -153,7 +153,7 @@
}
}
-// compare with relative error
+// This compares A and B but considering maybe small differences.
static bool Equals(double A, double B) {
double maxRelativeError = 0.0000001;
if (A == B)
@@ -167,6 +167,9 @@
return false;
}
+// This checks if the function "exit" is reachable from an given function
+// via calls, this is necessary to check if a profile is valid despite the
+// counts not fitting exactly.
bool ProfileVerifierPass::exitReachable(const Function *F) {
if (!F) return false;
@@ -196,7 +199,7 @@
double EdgeWeight = PI->getEdgeWeight(E);
if (EdgeWeight == ProfileInfo::MissingValue) {
errs() << "Edge " << E << " in Function "
- << E.first->getParent()->getNameStr() << ": ";
+ << ProfileInfo.getFunction(E)->getNameStr() << ": ";
ASSERTMESSAGE("ASSERT:Edge has missing value");
return 0;
} else {
@@ -215,15 +218,23 @@
return;
}
+// This calculates the Information for a block and then recurses into the
+// successors.
void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) {
+ // Break the recursion by remembering all visited blocks.
if (BBisVisited.find(BB) != BBisVisited.end()) return;
+ // Use a data structure to store all the information, this can then be handed
+ // to debug printers.
DetailedBlockInfo DI;
DI.BB = BB;
DI.outCount = DI.inCount = DI.inWeight = DI.outWeight = 0;
+
+ // Read predecessors.
std::set<const BasicBlock*> ProcessedPreds;
pred_const_iterator bpi = pred_begin(BB), bpe = pred_end(BB);
+ // If there are none, check for (0,BB) edge.
if (bpi == bpe) {
DI.inWeight += ReadOrAssert(PI->getEdge(0,BB));
DI.inCount++;
@@ -235,14 +246,16 @@
}
}
+ // Read successors.
std::set<const BasicBlock*> ProcessedSuccs;
succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
- if (bbi == bbe) {
- double w = PI->getEdgeWeight(PI->getEdge(BB,0));
- if (w != ProfileInfo::MissingValue) {
- DI.outWeight += w;
- DI.outCount++;
- }
+ // If there is an (0,BB) edge, consider it too. (This is done not only when
+ // there are no successors, but every time; not every function contains
+ // return blocks with no successors (think loop latch as return block)).
+ double w = PI->getEdgeWeight(PI->getEdge(BB,0));
+ if (w != ProfileInfo::MissingValue) {
+ DI.outWeight += w;
+ DI.outCount++;
}
for (;bbi != bbe; ++bbi) {
if (ProcessedSuccs.insert(*bbi).second) {
@@ -251,6 +264,7 @@
}
}
+ // Read block weight.
DI.BBWeight = PI->getExecutionCount(BB);
CheckValue(DI.BBWeight == ProfileInfo::MissingValue,
"ASSERT:BasicBlock has missing value", &DI);
@@ -303,7 +317,7 @@
}
- // mark as visited and recurse into subnodes
+ // Mark this block as visited, rescurse into successors.
BBisVisited.insert(BB);
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
bbi != bbe; ++bbi ) {
@@ -314,14 +328,11 @@
bool ProfileVerifierPass::runOnFunction(Function &F) {
PI = &getAnalysis<ProfileInfo>();
- if (PI->getExecutionCount(&F) == ProfileInfo::MissingValue) {
- DEBUG(errs() << "Function " << F.getNameStr() << " has no profile\n");
- return false;
- }
-
+ // Prepare global variables.
PrintedDebugTree = false;
BBisVisited.clear();
+ // Fetch entry block and recurse into it.
const BasicBlock *entry = &F.getEntryBlock();
recurseBasicBlock(entry);