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

Chris Lattner clattner at apple.com
Thu Dec 3 09:47:11 PST 2009


On Dec 3, 2009, at 1:30 AM, Andreas Neustifter wrote:

> Author: astifter
> Date: Thu Dec  3 03:30:12 2009
> New Revision: 90445
>
> URL: http://llvm.org/viewvc/llvm-project?rev=90445&view=rev
> Log:
> Converted ProfileInfo to template, added more API for ProfileInfo- 
> preserving.

Does this have to be a template?  Why not use a base class that keeps  
a map<void*, double> and then have derived classes for LLVM BB and  
MBB's?  This would significantly reduce code size.

-Chris

>
> 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=90445&r1=90444&r2=90445&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/Analysis/ProfileInfo.h (original)
> +++ llvm/trunk/include/llvm/Analysis/ProfileInfo.h Thu Dec  3  
> 03:30:12 2009
> @@ -21,116 +21,228 @@
> #ifndef LLVM_ANALYSIS_PROFILEINFO_H
> #define LLVM_ANALYSIS_PROFILEINFO_H
>
> -#include "llvm/BasicBlock.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/Format.h"
> +#include "llvm/Support/raw_ostream.h"
> #include <cassert>
> #include <string>
> #include <map>
> +#include <set>
>
> namespace llvm {
> -  class Function;
>   class Pass;
>   class raw_ostream;
>
> +  class BasicBlock;
> +  class Function;
> +  class MachineBasicBlock;
> +  class MachineFunction;
> +
> +  // Helper for dumping edges to errs().
> +  raw_ostream& operator<<(raw_ostream &O, std::pair<const  
> BasicBlock *, const BasicBlock *> E);
> +  raw_ostream& operator<<(raw_ostream &O, std::pair<const  
> MachineBasicBlock *, const MachineBasicBlock *> E);
> +
> +  raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB);
> +  raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock  
> *MBB);
> +
> +  raw_ostream& operator<<(raw_ostream &O, const Function *F);
> +  raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF);
> +
>   /// ProfileInfo Class - This class holds and maintains profiling
>   /// information for some unit of code.
> -  class ProfileInfo {
> +  template<class FType, class BType>
> +  class ProfileInfoT {
>   public:
>     // Types for handling profiling information.
> -    typedef std::pair<const BasicBlock*, const BasicBlock*> Edge;
> +    typedef std::pair<const BType*, const BType*> Edge;
>     typedef std::pair<Edge, double> EdgeWeight;
>     typedef std::map<Edge, double> EdgeWeights;
> -    typedef std::map<const BasicBlock*, double> BlockCounts;
> +    typedef std::map<const BType*, double> BlockCounts;
> +    typedef std::map<const BType*, const BType*> Path;
>
>   protected:
>     // EdgeInformation - Count the number of times a transition  
> between two
>     // blocks is executed. As a special case, we also hold an edge  
> from the
>     // null BasicBlock to the entry block to indicate how many times  
> the
>     // function was entered.
> -    std::map<const Function*, EdgeWeights> EdgeInformation;
> +    std::map<const FType*, EdgeWeights> EdgeInformation;
>
>     // BlockInformation - Count the number of times a block is  
> executed.
> -    std::map<const Function*, BlockCounts> BlockInformation;
> +    std::map<const FType*, BlockCounts> BlockInformation;
>
>     // FunctionInformation - Count the number of times a function is  
> executed.
> -    std::map<const Function*, double> FunctionInformation;
> +    std::map<const FType*, double> FunctionInformation;
> +
> +    ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile;
>   public:
>     static char ID; // Class identification, replacement for typeinfo
> -    virtual ~ProfileInfo();  // We want to be subclassed
> +    ProfileInfoT();
> +    ~ProfileInfoT();  // We want to be subclassed
>
>     // MissingValue - The value that is returned for execution  
> counts in case
>     // no value is available.
>     static const double MissingValue;
>
>     // getFunction() - Returns the Function for an Edge, checking  
> for validity.
> -    static const Function* getFunction(Edge e) {
> +    static const FType* getFunction(Edge e) {
>       if (e.first) {
>         return e.first->getParent();
>       } else if (e.second) {
>         return e.second->getParent();
>       }
>       assert(0 && "Invalid ProfileInfo::Edge");
> -      return (const Function*)0;
> +      return (const FType*)0;
>     }
>
>     // getEdge() - Creates an Edge from two BasicBlocks.
> -    static Edge getEdge(const BasicBlock *Src, const BasicBlock  
> *Dest) {
> +    static Edge getEdge(const BType *Src, const BType *Dest) {
>       return std::make_pair(Src, Dest);
>     }
>
>     // 
> ===------------------------------------------------------------------ 
> ===//
>     /// Profile Information Queries
>     ///
> -    double getExecutionCount(const Function *F);
> +    double getExecutionCount(const FType *F);
> +
> +    double getExecutionCount(const BType *BB);
> +
> +    void setExecutionCount(const BType *BB, double w);
>
> -    double getExecutionCount(const BasicBlock *BB);
> +    void addExecutionCount(const BType *BB, double w);
>
>     double getEdgeWeight(Edge e) const {
> -      std::map<const Function*, EdgeWeights>::const_iterator J =
> +      typename std::map<const FType*, EdgeWeights>::const_iterator  
> J =
>         EdgeInformation.find(getFunction(e));
>       if (J == EdgeInformation.end()) return MissingValue;
>
> -      EdgeWeights::const_iterator I = J->second.find(e);
> +      typename EdgeWeights::const_iterator I = J->second.find(e);
>       if (I == J->second.end()) return MissingValue;
>
>       return I->second;
>     }
>
> -    EdgeWeights &getEdgeWeights (const Function *F) {
> +    void setEdgeWeight(Edge e, double w) {
> +      DEBUG_WITH_TYPE("profile-info",
> +            errs() << "Creating Edge " << e
> +                   << " (weight: " << format("%.20g",w) << ")\n");
> +      EdgeInformation[getFunction(e)][e] = w;
> +    }
> +
> +    void addEdgeWeight(Edge e, double w);
> +
> +    EdgeWeights &getEdgeWeights (const FType *F) {
>       return EdgeInformation[F];
>     }
>
>     // 
> ===------------------------------------------------------------------ 
> ===//
>     /// Analysis Update Methods
>     ///
> -    void removeBlock(const BasicBlock *BB) {
> -      std::map<const Function*, BlockCounts>::iterator J =
> -        BlockInformation.find(BB->getParent());
> -      if (J == BlockInformation.end()) return;
> +    void removeBlock(const BType *BB);
>
> -      J->second.erase(BB);
> -    }
> +    void removeEdge(Edge e);
>
> -    void removeEdge(Edge e) {
> -      std::map<const Function*, EdgeWeights>::iterator J =
> -        EdgeInformation.find(getFunction(e));
> -      if (J == EdgeInformation.end()) return;
> +    void replaceEdge(const Edge &, const Edge &);
>
> -      J->second.erase(e);
> +    enum GetPathMode {
> +      GetPathToExit = 1,
> +      GetPathToValue = 2,
> +      GetPathToDest = 4,
> +      GetPathWithNewEdges = 8
> +    };
> +
> +    const BType *GetPath(const BType *Src, const BType *Dest,
> +                              Path &P, unsigned Mode);
> +
> +    void divertFlow(const Edge &, const Edge &);
> +
> +    void splitEdge(const BType *FirstBB, const BType *SecondBB,
> +                   const BType *NewBB, bool MergeIdenticalEdges =  
> false);
> +
> +    void splitBlock(const BType *Old, const BType* New);
> +
> +    void splitBlock(const BType *BB, const BType* NewBB,
> +                    BType *const *Preds, unsigned NumPreds);
> +
> +    void replaceAllUses(const BType *RmBB, const BType *DestBB);
> +
> +    void transfer(const FType *Old, const FType *New);
> +
> +    void repair(const FType *F);
> +
> +    void dump(FType *F = 0, bool real = true) {
> +      errs() << "**** This is ProfileInfo " << this << " speaking: 
> \n";
> +      if (!real) {
> +        typename std::set<const FType*> Functions;
> +
> +        errs() << "Functions: \n";
> +        if (F) {
> +          errs() << F << "@" << format("%p", F) << ": " <<  
> format("%.20g",getExecutionCount(F)) << "\n";
> +          Functions.insert(F);
> +        } else {
> +          for (typename std::map<const FType*, double>::iterator fi  
> = FunctionInformation.begin(),
> +               fe = FunctionInformation.end(); fi != fe; ++fi) {
> +            errs() << fi->first << "@" << format("%p",fi->first) <<  
> ": " << format("%.20g",fi->second) << "\n";
> +            Functions.insert(fi->first);
> +          }
> +        }
> +
> +        for (typename std::set<const FType*>::iterator FI =  
> Functions.begin(), FE = Functions.end();
> +             FI != FE; ++FI) {
> +          const FType *F = *FI;
> +          typename std::map<const FType*, BlockCounts>::iterator  
> bwi = BlockInformation.find(F);
> +          errs() << "BasicBlocks for Function " << F << ":\n";
> +          for (typename BlockCounts::const_iterator bi = bwi- 
> >second.begin(), be = bwi->second.end(); bi != be; ++bi) {
> +            errs() << bi->first << "@" << format("%p", bi->first)  
> << ": " << format("%.20g",bi->second) << "\n";
> +          }
> +        }
> +
> +        for (typename std::set<const FType*>::iterator FI =  
> Functions.begin(), FE = Functions.end();
> +             FI != FE; ++FI) {
> +          typename std::map<const FType*, EdgeWeights>::iterator ei  
> = EdgeInformation.find(*FI);
> +          errs() << "Edges for Function " << ei->first << ":\n";
> +          for (typename EdgeWeights::iterator ewi = ei- 
> >second.begin(), ewe = ei->second.end();
> +               ewi != ewe; ++ewi) {
> +            errs() << ewi->first << ": " << format("%.20g",ewi- 
> >second) << "\n";
> +          }
> +        }
> +      } else {
> +        assert(F && "No function given, this is not supported!");
> +        errs() << "Functions: \n";
> +        errs() << F << "@" << format("%p", F) << ": " << format("%. 
> 20g",getExecutionCount(F)) << "\n";
> +
> +        errs() << "BasicBlocks for Function " << F << ":\n";
> +        for (typename FType::const_iterator BI = F->begin(), BE = F- 
> >end();
> +             BI != BE; ++BI) {
> +          const BType *BB = &(*BI);
> +          errs() << BB << "@" << format("%p", BB) << ": " <<  
> format("%.20g",getExecutionCount(BB)) << "\n";
> +        }
> +      }
> +      errs() << "**** ProfileInfo " << this << ", over and out.\n";
>     }
>
> -    void splitEdge(const BasicBlock *FirstBB, const BasicBlock  
> *SecondBB,
> -                   const BasicBlock *NewBB, bool  
> MergeIdenticalEdges = false);
> +    bool CalculateMissingEdge(const BType *BB, Edge &removed, bool  
> assumeEmptyExit = false);
> +
> +    bool EstimateMissingEdges(const BType *BB);
>
> -    void replaceAllUses(const BasicBlock *RmBB, const BasicBlock  
> *DestBB);
> +    ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() {
> +      if (MachineProfile == 0)
> +        MachineProfile = new ProfileInfoT<MachineFunction,  
> MachineBasicBlock>();
> +      return MachineProfile;
> +    }
> +
> +    bool hasMI() const {
> +      return (MachineProfile != 0);
> +    }
>   };
>
> +  typedef ProfileInfoT<Function, BasicBlock> ProfileInfo;
> +  typedef ProfileInfoT<MachineFunction, MachineBasicBlock>  
> MachineProfileInfo;
> +
>   /// createProfileLoaderPass - This function returns a Pass that  
> loads the
>   /// profiling information for the module from the specified  
> filename, making
>   /// it available to the optimizers.
>   Pass *createProfileLoaderPass(const std::string &Filename);
>
> -  raw_ostream& operator<<(raw_ostream &O, ProfileInfo::Edge E);
> -
> } // End llvm namespace
>
> #endif
>
> Modified: llvm/trunk/lib/Analysis/ProfileInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ProfileInfo.cpp?rev=90445&r1=90444&r2=90445&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Analysis/ProfileInfo.cpp (original)
> +++ llvm/trunk/lib/Analysis/ProfileInfo.cpp Thu Dec  3 03:30:12 2009
> @@ -11,25 +11,51 @@
> // "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/Support/Debug.h"
> -#include "llvm/Support/raw_ostream.h"
> -#include "llvm/Support/Format.h"
> +#include "llvm/ADT/SmallSet.h"
> #include <set>
> +#include <queue>
> +#include <limits>
> using namespace llvm;
>
> // Register the ProfileInfo interface, providing a nice name to  
> refer to.
> static RegisterAnalysisGroup<ProfileInfo> Z("Profile Information");
> +
> +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 ProfileInfo::ID = 0;
>
> -ProfileInfo::~ProfileInfo() {}
> +template<>
> +char MachineProfileInfo::ID = 0;
>
> +template<>
> const double ProfileInfo::MissingValue = -1;
>
> +template<>
> +const double MachineProfileInfo::MissingValue = -1;
> +
> +template<>
> double ProfileInfo::getExecutionCount(const BasicBlock *BB) {
>   std::map<const Function*, BlockCounts>::iterator J =
>     BlockInformation.find(BB->getParent());
> @@ -39,35 +65,72 @@
>       return I->second;
>   }
>
> +  double Count = MissingValue;
> +
>   pred_const_iterator PI = pred_begin(BB), PE = pred_end(BB);
>
>   // Are there zero predecessors of this block?
>   if (PI == PE) {
> -    // If this is the entry block, look for the Null -> Entry edge.
> -    if (BB == &BB->getParent()->getEntryBlock())
> -      return getEdgeWeight(getEdge(0, BB));
> -    else
> -      return 0;   // Otherwise, this is a dead block.
> +    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)
> +      if (ProcessedPreds.insert(*PI).second) {
> +        double w = getEdgeWeight(getEdge(*PI, BB));
> +        if (w == MissingValue) {
> +          Count = MissingValue;
> +          break;
> +        }
> +        Count += w;
> +      }
>   }
>
> -  // 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;
> -  double Count = 0;
> -  for (; PI != PE; ++PI)
> -    if (ProcessedPreds.insert(*PI).second) {
> -      double w = getEdgeWeight(getEdge(*PI, 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 MachineProfileInfo::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 ProfileInfo::getExecutionCount(const Function *F) {
>   std::map<const Function*, double>::iterator J =
>     FunctionInformation.find(F);
> @@ -83,35 +146,204 @@
>   return Count;
> }
>
> +template<>
> +double MachineProfileInfo::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 ProfileInfo::setExecutionCount(const BasicBlock *BB, double w) {
> +  DEBUG(errs() << "Creating Block " << BB->getName()
> +               << " (weight: " << format("%.20g",w) << ")\n");
> +  BlockInformation[BB->getParent()][BB] = w;
> +}
> +
> +template<>
> +void MachineProfileInfo::setExecutionCount(const MachineBasicBlock  
> *MBB, double w) {
> +  DEBUG(errs() << "Creating Block " << MBB->getBasicBlock()- 
> >getName()
> +               << " (weight: " << format("%.20g",w) << ")\n");
> +  BlockInformation[MBB->getParent()][MBB] = w;
> +}
> +
> +template<>
> +void ProfileInfo::addEdgeWeight(Edge e, double w) {
> +  double oldw = getEdgeWeight(e);
> +  assert (oldw != MissingValue && "Adding weight to Edge with no  
> previous weight");
> +  DEBUG(errs() << "Adding to Edge " << e
> +               << " (new weight: " << format("%.20g",oldw + w) << ") 
> \n");
> +  EdgeInformation[getFunction(e)][e] = oldw + w;
> +}
> +
> +template<>
> +void ProfileInfo::addExecutionCount(const BasicBlock *BB, double w) {
> +  double oldw = getExecutionCount(BB);
> +  assert (oldw != MissingValue && "Adding weight to Block with no  
> previous weight");
> +  DEBUG(errs() << "Adding to Block " << BB->getName()
> +               << " (new weight: " << format("%.20g",oldw + w) << ") 
> \n");
> +  BlockInformation[BB->getParent()][BB] = oldw + w;
> +}
> +
> +template<>
> +void ProfileInfo::removeBlock(const BasicBlock *BB) {
> +  std::map<const Function*, BlockCounts>::iterator J =
> +    BlockInformation.find(BB->getParent());
> +  if (J == BlockInformation.end()) return;
> +
> +  DEBUG(errs() << "Deleting " << BB->getName() << "\n");
> +  J->second.erase(BB);
> +}
> +
> +template<>
> +void ProfileInfo::removeEdge(Edge e) {
> +  std::map<const Function*, EdgeWeights>::iterator J =
> +    EdgeInformation.find(getFunction(e));
> +  if (J == EdgeInformation.end()) return;
> +
> +  DEBUG(errs() << "Deleting" << e << "\n");
> +  J->second.erase(e);
> +}
> +
> +template<>
> +void ProfileInfo::replaceEdge(const Edge &oldedge, const Edge  
> &newedge) {
> +  double w;
> +  if ((w = getEdgeWeight(newedge)) == MissingValue) {
> +    w = getEdgeWeight(oldedge);
> +    DEBUG(errs() << "Replacing " << oldedge << " with " << newedge   
> << "\n");
> +  } else {
> +    w += getEdgeWeight(oldedge);
> +    DEBUG(errs() << "Adding " << oldedge << " to " << newedge  <<  
> "\n");
> +  }
> +  setEdgeWeight(newedge,w);
> +  removeEdge(oldedge);
> +}
> +
> +template<>
> +const BasicBlock *ProfileInfo::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 ProfileInfo::divertFlow(const Edge &oldedge, const Edge  
> &newedge) {
> +  DEBUG(errs() << "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(errs() << ", 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 ProfileInfo::replaceAllUses(const BasicBlock *RmBB,
>                                  const BasicBlock *DestBB) {
> -  DEBUG(errs() << "Replacing " << RmBB->getNameStr()
> -               << " with " << DestBB->getNameStr() << "\n");
> +  DEBUG(errs() << "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;
>
> -  for (EdgeWeights::iterator I = J->second.begin(), E = J- 
> >second.end();
> -       I != E; ++I) {
> -    Edge e = I->first;
> -    Edge newedge; bool foundedge = false;
> +  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) {
> -      newedge = getEdge(DestBB, e.second);
> -      foundedge = true;
> +      if (e.second == DestBB) {
> +        eraseedge = true;
> +      } else {
> +        newedge = getEdge(DestBB, e.second);
> +        foundedge = true;
> +      }
>     }
>     if (e.second == RmBB) {
> -      newedge = getEdge(e.first, DestBB);
> -      foundedge = true;
> +      if (e.first == DestBB) {
> +        eraseedge = true;
> +      } else {
> +        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);
> +      replaceEdge(e, newedge);
> +    }
> +    if (eraseedge) {
> +      if (erasededge) {
> +        Edge newedge = getEdge(DestBB, DestBB);
> +        replaceEdge(e, newedge);
> +      } else {
> +        removeEdge(e);
> +        erasededge = true;
> +      }
>     }
>   }
> }
> @@ -119,6 +351,7 @@
> /// 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 ProfileInfo::splitEdge(const BasicBlock *FirstBB,
>                             const BasicBlock *SecondBB,
>                             const BasicBlock *NewBB,
> @@ -153,7 +386,7 @@
>
>   // 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;
> +  double neww = floor(w / succ_count);
>   ECs[n1] += neww;
>   ECs[n2] += neww;
>   BlockInformation[F][NewBB] += neww;
> @@ -164,14 +397,666 @@
>   }
> }
>
> -raw_ostream& llvm::operator<<(raw_ostream &O, ProfileInfo::Edge E) {
> +template<>
> +void ProfileInfo::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(errs() << "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 ProfileInfo::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(errs() << "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 ProfileInfo::transfer(const Function *Old, const Function  
> *New) {
> +  DEBUG(errs() << "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 ProfileInfo::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;
> +  pred_const_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(errs() << "--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 ProfileInfo::EstimateMissingEdges(const BasicBlock *BB) {
> +  bool hasNoSuccessors = false;
> +
> +  double inWeight = 0;
> +  std::set<Edge> inMissing;
> +  std::set<const BasicBlock*> ProcessedPreds;
> +  pred_const_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);
> +    hasNoSuccessors = true;
> +  }
> +  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 ProfileInfo::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);
> +//      {
> +//        pred_const_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 (pred_const_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 (pred_const_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;
> +      Path P;
> +      bool BackEdgeFound = false;
> +      for (pred_const_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 (pred_const_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 (pred_const_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;
> +      errs() << BB->getName();
> +      if (FI != FE)
> +        errs() << ",";
> +    }
> +    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 << "(";
> -  O << (E.first ? E.first->getNameStr() : "0");
> +
> +  if (E.first)
> +    O << E.first;
> +  else
> +    O << "0";
> +
>   O << ",";
> -  O << (E.second ? E.second->getNameStr() : "0");
> +
> +  if (E.second)
> +    O << E.second;
> +  else
> +    O << "0";
> +
>   return O << ")";
> }
>
> +} // namespace llvm
> +
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> //  NoProfile ProfileInfo implementation
> //
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list