//===- ProfileInfo.cpp - Profile Info Interface ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the abstract ProfileInfo interface, and the default
// "no profile" implementation.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "profile-info"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ProfileInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/ADT/SmallSet.h"
#include <set>
#include <queue>
#include <limits>
using namespace llvm;

namespace llvm {
  template<> char ProfileInfoT<Function,BasicBlock>::ID = 0;
}

// Register the ProfileInfo interface, providing a nice name to refer to.
INITIALIZE_ANALYSIS_GROUP(ProfileInfo, "Profile Information", NoProfileInfo)

namespace llvm {

template <>
ProfileInfoT<MachineFunction, MachineBasicBlock>::ProfileInfoT() {}
template <>
ProfileInfoT<MachineFunction, MachineBasicBlock>::~ProfileInfoT() {}

template <>
ProfileInfoT<Function, BasicBlock>::ProfileInfoT() {
  MachineProfile = 0;
}
template <>
ProfileInfoT<Function, BasicBlock>::~ProfileInfoT() {
  if (MachineProfile) delete MachineProfile;
}

template<>
char ProfileInfoT<MachineFunction, MachineBasicBlock>::ID = 0;

template<>
const double ProfileInfoT<Function,BasicBlock>::MissingValue = -1;

template<> const
double ProfileInfoT<MachineFunction, MachineBasicBlock>::MissingValue = -1;

template<> double
ProfileInfoT<Function,BasicBlock>::getExecutionCount(const BasicBlock *BB) {
  std::map<const Function*, BlockCounts>::iterator J =
    BlockInformation.find(BB->getParent());
  if (J != BlockInformation.end()) {
    BlockCounts::iterator I = J->second.find(BB);
    if (I != J->second.end())
      return I->second;
  }

  double Count = MissingValue;

  const_pred_iterator PI = pred_begin(BB), PE = pred_end(BB);

  // Are there zero predecessors of this block?
  if (PI == PE) {
    Edge e = getEdge(0, BB);
    Count = getEdgeWeight(e);
  } else {
    // Otherwise, if there are predecessors, the execution count of this block is
    // the sum of the edge frequencies from the incoming edges.
    std::set<const BasicBlock*> ProcessedPreds;
    Count = 0;
    for (; PI != PE; ++PI) {
      const BasicBlock *P = *PI;
      if (ProcessedPreds.insert(P).second) {
        double w = getEdgeWeight(getEdge(P, BB));
        if (w == MissingValue) {
          Count = MissingValue;
          break;
        }
        Count += w;
      }
    }
  }

  // If the predecessors did not suffice to get block weight, try successors.
  if (Count == MissingValue) {

    succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB);

    // Are there zero successors of this block?
    if (SI == SE) {
      Edge e = getEdge(BB,0);
      Count = getEdgeWeight(e);
    } else {
      std::set<const BasicBlock*> ProcessedSuccs;
      Count = 0;
      for (; SI != SE; ++SI)
        if (ProcessedSuccs.insert(*SI).second) {
          double w = getEdgeWeight(getEdge(BB, *SI));
          if (w == MissingValue) {
            Count = MissingValue;
            break;
          }
          Count += w;
        }
    }
  }

  if (Count != MissingValue) BlockInformation[BB->getParent()][BB] = Count;
  return Count;
}

template<>
double ProfileInfoT<MachineFunction, MachineBasicBlock>::
        getExecutionCount(const MachineBasicBlock *MBB) {
  std::map<const MachineFunction*, BlockCounts>::iterator J =
    BlockInformation.find(MBB->getParent());
  if (J != BlockInformation.end()) {
    BlockCounts::iterator I = J->second.find(MBB);
    if (I != J->second.end())
      return I->second;
  }

  return MissingValue;
}

template<>
double ProfileInfoT<Function,BasicBlock>::getExecutionCount(const Function *F) {
  std::map<const Function*, double>::iterator J =
    FunctionInformation.find(F);
  if (J != FunctionInformation.end())
    return J->second;

  // isDeclaration() is checked here and not at start of function to allow
  // functions without a body still to have a execution count.
  if (F->isDeclaration()) return MissingValue;

  double Count = getExecutionCount(&F->getEntryBlock());
  if (Count != MissingValue) FunctionInformation[F] = Count;
  return Count;
}

template<>
double ProfileInfoT<MachineFunction, MachineBasicBlock>::
        getExecutionCount(const MachineFunction *MF) {
  std::map<const MachineFunction*, double>::iterator J =
    FunctionInformation.find(MF);
  if (J != FunctionInformation.end())
    return J->second;

  double Count = getExecutionCount(&MF->front());
  if (Count != MissingValue) FunctionInformation[MF] = Count;
  return Count;
}

template<>
void ProfileInfoT<Function,BasicBlock>::
        setExecutionCount(const BasicBlock *BB, double w) {
  DEBUG(dbgs() << "Creating Block " << BB->getName() 
               << " (weight: " << format("%.20g",w) << ")\n");
  BlockInformation[BB->getParent()][BB] = w;
}

template<>
void ProfileInfoT<MachineFunction, MachineBasicBlock>::
        setExecutionCount(const MachineBasicBlock *MBB, double w) {
  DEBUG(dbgs() << "Creating Block " << MBB->getBasicBlock()->getName()
               << " (weight: " << format("%.20g",w) << ")\n");
  BlockInformation[MBB->getParent()][MBB] = w;
}

template<>
void ProfileInfoT<Function,BasicBlock>::addEdgeWeight(Edge e, double w) {
  double oldw = getEdgeWeight(e);
  assert (oldw != MissingValue && "Adding weight to Edge with no previous weight");
  DEBUG(dbgs() << "Adding to Edge " << e
               << " (new weight: " << format("%.20g",oldw + w) << ")\n");
  EdgeInformation[getFunction(e)][e] = oldw + w;
}

template<>
void ProfileInfoT<Function,BasicBlock>::
        addExecutionCount(const BasicBlock *BB, double w) {
  double oldw = getExecutionCount(BB);
  assert (oldw != MissingValue && "Adding weight to Block with no previous weight");
  DEBUG(dbgs() << "Adding to Block " << BB->getName()
               << " (new weight: " << format("%.20g",oldw + w) << ")\n");
  BlockInformation[BB->getParent()][BB] = oldw + w;
}

template<>
void ProfileInfoT<Function,BasicBlock>::removeBlock(const BasicBlock *BB) {
  std::map<const Function*, BlockCounts>::iterator J =
    BlockInformation.find(BB->getParent());
  if (J == BlockInformation.end()) return;

  DEBUG(dbgs() << "Deleting " << BB->getName() << "\n");
  J->second.erase(BB);
}

template<>
void ProfileInfoT<Function,BasicBlock>::removeEdge(Edge e) {
  std::map<const Function*, EdgeWeights>::iterator J =
    EdgeInformation.find(getFunction(e));
  if (J == EdgeInformation.end()) return;

  DEBUG(dbgs() << "Deleting" << e << "\n");
  J->second.erase(e);
}

template<>
void ProfileInfoT<Function,BasicBlock>::
        replaceEdge(const Edge &oldedge, const Edge &newedge) {
  double w;
  if ((w = getEdgeWeight(newedge)) == MissingValue) {
    w = getEdgeWeight(oldedge);
    DEBUG(dbgs() << "Replacing " << oldedge << " with " << newedge  << "\n");
  } else {
    w += getEdgeWeight(oldedge);
    DEBUG(dbgs() << "Adding " << oldedge << " to " << newedge  << "\n");
  }
  setEdgeWeight(newedge,w);
  removeEdge(oldedge);
}

template<>
const BasicBlock *ProfileInfoT<Function,BasicBlock>::
        GetPath(const BasicBlock *Src, const BasicBlock *Dest,
                Path &P, unsigned Mode) {
  const BasicBlock *BB = 0;
  bool hasFoundPath = false;

  std::queue<const BasicBlock *> BFS;
  BFS.push(Src);

  while(BFS.size() && !hasFoundPath) {
    BB = BFS.front();
    BFS.pop();

    succ_const_iterator Succ = succ_begin(BB), End = succ_end(BB);
    if (Succ == End) {
      P[0] = BB;
      if (Mode & GetPathToExit) {
        hasFoundPath = true;
        BB = 0;
      }
    }
    for(;Succ != End; ++Succ) {
      if (P.find(*Succ) != P.end()) continue;
      Edge e = getEdge(BB,*Succ);
      if ((Mode & GetPathWithNewEdges) && (getEdgeWeight(e) != MissingValue)) continue;
      P[*Succ] = BB;
      BFS.push(*Succ);
      if ((Mode & GetPathToDest) && *Succ == Dest) {
        hasFoundPath = true;
        BB = *Succ;
        break;
      }
      if ((Mode & GetPathToValue) && (getExecutionCount(*Succ) != MissingValue)) {
        hasFoundPath = true;
        BB = *Succ;
        break;
      }
    }
  }

  return BB;
}

template<>
void ProfileInfoT<Function,BasicBlock>::
        divertFlow(const Edge &oldedge, const Edge &newedge) {
  DEBUG(dbgs() << "Diverting " << oldedge << " via " << newedge );

  // First check if the old edge was taken, if not, just delete it...
  if (getEdgeWeight(oldedge) == 0) {
    removeEdge(oldedge);
    return;
  }

  Path P;
  P[newedge.first] = 0;
  P[newedge.second] = newedge.first;
  const BasicBlock *BB = GetPath(newedge.second,oldedge.second,P,GetPathToExit | GetPathToDest);

  double w = getEdgeWeight (oldedge);
  DEBUG(dbgs() << ", Weight: " << format("%.20g",w) << "\n");
  do {
    const BasicBlock *Parent = P.find(BB)->second;
    Edge e = getEdge(Parent,BB);
    double oldw = getEdgeWeight(e);
    double oldc = getExecutionCount(e.first);
    setEdgeWeight(e, w+oldw);
    if (Parent != oldedge.first) {
      setExecutionCount(e.first, w+oldc);
    }
    BB = Parent;
  } while (BB != newedge.first);
  removeEdge(oldedge);
}

/// 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.
template<>
void ProfileInfoT<Function,BasicBlock>::
        replaceAllUses(const BasicBlock *RmBB, const BasicBlock *DestBB) {
  DEBUG(dbgs() << "Replacing " << RmBB->getName()
               << " with " << DestBB->getName() << "\n");
  const Function *F = DestBB->getParent();
  std::map<const Function*, EdgeWeights>::iterator J =
    EdgeInformation.find(F);
  if (J == EdgeInformation.end()) return;

  Edge e, newedge;
  bool erasededge = false;
  EdgeWeights::iterator I = J->second.begin(), E = J->second.end();
  while(I != E) {
    e = (I++)->first;
    bool foundedge = false; bool eraseedge = false;
    if (e.first == RmBB) {
      if (e.second == DestBB) {
        eraseedge = true;
      } else {
        newedge = getEdge(DestBB, e.second);
        foundedge = true;
      }
    }
    if (e.second == RmBB) {
      if (e.first == DestBB) {
        eraseedge = true;
      } else {
        newedge = getEdge(e.first, DestBB);
        foundedge = true;
      }
    }
    if (foundedge) {
      replaceEdge(e, newedge);
    }
    if (eraseedge) {
      if (erasededge) {
        Edge newedge = getEdge(DestBB, DestBB);
        replaceEdge(e, newedge);
      } else {
        removeEdge(e);
        erasededge = true;
      }
    }
  }
}

/// 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.
template<>
void ProfileInfoT<Function,BasicBlock>::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 = floor(w / succ_count);
  ECs[n1] += neww;
  ECs[n2] += neww;
  BlockInformation[F][NewBB] += neww;
  if (succ_count == 1) {
    ECs.erase(e);
  } else {
    ECs[e] -= neww;
  }
}

template<>
void ProfileInfoT<Function,BasicBlock>::splitBlock(const BasicBlock *Old,
                                                   const BasicBlock* New) {
  const Function *F = Old->getParent();
  std::map<const Function*, EdgeWeights>::iterator J =
    EdgeInformation.find(F);
  if (J == EdgeInformation.end()) return;

  DEBUG(dbgs() << "Splitting " << Old->getName() << " to " << New->getName() << "\n");

  std::set<Edge> Edges;
  for (EdgeWeights::iterator ewi = J->second.begin(), ewe = J->second.end(); 
       ewi != ewe; ++ewi) {
    Edge old = ewi->first;
    if (old.first == Old) {
      Edges.insert(old);
    }
  }
  for (std::set<Edge>::iterator EI = Edges.begin(), EE = Edges.end(); 
       EI != EE; ++EI) {
    Edge newedge = getEdge(New, EI->second);
    replaceEdge(*EI, newedge);
  }

  double w = getExecutionCount(Old);
  setEdgeWeight(getEdge(Old, New), w);
  setExecutionCount(New, w);
}

template<>
void ProfileInfoT<Function,BasicBlock>::splitBlock(const BasicBlock *BB,
                                                   const BasicBlock* NewBB,
                                                   BasicBlock *const *Preds,
                                                   unsigned NumPreds) {
  const Function *F = BB->getParent();
  std::map<const Function*, EdgeWeights>::iterator J =
    EdgeInformation.find(F);
  if (J == EdgeInformation.end()) return;

  DEBUG(dbgs() << "Splitting " << NumPreds << " Edges from " << BB->getName() 
               << " to " << NewBB->getName() << "\n");

  // Collect weight that was redirected over NewBB.
  double newweight = 0;
  
  std::set<const BasicBlock *> ProcessedPreds;
  // For all requestes Predecessors.
  for (unsigned pred = 0; pred < NumPreds; ++pred) {
    const BasicBlock * Pred = Preds[pred];
    if (ProcessedPreds.insert(Pred).second) {
      // Create edges and read old weight.
      Edge oldedge = getEdge(Pred, BB);
      Edge newedge = getEdge(Pred, NewBB);

      // Remember how much weight was redirected.
      newweight += getEdgeWeight(oldedge);
    
      replaceEdge(oldedge,newedge);
    }
  }

  Edge newedge = getEdge(NewBB,BB);
  setEdgeWeight(newedge, newweight);
  setExecutionCount(NewBB, newweight);
}

template<>
void ProfileInfoT<Function,BasicBlock>::transfer(const Function *Old,
                                                 const Function *New) {
  DEBUG(dbgs() << "Replacing Function " << Old->getName() << " with "
               << New->getName() << "\n");
  std::map<const Function*, EdgeWeights>::iterator J =
    EdgeInformation.find(Old);
  if(J != EdgeInformation.end()) {
    EdgeInformation[New] = J->second;
  }
  EdgeInformation.erase(Old);
  BlockInformation.erase(Old);
  FunctionInformation.erase(Old);
}

static double readEdgeOrRemember(ProfileInfo::Edge edge, double w,
                                 ProfileInfo::Edge &tocalc, unsigned &uncalc) {
  if (w == ProfileInfo::MissingValue) {
    tocalc = edge;
    uncalc++;
    return 0;
  } else {
    return w;
  }
}

template<>
bool ProfileInfoT<Function,BasicBlock>::
        CalculateMissingEdge(const BasicBlock *BB, Edge &removed,
                             bool assumeEmptySelf) {
  Edge edgetocalc;
  unsigned uncalculated = 0;

  // collect weights of all incoming and outgoing edges, rememer edges that
  // have no value
  double incount = 0;
  SmallSet<const BasicBlock*,8> pred_visited;
  const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
  if (bbi==bbe) {
    Edge e = getEdge(0,BB);
    incount += readEdgeOrRemember(e, getEdgeWeight(e) ,edgetocalc,uncalculated);
  }
  for (;bbi != bbe; ++bbi) {
    if (pred_visited.insert(*bbi)) {
      Edge e = getEdge(*bbi,BB);
      incount += readEdgeOrRemember(e, getEdgeWeight(e) ,edgetocalc,uncalculated);
    }
  }

  double outcount = 0;
  SmallSet<const BasicBlock*,8> succ_visited;
  succ_const_iterator sbbi = succ_begin(BB), sbbe = succ_end(BB);
  if (sbbi==sbbe) {
    Edge e = getEdge(BB,0);
    if (getEdgeWeight(e) == MissingValue) {
      double w = getExecutionCount(BB);
      if (w != MissingValue) {
        setEdgeWeight(e,w);
        removed = e;
      }
    }
    outcount += readEdgeOrRemember(e, getEdgeWeight(e), edgetocalc, uncalculated);
  }
  for (;sbbi != sbbe; ++sbbi) {
    if (succ_visited.insert(*sbbi)) {
      Edge e = getEdge(BB,*sbbi);
      outcount += readEdgeOrRemember(e, getEdgeWeight(e), edgetocalc, uncalculated);
    }
  }

  // if exactly one edge weight was missing, calculate it and remove it from
  // spanning tree
  if (uncalculated == 0 ) {
    return true;
  } else
  if (uncalculated == 1) {
    if (incount < outcount) {
      EdgeInformation[BB->getParent()][edgetocalc] = outcount-incount;
    } else {
      EdgeInformation[BB->getParent()][edgetocalc] = incount-outcount;
    }
    DEBUG(dbgs() << "--Calc Edge Counter for " << edgetocalc << ": "
                 << format("%.20g", getEdgeWeight(edgetocalc)) << "\n");
    removed = edgetocalc;
    return true;
  } else 
  if (uncalculated == 2 && assumeEmptySelf && edgetocalc.first == edgetocalc.second && incount == outcount) {
    setEdgeWeight(edgetocalc, incount * 10);
    removed = edgetocalc;
    return true;
  } else {
    return false;
  }
}

static void readEdge(ProfileInfo *PI, ProfileInfo::Edge e, double &calcw, std::set<ProfileInfo::Edge> &misscount) {
  double w = PI->getEdgeWeight(e);
  if (w != ProfileInfo::MissingValue) {
    calcw += w;
  } else {
    misscount.insert(e);
  }
}

template<>
bool ProfileInfoT<Function,BasicBlock>::EstimateMissingEdges(const BasicBlock *BB) {
  double inWeight = 0;
  std::set<Edge> inMissing;
  std::set<const BasicBlock*> ProcessedPreds;
  const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
  if (bbi == bbe) {
    readEdge(this,getEdge(0,BB),inWeight,inMissing);
  }
  for( ; bbi != bbe; ++bbi ) {
    if (ProcessedPreds.insert(*bbi).second) {
      readEdge(this,getEdge(*bbi,BB),inWeight,inMissing);
    }
  }

  double outWeight = 0;
  std::set<Edge> outMissing;
  std::set<const BasicBlock*> ProcessedSuccs;
  succ_const_iterator sbbi = succ_begin(BB), sbbe = succ_end(BB);
  if (sbbi == sbbe)
    readEdge(this,getEdge(BB,0),outWeight,outMissing);
  for ( ; sbbi != sbbe; ++sbbi ) {
    if (ProcessedSuccs.insert(*sbbi).second) {
      readEdge(this,getEdge(BB,*sbbi),outWeight,outMissing);
    }
  }

  double share;
  std::set<Edge>::iterator ei,ee;
  if (inMissing.size() == 0 && outMissing.size() > 0) {
    ei = outMissing.begin();
    ee = outMissing.end();
    share = inWeight/outMissing.size();
    setExecutionCount(BB,inWeight);
  } else
  if (inMissing.size() > 0 && outMissing.size() == 0 && outWeight == 0) {
    ei = inMissing.begin();
    ee = inMissing.end();
    share = 0;
    setExecutionCount(BB,0);
  } else
  if (inMissing.size() == 0 && outMissing.size() == 0) {
    setExecutionCount(BB,outWeight);
    return true;
  } else {
    return false;
  }
  for ( ; ei != ee; ++ei ) {
    setEdgeWeight(*ei,share);
  }
  return true;
}

template<>
void ProfileInfoT<Function,BasicBlock>::repair(const Function *F) {
//  if (getExecutionCount(&(F->getEntryBlock())) == 0) {
//    for (Function::const_iterator FI = F->begin(), FE = F->end();
//         FI != FE; ++FI) {
//      const BasicBlock* BB = &(*FI);
//      {
//        const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
//        if (NBB == End) {
//          setEdgeWeight(getEdge(0,BB),0);
//        }
//        for(;NBB != End; ++NBB) {
//          setEdgeWeight(getEdge(*NBB,BB),0);
//        }
//      }
//      {
//        succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
//        if (NBB == End) {
//          setEdgeWeight(getEdge(0,BB),0);
//        }
//        for(;NBB != End; ++NBB) {
//          setEdgeWeight(getEdge(*NBB,BB),0);
//        }
//      }
//    }
//    return;
//  }
  // The set of BasicBlocks that are still unvisited.
  std::set<const BasicBlock*> Unvisited;

  // The set of return edges (Edges with no successors).
  std::set<Edge> ReturnEdges;
  double ReturnWeight = 0;
  
  // First iterate over the whole function and collect:
  // 1) The blocks in this function in the Unvisited set.
  // 2) The return edges in the ReturnEdges set.
  // 3) The flow that is leaving the function already via return edges.

  // Data structure for searching the function.
  std::queue<const BasicBlock *> BFS;
  const BasicBlock *BB = &(F->getEntryBlock());
  BFS.push(BB);
  Unvisited.insert(BB);

  while (BFS.size()) {
    BB = BFS.front(); BFS.pop();
    succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
    if (NBB == End) {
      Edge e = getEdge(BB,0);
      double w = getEdgeWeight(e);
      if (w == MissingValue) {
        // If the return edge has no value, try to read value from block.
        double bw = getExecutionCount(BB);
        if (bw != MissingValue) {
          setEdgeWeight(e,bw);
          ReturnWeight += bw;
        } else {
          // If both return edge and block provide no value, collect edge.
          ReturnEdges.insert(e);
        }
      } else {
        // If the return edge has a proper value, collect it.
        ReturnWeight += w;
      }
    }
    for (;NBB != End; ++NBB) {
      if (Unvisited.insert(*NBB).second) {
        BFS.push(*NBB);
      }
    }
  }

  while (Unvisited.size() > 0) {
    unsigned oldUnvisitedCount = Unvisited.size();
    bool FoundPath = false;

    // If there is only one edge left, calculate it.
    if (ReturnEdges.size() == 1) {
      ReturnWeight = getExecutionCount(&(F->getEntryBlock())) - ReturnWeight;

      Edge e = *ReturnEdges.begin();
      setEdgeWeight(e,ReturnWeight);
      setExecutionCount(e.first,ReturnWeight);

      Unvisited.erase(e.first);
      ReturnEdges.erase(e);
      continue;
    }

    // Calculate all blocks where only one edge is missing, this may also
    // resolve furhter return edges.
    std::set<const BasicBlock *>::iterator FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE) {
      const BasicBlock *BB = *FI; ++FI;
      Edge e;
      if(CalculateMissingEdge(BB,e,true)) {
        if (BlockInformation[F].find(BB) == BlockInformation[F].end()) {
          setExecutionCount(BB,getExecutionCount(BB));
        }
        Unvisited.erase(BB);
        if (e.first != 0 && e.second == 0) {
          ReturnEdges.erase(e);
          ReturnWeight += getEdgeWeight(e);
        }
      }
    }
    if (oldUnvisitedCount > Unvisited.size()) continue;

    // Estimate edge weights by dividing the flow proportionally.
    FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE) {
      const BasicBlock *BB = *FI; ++FI;
      const BasicBlock *Dest = 0;
      bool AllEdgesHaveSameReturn = true;
      // Check each Successor, these must all end up in the same or an empty
      // return block otherwise its dangerous to do an estimation on them.
      for (succ_const_iterator Succ = succ_begin(BB), End = succ_end(BB);
           Succ != End; ++Succ) {
        Path P;
        GetPath(*Succ, 0, P, GetPathToExit);
        if (Dest && Dest != P[0]) {
          AllEdgesHaveSameReturn = false;
        }
        Dest = P[0];
      }
      if (AllEdgesHaveSameReturn) {
        if(EstimateMissingEdges(BB)) {
          Unvisited.erase(BB);
          break;
        }
      }
    }
    if (oldUnvisitedCount > Unvisited.size()) continue;

    // Check if there is a path to an block that has a known value and redirect
    // flow accordingly.
    FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE && !FoundPath) {
      // Fetch path.
      const BasicBlock *BB = *FI; ++FI;
      Path P;
      const BasicBlock *Dest = GetPath(BB, 0, P, GetPathToValue);

      // Calculate incoming flow.
      double iw = 0; unsigned inmissing = 0; unsigned incount = 0; unsigned invalid = 0;
      std::set<const BasicBlock *> Processed;
      for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
           NBB != End; ++NBB) {
        if (Processed.insert(*NBB).second) {
          Edge e = getEdge(*NBB, BB);
          double ew = getEdgeWeight(e);
          if (ew != MissingValue) {
            iw += ew;
            invalid++;
          } else {
            // If the path contains the successor, this means its a backedge,
            // do not count as missing.
            if (P.find(*NBB) == P.end())
              inmissing++;
          }
          incount++;
        }
      }
      if (inmissing == incount) continue;
      if (invalid == 0) continue;

      // Subtract (already) outgoing flow.
      Processed.clear();
      for (succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
           NBB != End; ++NBB) {
        if (Processed.insert(*NBB).second) {
          Edge e = getEdge(BB, *NBB);
          double ew = getEdgeWeight(e);
          if (ew != MissingValue) {
            iw -= ew;
          }
        }
      }
      if (iw < 0) continue;

      // Check the recieving end of the path if it can handle the flow.
      double ow = getExecutionCount(Dest);
      Processed.clear();
      for (succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
           NBB != End; ++NBB) {
        if (Processed.insert(*NBB).second) {
          Edge e = getEdge(BB, *NBB);
          double ew = getEdgeWeight(e);
          if (ew != MissingValue) {
            ow -= ew;
          }
        }
      }
      if (ow < 0) continue;

      // Determine how much flow shall be used.
      double ew = getEdgeWeight(getEdge(P[Dest],Dest));
      if (ew != MissingValue) {
        ew = ew<ow?ew:ow;
        ew = ew<iw?ew:iw;
      } else {
        if (inmissing == 0)
          ew = iw;
      }

      // Create flow.
      if (ew != MissingValue) {
        do {
          Edge e = getEdge(P[Dest],Dest);
          if (getEdgeWeight(e) == MissingValue) {
            setEdgeWeight(e,ew);
            FoundPath = true;
          }
          Dest = P[Dest];
        } while (Dest != BB);
      }
    }
    if (FoundPath) continue;

    // Calculate a block with self loop.
    FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE && !FoundPath) {
      const BasicBlock *BB = *FI; ++FI;
      bool SelfEdgeFound = false;
      for (succ_const_iterator NBB = succ_begin(BB), End = succ_end(BB);
           NBB != End; ++NBB) {
        if (*NBB == BB) {
          SelfEdgeFound = true;
          break;
        }
      }
      if (SelfEdgeFound) {
        Edge e = getEdge(BB,BB);
        if (getEdgeWeight(e) == MissingValue) {
          double iw = 0;
          std::set<const BasicBlock *> Processed;
          for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
               NBB != End; ++NBB) {
            if (Processed.insert(*NBB).second) {
              Edge e = getEdge(*NBB, BB);
              double ew = getEdgeWeight(e);
              if (ew != MissingValue) {
                iw += ew;
              }
            }
          }
          setEdgeWeight(e,iw * 10);
          FoundPath = true;
        }
      }
    }
    if (FoundPath) continue;

    // Determine backedges, set them to zero.
    FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE && !FoundPath) {
      const BasicBlock *BB = *FI; ++FI;
      const BasicBlock *Dest = 0;
      Path P;
      bool BackEdgeFound = false;
      for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
           NBB != End; ++NBB) {
        Dest = GetPath(BB, *NBB, P, GetPathToDest | GetPathWithNewEdges);
        if (Dest == *NBB) {
          BackEdgeFound = true;
          break;
        }
      }
      if (BackEdgeFound) {
        Edge e = getEdge(Dest,BB);
        double w = getEdgeWeight(e);
        if (w == MissingValue) {
          setEdgeWeight(e,0);
          FoundPath = true;
        }
        do {
          Edge e = getEdge(P[Dest], Dest);
          double w = getEdgeWeight(e);
          if (w == MissingValue) {
            setEdgeWeight(e,0);
            FoundPath = true;
          }
          Dest = P[Dest];
        } while (Dest != BB);
      }
    }
    if (FoundPath) continue;

    // Channel flow to return block.
    FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE && !FoundPath) {
      const BasicBlock *BB = *FI; ++FI;

      Path P;
      const BasicBlock *Dest = GetPath(BB, 0, P, GetPathToExit | GetPathWithNewEdges);
      Dest = P[0];
      if (!Dest) continue;

      if (getEdgeWeight(getEdge(Dest,0)) == MissingValue) {
        // Calculate incoming flow.
        double iw = 0;
        std::set<const BasicBlock *> Processed;
        for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
             NBB != End; ++NBB) {
          if (Processed.insert(*NBB).second) {
            Edge e = getEdge(*NBB, BB);
            double ew = getEdgeWeight(e);
            if (ew != MissingValue) {
              iw += ew;
            }
          }
        }
        do {
          Edge e = getEdge(P[Dest], Dest);
          double w = getEdgeWeight(e);
          if (w == MissingValue) {
            setEdgeWeight(e,iw);
            FoundPath = true;
          } else {
            assert(0 && "Edge should not have value already!");
          }
          Dest = P[Dest];
        } while (Dest != BB);
      }
    }
    if (FoundPath) continue;

    // Speculatively set edges to zero.
    FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE && !FoundPath) {
      const BasicBlock *BB = *FI; ++FI;

      for (const_pred_iterator NBB = pred_begin(BB), End = pred_end(BB);
           NBB != End; ++NBB) {
        Edge e = getEdge(*NBB,BB);
        double w = getEdgeWeight(e);
        if (w == MissingValue) {
          setEdgeWeight(e,0);
          FoundPath = true;
          break;
        }
      }
    }
    if (FoundPath) continue;

    errs() << "{";
    FI = Unvisited.begin(), FE = Unvisited.end();
    while(FI != FE) {
      const BasicBlock *BB = *FI; ++FI;
      dbgs() << BB->getName();
      if (FI != FE)
        dbgs() << ",";
    }
    errs() << "}";

    errs() << "ASSERT: could not repair function";
    assert(0 && "could not repair function");
  }

  EdgeWeights J = EdgeInformation[F];
  for (EdgeWeights::iterator EI = J.begin(), EE = J.end(); EI != EE; ++EI) {
    Edge e = EI->first;

    bool SuccFound = false;
    if (e.first != 0) {
      succ_const_iterator NBB = succ_begin(e.first), End = succ_end(e.first);
      if (NBB == End) {
        if (0 == e.second) {
          SuccFound = true;
        }
      }
      for (;NBB != End; ++NBB) {
        if (*NBB == e.second) {
          SuccFound = true;
          break;
        }
      }
      if (!SuccFound) {
        removeEdge(e);
      }
    }
  }
}

raw_ostream& operator<<(raw_ostream &O, const Function *F) {
  return O << F->getName();
}

raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF) {
  return O << MF->getFunction()->getName() << "(MF)";
}

raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB) {
  return O << BB->getName();
}

raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB) {
  return O << MBB->getBasicBlock()->getName() << "(MB)";
}

raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E) {
  O << "(";

  if (E.first)
    O << E.first;
  else
    O << "0";

  O << ",";

  if (E.second)
    O << E.second;
  else
    O << "0";

  return O << ")";
}

raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E) {
  O << "(";

  if (E.first)
    O << E.first;
  else
    O << "0";

  O << ",";

  if (E.second)
    O << E.second;
  else
    O << "0";

  return O << ")";
}

} // namespace llvm

//===----------------------------------------------------------------------===//
//  NoProfile ProfileInfo implementation
//

namespace {
  struct NoProfileInfo : public ImmutablePass, public ProfileInfo {
    static char ID; // Class identification, replacement for typeinfo
    NoProfileInfo() : ImmutablePass(ID) {
      initializeNoProfileInfoPass(*PassRegistry::getPassRegistry());
    }
    
    /// getAdjustedAnalysisPointer - This method is used when a pass implements
    /// an analysis interface through multiple inheritance.  If needed, it
    /// should override this to adjust the this pointer as needed for the
    /// specified pass info.
    virtual void *getAdjustedAnalysisPointer(AnalysisID PI) {
      if (PI == &ProfileInfo::ID)
        return (ProfileInfo*)this;
      return this;
    }
    
    virtual const char *getPassName() const {
      return "NoProfileInfo";
    }
  };
}  // End of anonymous namespace

char NoProfileInfo::ID = 0;
// Register this pass...
INITIALIZE_AG_PASS(NoProfileInfo, ProfileInfo, "no-profile",
                   "No Profile Information", false, true, true)

ImmutablePass *llvm::createNoProfileInfoPass() { return new NoProfileInfo(); }
