X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FAnalysis%2FProfileInfo.h;h=5d17fa1220e102cb33436c9df47a833aead0cfd3;hb=b09c146b116359616f6cbd4c8b3328607e00ff42;hp=ff83f97ee042d6fbee9abcecfb60b03c9268dcc8;hpb=7ed47a13356daed2a34cd2209a31f92552e3bdd8;p=oota-llvm.git diff --git a/include/llvm/Analysis/ProfileInfo.h b/include/llvm/Analysis/ProfileInfo.h index ff83f97ee04..5d17fa1220e 100644 --- a/include/llvm/Analysis/ProfileInfo.h +++ b/include/llvm/Analysis/ProfileInfo.h @@ -14,54 +14,234 @@ // // 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. +// made. (This is not implemented yet.) // //===----------------------------------------------------------------------===// #ifndef LLVM_ANALYSIS_PROFILEINFO_H #define LLVM_ANALYSIS_PROFILEINFO_H -#include +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include #include +#include +#include namespace llvm { - class BasicBlock; 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 E); + raw_ostream& operator<<(raw_ostream &O, std::pair E); + + raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB); + raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB); - /// ProfileInfo Class - This class holds and maintains edge profiling + 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 ProfileInfoT { + public: + // Types for handling profiling information. + typedef std::pair Edge; + typedef std::pair EdgeWeight; + typedef std::map EdgeWeights; + typedef std::map BlockCounts; + typedef std::map Path; + protected: - // EdgeCounts - 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, unsigned> EdgeCounts; + // 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 EdgeInformation; + + // BlockInformation - Count the number of times a block is executed. + std::map BlockInformation; + + // FunctionInformation - Count the number of times a function is executed. + std::map FunctionInformation; + + ProfileInfoT *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 FType* getFunction(Edge e) { + if (e.first) + return e.first->getParent(); + if (e.second) + return e.second->getParent(); + llvm_unreachable("Invalid ProfileInfo::Edge"); + } + + // 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 /// - unsigned getExecutionCount(BasicBlock *BB) const; + 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_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); - unsigned getEdgeWeight(BasicBlock *Src, BasicBlock *Dest) const { - std::map, unsigned>::const_iterator I= - EdgeCounts.find(std::make_pair(Src, Dest)); - return I != EdgeCounts.end() ? I->second : 0; + 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 Functions; + + dbgs() << "Functions: \n"; + if (F) { + dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n"; + Functions.insert(F); + } else { + for (typename std::map::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::iterator FI = Functions.begin(), FE = Functions.end(); + FI != FE; ++FI) { + const FType *F = *FI; + typename std::map::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::iterator FI = Functions.begin(), FE = Functions.end(); + FI != FE; ++FI) { + typename std::map::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 *MI() { + if (MachineProfile == 0) + MachineProfile = new ProfileInfoT(); + return MachineProfile; + } + + bool hasMI() const { + return (MachineProfile != 0); + } }; + typedef ProfileInfoT ProfileInfo; + typedef ProfileInfoT 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