aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/ProfileInfoLoader.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-08 20:03:52 +0000
committerChris Lattner <sabre@nondot.org>2004-03-08 20:03:52 +0000
commitdbbbfef165ef730977d948e58b226e1bd8f450d4 (patch)
treeae5d1699fdbb2829cc0e53bc300529ed9c9d79b7 /lib/Analysis/ProfileInfoLoader.cpp
parent9f717ef279f4b82e28c341c98a9aa602f01f9b27 (diff)
If we have edge counts, we can produce block counts. I've verified that
using an edge profile to produce block counts gives the exact same numbers as using a block count directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12232 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ProfileInfoLoader.cpp')
-rw-r--r--lib/Analysis/ProfileInfoLoader.cpp78
1 files changed, 67 insertions, 11 deletions
diff --git a/lib/Analysis/ProfileInfoLoader.cpp b/lib/Analysis/ProfileInfoLoader.cpp
index cef0897983..6c3f0d7bb3 100644
--- a/lib/Analysis/ProfileInfoLoader.cpp
+++ b/lib/Analysis/ProfileInfoLoader.cpp
@@ -16,6 +16,7 @@
#include "llvm/Module.h"
#include "llvm/InstrTypes.h"
#include <cstdio>
+#include <map>
using namespace llvm;
enum ProfilingType {
@@ -145,15 +146,19 @@ ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
unsigned> > &Counts) {
if (FunctionCounts.empty()) {
- // Synthesize function frequency information from the number of times their
- // entry blocks were executed.
- std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
- getBlockCounts(BlockCounts);
-
- for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
- if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first)
- Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
- BlockCounts[i].second));
+ if (hasAccurateBlockCounts()) {
+ // Synthesize function frequency information from the number of times
+ // their entry blocks were executed.
+ std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
+ getBlockCounts(BlockCounts);
+
+ for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
+ if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first)
+ Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
+ BlockCounts[i].second));
+ } else {
+ std::cerr << "Function counts are not available!\n";
+ }
return;
}
@@ -171,8 +176,59 @@ void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
unsigned> > &Counts) {
if (BlockCounts.empty()) {
- std::cerr << "Block counts not available, and no synthesis "
- << "is implemented yet!\n";
+ if (hasAccurateEdgeCounts()) {
+ // Synthesize block count information from edge frequency information.
+ // The block execution frequency is equal to the sum of the execution
+ // frequency of all outgoing edges from a block.
+ //
+ // If a block has no successors, this will not be correct, so we have to
+ // special case it. :(
+ std::vector<std::pair<Edge, unsigned> > EdgeCounts;
+ getEdgeCounts(EdgeCounts);
+
+ std::map<BasicBlock*, unsigned> InEdgeFreqs;
+
+ BasicBlock *LastBlock = 0;
+ TerminatorInst *TI = 0;
+ for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) {
+ if (EdgeCounts[i].first.first != LastBlock) {
+ LastBlock = EdgeCounts[i].first.first;
+ TI = LastBlock->getTerminator();
+ Counts.push_back(std::make_pair(LastBlock, 0));
+ }
+ Counts.back().second += EdgeCounts[i].second;
+ unsigned SuccNum = EdgeCounts[i].first.second;
+ if (SuccNum >= TI->getNumSuccessors()) {
+ static bool Warned = false;
+ if (!Warned) {
+ std::cerr << "WARNING: profile info doesn't seem to match"
+ << " the program!\n";
+ Warned = true;
+ }
+ } else {
+ // If this successor has no successors of its own, we will never
+ // compute an execution count for that block. Remember the incoming
+ // edge frequencies to add later.
+ BasicBlock *Succ = TI->getSuccessor(SuccNum);
+ if (Succ->getTerminator()->getNumSuccessors() == 0)
+ InEdgeFreqs[Succ] += EdgeCounts[i].second;
+ }
+ }
+
+ // Now we have to accumulate information for those blocks without
+ // successors into our table.
+ for (std::map<BasicBlock*, unsigned>::iterator I = InEdgeFreqs.begin(),
+ E = InEdgeFreqs.end(); I != E; ++I) {
+ unsigned i = 0;
+ for (; i != Counts.size() && Counts[i].first != I->first; ++i)
+ /*empty*/;
+ if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0));
+ Counts[i].second += I->second;
+ }
+
+ } else {
+ std::cerr << "Block counts are not available!\n";
+ }
return;
}