LLVM API Documentation
00001 //===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the generic ProfileInfo interface, which is used as the 00011 // common interface used by all clients of profiling information, and 00012 // implemented either by making static guestimations, or by actually reading in 00013 // profiling information gathered by running the program. 00014 // 00015 // Note that to be useful, all profile-based optimizations should preserve 00016 // ProfileInfo, which requires that they notify it when changes to the CFG are 00017 // made. (This is not implemented yet.) 00018 // 00019 //===----------------------------------------------------------------------===// 00020 00021 #ifndef LLVM_ANALYSIS_PROFILEINFO_H 00022 #define LLVM_ANALYSIS_PROFILEINFO_H 00023 00024 #include "llvm/Support/Debug.h" 00025 #include "llvm/Support/ErrorHandling.h" 00026 #include "llvm/Support/Format.h" 00027 #include "llvm/Support/raw_ostream.h" 00028 #include <cassert> 00029 #include <map> 00030 #include <set> 00031 #include <string> 00032 00033 namespace llvm { 00034 class Pass; 00035 class raw_ostream; 00036 00037 class BasicBlock; 00038 class Function; 00039 class MachineBasicBlock; 00040 class MachineFunction; 00041 00042 // Helper for dumping edges to dbgs(). 00043 raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E); 00044 raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E); 00045 00046 raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB); 00047 raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB); 00048 00049 raw_ostream& operator<<(raw_ostream &O, const Function *F); 00050 raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF); 00051 00052 /// ProfileInfo Class - This class holds and maintains profiling 00053 /// information for some unit of code. 00054 template<class FType, class BType> 00055 class ProfileInfoT { 00056 public: 00057 // Types for handling profiling information. 00058 typedef std::pair<const BType*, const BType*> Edge; 00059 typedef std::pair<Edge, double> EdgeWeight; 00060 typedef std::map<Edge, double> EdgeWeights; 00061 typedef std::map<const BType*, double> BlockCounts; 00062 typedef std::map<const BType*, const BType*> Path; 00063 00064 protected: 00065 // EdgeInformation - Count the number of times a transition between two 00066 // blocks is executed. As a special case, we also hold an edge from the 00067 // null BasicBlock to the entry block to indicate how many times the 00068 // function was entered. 00069 std::map<const FType*, EdgeWeights> EdgeInformation; 00070 00071 // BlockInformation - Count the number of times a block is executed. 00072 std::map<const FType*, BlockCounts> BlockInformation; 00073 00074 // FunctionInformation - Count the number of times a function is executed. 00075 std::map<const FType*, double> FunctionInformation; 00076 00077 ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile; 00078 public: 00079 static char ID; // Class identification, replacement for typeinfo 00080 ProfileInfoT(); 00081 ~ProfileInfoT(); // We want to be subclassed 00082 00083 // MissingValue - The value that is returned for execution counts in case 00084 // no value is available. 00085 static const double MissingValue; 00086 00087 // getFunction() - Returns the Function for an Edge, checking for validity. 00088 static const FType* getFunction(Edge e) { 00089 if (e.first) 00090 return e.first->getParent(); 00091 if (e.second) 00092 return e.second->getParent(); 00093 llvm_unreachable("Invalid ProfileInfo::Edge"); 00094 } 00095 00096 // getEdge() - Creates an Edge from two BasicBlocks. 00097 static Edge getEdge(const BType *Src, const BType *Dest) { 00098 return std::make_pair(Src, Dest); 00099 } 00100 00101 //===------------------------------------------------------------------===// 00102 /// Profile Information Queries 00103 /// 00104 double getExecutionCount(const FType *F); 00105 00106 double getExecutionCount(const BType *BB); 00107 00108 void setExecutionCount(const BType *BB, double w); 00109 00110 void addExecutionCount(const BType *BB, double w); 00111 00112 double getEdgeWeight(Edge e) const { 00113 typename std::map<const FType*, EdgeWeights>::const_iterator J = 00114 EdgeInformation.find(getFunction(e)); 00115 if (J == EdgeInformation.end()) return MissingValue; 00116 00117 typename EdgeWeights::const_iterator I = J->second.find(e); 00118 if (I == J->second.end()) return MissingValue; 00119 00120 return I->second; 00121 } 00122 00123 void setEdgeWeight(Edge e, double w) { 00124 DEBUG_WITH_TYPE("profile-info", 00125 dbgs() << "Creating Edge " << e 00126 << " (weight: " << format("%.20g",w) << ")\n"); 00127 EdgeInformation[getFunction(e)][e] = w; 00128 } 00129 00130 void addEdgeWeight(Edge e, double w); 00131 00132 EdgeWeights &getEdgeWeights (const FType *F) { 00133 return EdgeInformation[F]; 00134 } 00135 00136 //===------------------------------------------------------------------===// 00137 /// Analysis Update Methods 00138 /// 00139 void removeBlock(const BType *BB); 00140 00141 void removeEdge(Edge e); 00142 00143 void replaceEdge(const Edge &, const Edge &); 00144 00145 enum GetPathMode { 00146 GetPathToExit = 1, 00147 GetPathToValue = 2, 00148 GetPathToDest = 4, 00149 GetPathWithNewEdges = 8 00150 }; 00151 00152 const BType *GetPath(const BType *Src, const BType *Dest, 00153 Path &P, unsigned Mode); 00154 00155 void divertFlow(const Edge &, const Edge &); 00156 00157 void splitEdge(const BType *FirstBB, const BType *SecondBB, 00158 const BType *NewBB, bool MergeIdenticalEdges = false); 00159 00160 void splitBlock(const BType *Old, const BType* New); 00161 00162 void splitBlock(const BType *BB, const BType* NewBB, 00163 BType *const *Preds, unsigned NumPreds); 00164 00165 void replaceAllUses(const BType *RmBB, const BType *DestBB); 00166 00167 void transfer(const FType *Old, const FType *New); 00168 00169 void repair(const FType *F); 00170 00171 void dump(FType *F = 0, bool real = true) { 00172 dbgs() << "**** This is ProfileInfo " << this << " speaking:\n"; 00173 if (!real) { 00174 typename std::set<const FType*> Functions; 00175 00176 dbgs() << "Functions: \n"; 00177 if (F) { 00178 dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; 00179 Functions.insert(F); 00180 } else { 00181 for (typename std::map<const FType*, double>::iterator fi = FunctionInformation.begin(), 00182 fe = FunctionInformation.end(); fi != fe; ++fi) { 00183 dbgs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n"; 00184 Functions.insert(fi->first); 00185 } 00186 } 00187 00188 for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end(); 00189 FI != FE; ++FI) { 00190 const FType *F = *FI; 00191 typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F); 00192 dbgs() << "BasicBlocks for Function " << F << ":\n"; 00193 for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) { 00194 dbgs() << bi->first << "@" << format("%p", bi->first) << ": " << format("%.20g",bi->second) << "\n"; 00195 } 00196 } 00197 00198 for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end(); 00199 FI != FE; ++FI) { 00200 typename std::map<const FType*, EdgeWeights>::iterator ei = EdgeInformation.find(*FI); 00201 dbgs() << "Edges for Function " << ei->first << ":\n"; 00202 for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end(); 00203 ewi != ewe; ++ewi) { 00204 dbgs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n"; 00205 } 00206 } 00207 } else { 00208 assert(F && "No function given, this is not supported!"); 00209 dbgs() << "Functions: \n"; 00210 dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; 00211 00212 dbgs() << "BasicBlocks for Function " << F << ":\n"; 00213 for (typename FType::const_iterator BI = F->begin(), BE = F->end(); 00214 BI != BE; ++BI) { 00215 const BType *BB = &(*BI); 00216 dbgs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n"; 00217 } 00218 } 00219 dbgs() << "**** ProfileInfo " << this << ", over and out.\n"; 00220 } 00221 00222 bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false); 00223 00224 bool EstimateMissingEdges(const BType *BB); 00225 00226 ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() { 00227 if (MachineProfile == 0) 00228 MachineProfile = new ProfileInfoT<MachineFunction, MachineBasicBlock>(); 00229 return MachineProfile; 00230 } 00231 00232 bool hasMI() const { 00233 return (MachineProfile != 0); 00234 } 00235 }; 00236 00237 typedef ProfileInfoT<Function, BasicBlock> ProfileInfo; 00238 typedef ProfileInfoT<MachineFunction, MachineBasicBlock> MachineProfileInfo; 00239 00240 /// createProfileLoaderPass - This function returns a Pass that loads the 00241 /// profiling information for the module from the specified filename, making 00242 /// it available to the optimizers. 00243 Pass *createProfileLoaderPass(const std::string &Filename); 00244 00245 } // End llvm namespace 00246 00247 #endif