summaryrefslogtreecommitdiff
path: root/lib/Analysis/ProfileInfo.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-08 22:04:08 +0000
committerChris Lattner <sabre@nondot.org>2004-03-08 22:04:08 +0000
commit96ab5caf2db23939c21c36d9468fa6c95e23129d (patch)
treeb03e785eb8b0154a88673947698e2dbf5c5c29c4 /lib/Analysis/ProfileInfo.cpp
parent7d84dda56044b9731aea613a26ff98c8ceb3b5f9 (diff)
downloadllvm-96ab5caf2db23939c21c36d9468fa6c95e23129d.tar.gz
llvm-96ab5caf2db23939c21c36d9468fa6c95e23129d.tar.bz2
llvm-96ab5caf2db23939c21c36d9468fa6c95e23129d.tar.xz
Switch to using edge profiling information as the basic source of profile info
from using basic block counts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12242 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ProfileInfo.cpp')
-rw-r--r--lib/Analysis/ProfileInfo.cpp52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/Analysis/ProfileInfo.cpp b/lib/Analysis/ProfileInfo.cpp
index a96dc4f2fc..8cb1e00176 100644
--- a/lib/Analysis/ProfileInfo.cpp
+++ b/lib/Analysis/ProfileInfo.cpp
@@ -14,6 +14,8 @@
#include "llvm/Analysis/ProfileInfo.h"
#include "llvm/Pass.h"
+#include "llvm/Support/CFG.h"
+#include <set>
using namespace llvm;
// Register the ProfileInfo interface, providing a nice name to refer to.
@@ -23,6 +25,56 @@ namespace {
ProfileInfo::~ProfileInfo() {}
+unsigned ProfileInfo::getExecutionCount(BasicBlock *BB) const {
+ pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
+
+ // Are there zero predecessors of this block?
+ if (PI == PE) {
+ // If this is the entry block, look for the Null -> Entry edge.
+ if (BB == &BB->getParent()->front())
+ return getEdgeWeight(0, BB);
+ else
+ return 0; // Otherwise, this is a dead block.
+ }
+
+ // Otherwise, if there are predecessors, the execution count of this block is
+ // the sum of the edge frequencies from the incoming edges. Note that if
+ // there are multiple edges from a predecessor to this block that we don't
+ // want to count its weight multiple times. For this reason, we keep track of
+ // the predecessors we've seen and only count them if we haven't run into them
+ // yet.
+ //
+ // We don't want to create an std::set unless we are dealing with a block that
+ // has a LARGE number of in-edges. Handle the common case of having only a
+ // few in-edges with special code.
+ //
+ BasicBlock *FirstPred = *PI;
+ unsigned Count = getEdgeWeight(FirstPred, BB);
+ ++PI;
+ if (PI == PE) return Count; // Quick exit for single predecessor blocks
+
+ BasicBlock *SecondPred = *PI;
+ if (SecondPred != FirstPred) Count += getEdgeWeight(SecondPred, BB);
+ ++PI;
+ if (PI == PE) return Count; // Quick exit for two predecessor blocks
+
+ BasicBlock *ThirdPred = *PI;
+ if (ThirdPred != FirstPred && ThirdPred != SecondPred)
+ Count += getEdgeWeight(ThirdPred, BB);
+ ++PI;
+ if (PI == PE) return Count; // Quick exit for three predecessor blocks
+
+ std::set<BasicBlock*> ProcessedPreds;
+ ProcessedPreds.insert(FirstPred);
+ ProcessedPreds.insert(SecondPred);
+ ProcessedPreds.insert(ThirdPred);
+ for (; PI != PE; ++PI)
+ if (ProcessedPreds.insert(*PI).second)
+ Count += getEdgeWeight(*PI, BB);
+ return Count;
+}
+
+
//===----------------------------------------------------------------------===//
// NoProfile ProfileInfo implementation