diff options
author | Chris Lattner <sabre@nondot.org> | 2004-03-08 20:03:52 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-03-08 20:03:52 +0000 |
commit | dbbbfef165ef730977d948e58b226e1bd8f450d4 (patch) | |
tree | ae5d1699fdbb2829cc0e53bc300529ed9c9d79b7 /lib/Analysis | |
parent | 9f717ef279f4b82e28c341c98a9aa602f01f9b27 (diff) | |
download | external_llvm-dbbbfef165ef730977d948e58b226e1bd8f450d4.zip external_llvm-dbbbfef165ef730977d948e58b226e1bd8f450d4.tar.gz external_llvm-dbbbfef165ef730977d948e58b226e1bd8f450d4.tar.bz2 |
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')
-rw-r--r-- | lib/Analysis/ProfileInfoLoader.cpp | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/lib/Analysis/ProfileInfoLoader.cpp b/lib/Analysis/ProfileInfoLoader.cpp index cef0897..6c3f0d7 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; } |