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