Incorporated changes in alloca and getElementPointer instruction
[oota-llvm.git] / lib / Transforms / Instrumentation / ProfilePaths / ProfilePaths.cpp
index a3ddab2d64fa8b9edd3f8a7761ffda8fb5133c6a..cd341920a5518384ce5f9d70432ba6efb1298a64 100644 (file)
 using std::vector;
 
 struct ProfilePaths : public FunctionPass {
-  const char *getPassName() const { return "ProfilePaths"; }
-
   bool runOnFunction(Function &F);
 
   // Before this pass, make sure that there is only one 
   // entry and only one exit node for the function in the CFG of the function
   //
   void ProfilePaths::getAnalysisUsage(AnalysisUsage &AU) const {
-    AU.addRequired(UnifyFunctionExitNodes::ID);
+    AU.addRequired<UnifyFunctionExitNodes>();
   }
 };
 
+static RegisterOpt<ProfilePaths> X("paths", "Profile Paths");
+
 // createProfilePathsPass - Create a new pass to add path profiling
 //
 Pass *createProfilePathsPass() {
@@ -70,16 +70,13 @@ bool ProfilePaths::runOnFunction(Function &F){
 
   static int mn = -1;
 
-  if(F.size() <=1) {
+  if(F.isExternal()) {
     return false;
   }
  
   //increment counter for instrumented functions. mn is now function#
   mn++;
   
-  //std::cerr<<"MN = "<<mn<<"\n";;
-  //std::cerr<<F;
-
   // Transform the cfg s.t. we have just one exit node
   BasicBlock *ExitNode = getAnalysis<UnifyFunctionExitNodes>().getExitNode();  
 
@@ -128,14 +125,17 @@ bool ProfilePaths::runOnFunction(Function &F){
   // The graph is made acyclic: this is done
   // by removing back edges for now, and adding them later on
   vector<Edge> be;
-  g.getBackEdges(be);
-
-  //std::cerr<<"BackEdges-------------\n";
-  //   for(vector<Edge>::iterator VI=be.begin(); VI!=be.end(); ++VI){
-  //printEdge(*VI);
-  //cerr<<"\n";
-  //}
-  //std::cerr<<"------\n";
+  std::map<Node *, int> nodePriority; //it ranks nodes in depth first order traversal
+  g.getBackEdges(be, nodePriority);
+  
+#ifdef DEBUG_PATH_PROFILES
+  std::cerr<<"BackEdges-------------\n";
+  for(vector<Edge>::iterator VI=be.begin(); VI!=be.end(); ++VI){
+    printEdge(*VI);
+    cerr<<"\n";
+  }
+  std::cerr<<"------\n";
+#endif
 
 #ifdef DEBUG_PATH_PROFILES
   cerr<<"Backedges:"<<be.size()<<endl;
@@ -150,19 +150,25 @@ bool ProfilePaths::runOnFunction(Function &F){
   vector<Edge> exDummy;
   addDummyEdges(stDummy, exDummy, g, be);
 
-  //std::cerr<<"After adding dummy edges\n";
-  //printGraph(g);
-    
+#ifdef DEBUG_PATH_PROFILES
+  std::cerr<<"After adding dummy edges\n";
+  printGraph(g);
+#endif
+
   // Now, every edge in the graph is assigned a weight
   // This weight later adds on to assign path
   // numbers to different paths in the graph
   //  All paths for now are acyclic,
   // since no back edges in the graph now
   // numPaths is the number of acyclic paths in the graph
-  int numPaths=valueAssignmentToEdges(g);
+  int numPaths=valueAssignmentToEdges(g, nodePriority, be);
+
+  if(numPaths<=1 || numPaths >5000) return false;
+  
+#ifdef DEBUG_PATH_PROFILES  
+  printGraph(g);
+#endif
 
-  //std::cerr<<"Numpaths="<<numPaths<<std::endl;
-  //printGraph(g);
   //create instruction allocation r and count
   //r is the variable that'll act like an accumulator
   //all along the path, we just add edge values to r
@@ -171,13 +177,13 @@ bool ProfilePaths::runOnFunction(Function &F){
   //the number of executions of path numbered x
 
   Instruction *rVar=new 
-    AllocaInst(PointerType::get(Type::IntTy)
+    AllocaInst(Type::IntTy
                ConstantUInt::get(Type::UIntTy,1),"R");
-    
+
   Instruction *countVar=new 
-    AllocaInst(PointerType::get(Type::IntTy)
+    AllocaInst(Type::IntTy
                ConstantUInt::get(Type::UIntTy, numPaths), "Count");
-    
+  
   // insert initialization code in first (entry) BB
   // this includes initializing r and count
   insertInTopBB(&F.getEntryNode(),numPaths, rVar, countVar);
@@ -186,33 +192,7 @@ bool ProfilePaths::runOnFunction(Function &F){
   //get increments along different paths,
   //and assign "increments" and "updates" (to r and count)
   //"optimally". Finally, insert llvm code along various edges
-  processGraph(g, rVar, countVar, be, stDummy, exDummy, numPaths);    
-  /*
-  //get the paths
-  static std::ofstream to("paths.sizes");
-  static std::ofstream bbs("paths.look");
-  assert(to && "Cannot open file\n");
-  assert(bbs && "Cannot open file\n");
-  for(int i=0;i<numPaths; ++i){
-  std::vector<BasicBlock *> vBB;
-    
-  getBBtrace(vBB, i, M);
-  //get total size of vector
-  int size=0;
-  bbs<<"Meth:"<<mn<<" Path:"<<i<<"\n-------------\n";
-  for(vector<BasicBlock *>::iterator VBI=vBB.begin(); VBI!=vBB.end();
-  ++VBI){
-  BasicBlock *BB=*VBI;
-  size+=BB->size();
-  if(BB==M->front())
-  size-=numPaths;
-  bbs<<BB->getName()<<"->";
-  }
-  bbs<<"\n--------------\n";
-  to<<"::::: "<<mn<<" "<<i<<" "<<size<<"\n";
-  }
-  */
-  //}
-  
+  processGraph(g, rVar, countVar, be, stDummy, exDummy, numPaths, mn);    
+   
   return true;  // Always modifies function
 }