[llvm-commits] [llvm] r81359 - in /llvm/trunk: include/llvm/Analysis/ProfileInfo.h lib/Analysis/ProfileInfo.cpp

Andreas Neustifter astifter-llvm at gmx.at
Wed Sep 9 10:52:58 PDT 2009


Author: astifter
Date: Wed Sep  9 12:52:57 2009
New Revision: 81359

URL: http://llvm.org/viewvc/llvm-project?rev=81359&view=rev
Log:
Add the first functions for updating ProfileInfo.

Modified:
    llvm/trunk/include/llvm/Analysis/ProfileInfo.h
    llvm/trunk/lib/Analysis/ProfileInfo.cpp

Modified: llvm/trunk/include/llvm/Analysis/ProfileInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileInfo.h?rev=81359&r1=81358&r2=81359&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/ProfileInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/ProfileInfo.h Wed Sep  9 12:52:57 2009
@@ -102,7 +102,26 @@
     //===------------------------------------------------------------------===//
     /// Analysis Update Methods
     ///
+    void removeBlock(const BasicBlock *BB) {
+      std::map<const Function*, BlockCounts>::iterator J =
+        BlockInformation.find(BB->getParent());
+      if (J == BlockInformation.end()) return;
 
+      J->second.erase(BB);
+    }
+
+    void removeEdge(Edge e) {
+      std::map<const Function*, EdgeWeights>::iterator J =
+        EdgeInformation.find(getFunction(e));
+      if (J == EdgeInformation.end()) return;
+
+      J->second.erase(e);
+    }
+
+    void splitEdge(const BasicBlock *FirstBB, const BasicBlock *SecondBB,
+                   const BasicBlock *NewBB, bool MergeIdenticalEdges = false);
+
+    void replaceAllUses(const BasicBlock *RmBB, const BasicBlock *DestBB);
   };
 
   /// createProfileLoaderPass - This function returns a Pass that loads the

Modified: llvm/trunk/lib/Analysis/ProfileInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileInfo.cpp?rev=81359&r1=81358&r2=81359&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ProfileInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/ProfileInfo.cpp Wed Sep  9 12:52:57 2009
@@ -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 @@
   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");





More information about the llvm-commits mailing list