//===- 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 occurrences of RmBB in the ProfilingInfo with DestBB.
/// This checks all edges of the function the blocks reside in and replaces the
/// occurrences 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 receiving 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(); }
