| //===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- C++ -*-===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file defines the generic ProfileInfo interface, which is used as the | 
 | // common interface used by all clients of profiling information, and | 
 | // implemented either by making static guestimations, or by actually reading in | 
 | // profiling information gathered by running the program. | 
 | // | 
 | // Note that to be useful, all profile-based optimizations should preserve | 
 | // ProfileInfo, which requires that they notify it when changes to the CFG are | 
 | // made. (This is not implemented yet.) | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #ifndef LLVM_ANALYSIS_PROFILEINFO_H | 
 | #define LLVM_ANALYSIS_PROFILEINFO_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 Pass; | 
 |   class raw_ostream; | 
 |  | 
 |   class BasicBlock; | 
 |   class Function; | 
 |   class MachineBasicBlock; | 
 |   class MachineFunction; | 
 |  | 
 |   // Helper for dumping edges to dbgs(). | 
 |   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. | 
 |   template<class FType, class BType> | 
 |   class ProfileInfoT { | 
 |   public: | 
 |     // Types for handling profiling information. | 
 |     typedef std::pair<const BType*, const BType*> Edge; | 
 |     typedef std::pair<Edge, double> EdgeWeight; | 
 |     typedef std::map<Edge, double> EdgeWeights; | 
 |     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 FType*, EdgeWeights> EdgeInformation; | 
 |  | 
 |     // BlockInformation - Count the number of times a block is executed. | 
 |     std::map<const FType*, BlockCounts> BlockInformation; | 
 |  | 
 |     // FunctionInformation - Count the number of times a function is executed. | 
 |     std::map<const FType*, double> FunctionInformation; | 
 |  | 
 |     ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile; | 
 |   public: | 
 |     static char ID; // Class identification, replacement for typeinfo | 
 |     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 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 FType*)0; | 
 |     } | 
 |  | 
 |     // getEdge() - Creates an Edge from two BasicBlocks. | 
 |     static Edge getEdge(const BType *Src, const BType *Dest) { | 
 |       return std::make_pair(Src, Dest); | 
 |     } | 
 |  | 
 |     //===------------------------------------------------------------------===// | 
 |     /// Profile Information Queries | 
 |     /// | 
 |     double getExecutionCount(const FType *F); | 
 |  | 
 |     double getExecutionCount(const BType *BB); | 
 |  | 
 |     void setExecutionCount(const BType *BB, double w); | 
 |  | 
 |     void addExecutionCount(const BType *BB, double w); | 
 |  | 
 |     double getEdgeWeight(Edge e) const { | 
 |       typename std::map<const FType*, EdgeWeights>::const_iterator J = | 
 |         EdgeInformation.find(getFunction(e)); | 
 |       if (J == EdgeInformation.end()) return MissingValue; | 
 |  | 
 |       typename EdgeWeights::const_iterator I = J->second.find(e); | 
 |       if (I == J->second.end()) return MissingValue; | 
 |  | 
 |       return I->second; | 
 |     } | 
 |  | 
 |     void setEdgeWeight(Edge e, double w) { | 
 |       DEBUG_WITH_TYPE("profile-info", | 
 |             dbgs() << "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 BType *BB); | 
 |  | 
 |     void removeEdge(Edge e); | 
 |  | 
 |     void replaceEdge(const Edge &, const Edge &); | 
 |  | 
 |     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) { | 
 |       dbgs() << "**** This is ProfileInfo " << this << " speaking:\n"; | 
 |       if (!real) { | 
 |         typename std::set<const FType*> Functions; | 
 |  | 
 |         dbgs() << "Functions: \n"; | 
 |         if (F) { | 
 |           dbgs() << 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) { | 
 |             dbgs() << 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); | 
 |           dbgs() << "BasicBlocks for Function " << F << ":\n"; | 
 |           for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) { | 
 |             dbgs() << 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); | 
 |           dbgs() << "Edges for Function " << ei->first << ":\n"; | 
 |           for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end();  | 
 |                ewi != ewe; ++ewi) { | 
 |             dbgs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n"; | 
 |           } | 
 |         } | 
 |       } else { | 
 |         assert(F && "No function given, this is not supported!"); | 
 |         dbgs() << "Functions: \n"; | 
 |         dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; | 
 |  | 
 |         dbgs() << "BasicBlocks for Function " << F << ":\n"; | 
 |         for (typename FType::const_iterator BI = F->begin(), BE = F->end(); | 
 |              BI != BE; ++BI) { | 
 |           const BType *BB = &(*BI); | 
 |           dbgs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n"; | 
 |         } | 
 |       } | 
 |       dbgs() << "**** ProfileInfo " << this << ", over and out.\n"; | 
 |     } | 
 |  | 
 |     bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false); | 
 |  | 
 |     bool EstimateMissingEdges(const BType *BB); | 
 |  | 
 |     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); | 
 |  | 
 | } // End llvm namespace | 
 |  | 
 | #endif |