| //===- 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 |