summaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorAndreas Neustifter <astifter-llvm@gmx.at>2009-09-09 17:52:57 +0000
committerAndreas Neustifter <astifter-llvm@gmx.at>2009-09-09 17:52:57 +0000
commit07abe17bd2f18eb0279663f686f84997527a238c (patch)
treed044d4c7631ca57b5a6dd003c64cfcf559fe3c14 /lib/Analysis
parent7fd7061de03ca8987e9997e498b67efb6d614fde (diff)
downloadllvm-07abe17bd2f18eb0279663f686f84997527a238c.tar.gz
llvm-07abe17bd2f18eb0279663f686f84997527a238c.tar.bz2
llvm-07abe17bd2f18eb0279663f686f84997527a238c.tar.xz
Add the first functions for updating ProfileInfo.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81359 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/ProfileInfo.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/lib/Analysis/ProfileInfo.cpp b/lib/Analysis/ProfileInfo.cpp
index 55c5cab751..9efdd23081 100644
--- a/lib/Analysis/ProfileInfo.cpp
+++ b/lib/Analysis/ProfileInfo.cpp
@@ -17,7 +17,9 @@
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Format.h"
#include <set>
using namespace llvm;
@@ -82,6 +84,87 @@ double ProfileInfo::getExecutionCount(const Function *F) {
return Count;
}
+/// Replaces all occurences of RmBB in the ProfilingInfo with DestBB.
+/// This checks all edges of the function the blocks reside in and replaces the
+/// occurences of RmBB with DestBB.
+void ProfileInfo::replaceAllUses(const BasicBlock *RmBB,
+ const BasicBlock *DestBB) {
+ DEBUG(errs() << "Replacing " << RmBB->getNameStr()
+ << " with " << DestBB->getNameStr() << "\n");
+ const Function *F = DestBB->getParent();
+ std::map<const Function*, EdgeWeights>::iterator J =
+ EdgeInformation.find(F);
+ if (J == EdgeInformation.end()) return;
+
+ for (EdgeWeights::iterator I = J->second.begin(), E = J->second.end();
+ I != E; ++I) {
+ Edge e = I->first;
+ Edge newedge; bool foundedge = false;
+ if (e.first == RmBB) {
+ newedge = getEdge(DestBB, e.second);
+ foundedge = true;
+ }
+ if (e.second == RmBB) {
+ newedge = getEdge(e.first, DestBB);
+ foundedge = true;
+ }
+ if (foundedge) {
+ double w = getEdgeWeight(e);
+ EdgeInformation[F][newedge] = w;
+ DEBUG(errs() << "Replacing " << e << " with " << newedge << "\n");
+ J->second.erase(e);
+ }
+ }
+}
+
+/// Splits an edge in the ProfileInfo and redirects flow over NewBB.
+/// Since its possible that there is more than one edge in the CFG from FristBB
+/// to SecondBB its necessary to redirect the flow proporionally.
+void ProfileInfo::splitEdge(const BasicBlock *FirstBB,
+ const BasicBlock *SecondBB,
+ const BasicBlock *NewBB,
+ bool MergeIdenticalEdges) {
+ const Function *F = FirstBB->getParent();
+ std::map<const Function*, EdgeWeights>::iterator J =
+ EdgeInformation.find(F);
+ if (J == EdgeInformation.end()) return;
+
+ // Generate edges and read current weight.
+ Edge e = getEdge(FirstBB, SecondBB);
+ Edge n1 = getEdge(FirstBB, NewBB);
+ Edge n2 = getEdge(NewBB, SecondBB);
+ EdgeWeights &ECs = J->second;
+ double w = ECs[e];
+
+ int succ_count = 0;
+ if (!MergeIdenticalEdges) {
+ // First count the edges from FristBB to SecondBB, if there is more than
+ // one, only slice out a proporional part for NewBB.
+ for(succ_const_iterator BBI = succ_begin(FirstBB), BBE = succ_end(FirstBB);
+ BBI != BBE; ++BBI) {
+ if (*BBI == SecondBB) succ_count++;
+ }
+ // When the NewBB is completely new, increment the count by one so that
+ // the counts are properly distributed.
+ if (getExecutionCount(NewBB) == ProfileInfo::MissingValue) succ_count++;
+ } else {
+ // When the edges are merged anyway, then redirect all flow.
+ succ_count = 1;
+ }
+
+ // We know now how many edges there are from FirstBB to SecondBB, reroute a
+ // proportional part of the edge weight over NewBB.
+ double neww = w / succ_count;
+ ECs[n1] += neww;
+ ECs[n2] += neww;
+ BlockInformation[F][NewBB] += neww;
+ if (succ_count == 1) {
+ ECs.erase(e);
+ } else {
+ ECs[e] -= neww;
+ }
+}
+
raw_ostream& llvm::operator<<(raw_ostream &O, ProfileInfo::Edge E) {
O << "(";
O << (E.first ? E.first->getNameStr() : "0");