X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FProfileInfoLoaderPass.cpp;h=346f8d6d6258bd28ca5655b69082bdf0b53baa6e;hb=08368387a450dc2b5681000e2728ec702a8f1197;hp=1a2332c0e994bf05869cee7b09a090fe32c1a498;hpb=da5ea945545ca8864a873a5a33fd891ec381ec88;p=oota-llvm.git diff --git a/lib/Analysis/ProfileInfoLoaderPass.cpp b/lib/Analysis/ProfileInfoLoaderPass.cpp index 1a2332c0e99..346f8d6d625 100644 --- a/lib/Analysis/ProfileInfoLoaderPass.cpp +++ b/lib/Analysis/ProfileInfoLoaderPass.cpp @@ -12,21 +12,20 @@ // //===----------------------------------------------------------------------===// #define DEBUG_TYPE "profile-loader" -#include "llvm/BasicBlock.h" -#include "llvm/InstrTypes.h" -#include "llvm/Module.h" -#include "llvm/Pass.h" #include "llvm/Analysis/Passes.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/Statistic.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Analysis/ProfileInfoLoader.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Compiler.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Format.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/SmallSet.h" +#include "llvm/Support/raw_ostream.h" #include using namespace llvm; @@ -38,14 +37,16 @@ ProfileInfoFilename("profile-info-file", cl::init("llvmprof.out"), cl::desc("Profile file loaded by -profile-loader")); namespace { - class VISIBILITY_HIDDEN LoaderPass : public ModulePass, public ProfileInfo { + class LoaderPass : public ModulePass, public ProfileInfo { std::string Filename; std::set SpanningTree; std::set BBisUnvisited; + unsigned ReadCount; public: static char ID; // Class identification, replacement for typeinfo explicit LoaderPass(const std::string &filename = "") - : ModulePass(&ID), Filename(filename) { + : ModulePass(ID), Filename(filename) { + initializeLoaderPassPass(*PassRegistry::getPassRegistry()); if (filename.empty()) Filename = ProfileInfoFilename; } @@ -60,20 +61,29 @@ namespace { // recurseBasicBlock() - Calculates the edge weights for as much basic // blocks as possbile. virtual void recurseBasicBlock(const BasicBlock *BB); - virtual void readEdgeOrRemember(Edge, Edge&, unsigned &, unsigned &); - virtual void readOrRememberEdge(ProfileInfo::Edge, unsigned, - unsigned, Function*); + virtual void readEdgeOrRemember(Edge, Edge&, unsigned &, double &); + virtual void readEdge(ProfileInfo::Edge, std::vector&); + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(AnalysisID PI) { + if (PI == &ProfileInfo::ID) + return (ProfileInfo*)this; + return this; + } + /// run - Load the profile information from the specified file. virtual bool runOnModule(Module &M); }; } // End of anonymous namespace char LoaderPass::ID = 0; -static RegisterPass -X("profile-loader", "Load profile information from llvmprof.out", false, true); +INITIALIZE_AG_PASS(LoaderPass, ProfileInfo, "profile-loader", + "Load profile information from llvmprof.out", false, true, false) -static RegisterAnalysisGroup Y(X); +char &llvm::ProfileLoaderPassID = LoaderPass::ID; ModulePass *llvm::createProfileLoaderPass() { return new LoaderPass(); } @@ -85,7 +95,7 @@ Pass *llvm::createProfileLoaderPass(const std::string &Filename) { } void LoaderPass::readEdgeOrRemember(Edge edge, Edge &tocalc, - unsigned &uncalc, unsigned &count) { + unsigned &uncalc, double &count) { double w; if ((w = getEdgeWeight(edge)) == MissingValue) { tocalc = edge; @@ -108,125 +118,84 @@ void LoaderPass::recurseBasicBlock(const BasicBlock *BB) { bbi != bbe; ++bbi) { recurseBasicBlock(*bbi); } - for (pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB); + for (const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB); bbi != bbe; ++bbi) { recurseBasicBlock(*bbi); } - Edge edgetocalc; - unsigned uncalculated = 0; - - // collect weights of all incoming and outgoing edges, rememer edges that - // have no value - unsigned incount = 0; - SmallSet pred_visited; - pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB); - if (bbi==bbe) { - readEdgeOrRemember(getEdge(0, BB),edgetocalc,uncalculated,incount); - } - for (;bbi != bbe; ++bbi) { - if (pred_visited.insert(*bbi)) { - readEdgeOrRemember(getEdge(*bbi, BB),edgetocalc,uncalculated,incount); - } + Edge tocalc; + if (CalculateMissingEdge(BB, tocalc)) { + SpanningTree.erase(tocalc); } +} - unsigned outcount = 0; - SmallSet succ_visited; - succ_const_iterator sbbi = succ_begin(BB), sbbe = succ_end(BB); - if (sbbi==sbbe) { - readEdgeOrRemember(getEdge(BB, 0),edgetocalc,uncalculated,outcount); - } - for (;sbbi != sbbe; ++sbbi) { - if (succ_visited.insert(*sbbi)) { - readEdgeOrRemember(getEdge(BB, *sbbi),edgetocalc,uncalculated,outcount); - } - } +void LoaderPass::readEdge(ProfileInfo::Edge e, + std::vector &ECs) { + if (ReadCount < ECs.size()) { + double weight = ECs[ReadCount++]; + if (weight != ProfileInfoLoader::Uncounted) { + // Here the data realm changes from the unsigned of the file to the + // double of the ProfileInfo. This conversion is save because we know + // that everything thats representable in unsinged is also representable + // in double. + EdgeInformation[getFunction(e)][e] += (double)weight; - // if exactly one edge weight was missing, calculate it and remove it from - // spanning tree - if (uncalculated == 1) { - if (incount < outcount) { - EdgeInformation[BB->getParent()][edgetocalc] = outcount-incount; + DEBUG(dbgs() << "--Read Edge Counter for " << e + << " (# "<< (ReadCount-1) << "): " + << (unsigned)getEdgeWeight(e) << "\n"); } else { - EdgeInformation[BB->getParent()][edgetocalc] = incount-outcount; + // This happens only if reading optimal profiling information, not when + // reading regular profiling information. + SpanningTree.insert(e); } - DEBUG(errs() << "--Calc Edge Counter for " << edgetocalc << ": " - << format("%g", getEdgeWeight(edgetocalc)) << "\n"); - SpanningTree.erase(edgetocalc); - } -} - -void LoaderPass::readOrRememberEdge(ProfileInfo::Edge e, - unsigned weight, unsigned ei, - Function *F) { - if (weight != (unsigned)MissingValue) { - EdgeInformation[F][e] += weight; - DEBUG(errs()<<"--Read Edge Counter for " << e - <<" (# "< ECs = PIL.getRawEdgeCounts(); - if (ECs.size() > 0) { - unsigned ei = 0; + std::vector Counters = PIL.getRawEdgeCounts(); + if (Counters.size() > 0) { + ReadCount = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; - if (ei < ECs.size()) - EdgeInformation[F][ProfileInfo::getEdge(0, &F->getEntryBlock())] += - ECs[ei++]; + DEBUG(dbgs() << "Working on " << F->getName() << "\n"); + readEdge(getEdge(0,&F->getEntryBlock()), Counters); for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { - // Okay, we have to add a counter of each outgoing edge. If the - // outgoing edge is not critical don't split it, just insert the counter - // in the source or destination of the edge. TerminatorInst *TI = BB->getTerminator(); for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { - if (ei < ECs.size()) - EdgeInformation[F][ProfileInfo::getEdge(BB, TI->getSuccessor(s))] += - ECs[ei++]; + readEdge(getEdge(BB,TI->getSuccessor(s)), Counters); } } } - if (ei != ECs.size()) { + if (ReadCount != Counters.size()) { errs() << "WARNING: profile information is inconsistent with " << "the current program!\n"; } - NumEdgesRead = ei; + NumEdgesRead = ReadCount; } - ECs = PIL.getRawOptimalEdgeCounts(); - if (ECs.size() > 0) { - unsigned ei = 0; + Counters = PIL.getRawOptimalEdgeCounts(); + if (Counters.size() > 0) { + ReadCount = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; - DEBUG(errs()<<"Working on "<getNameStr()<<"\n"); - if (ei < ECs.size()) { - readOrRememberEdge(getEdge(0,&F->getEntryBlock()), ECs[ei], ei, F); - ei++; - } + DEBUG(dbgs() << "Working on " << F->getName() << "\n"); + readEdge(getEdge(0,&F->getEntryBlock()), Counters); for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { TerminatorInst *TI = BB->getTerminator(); if (TI->getNumSuccessors() == 0) { - if (ei < ECs.size()) { - readOrRememberEdge(getEdge(BB,0), ECs[ei], ei, F); ei++; - } + readEdge(getEdge(BB,0), Counters); } for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { - if (ei < ECs.size()) { - readOrRememberEdge(getEdge(BB,TI->getSuccessor(s)), ECs[ei], ei, F); - ei++; - } + readEdge(getEdge(BB,TI->getSuccessor(s)), Counters); } } while (SpanningTree.size() > 0) { -#if 0 + unsigned size = SpanningTree.size(); -#endif + BBisUnvisited.clear(); for (std::set::iterator ei = SpanningTree.begin(), ee = SpanningTree.end(); ei != ee; ++ei) { @@ -236,52 +205,59 @@ bool LoaderPass::runOnModule(Module &M) { while (BBisUnvisited.size() > 0) { recurseBasicBlock(*BBisUnvisited.begin()); } -#if 0 + if (SpanningTree.size() == size) { - DEBUG(errs()<<"{"); + DEBUG(dbgs()<<"{"); for (std::set::iterator ei = SpanningTree.begin(), ee = SpanningTree.end(); ei != ee; ++ei) { - DEBUG(errs()<<"("<<(ei->first?ei->first->getName():"0")<<"," - <<(ei->second?ei->second->getName():"0")<<"),"); + DEBUG(dbgs()<< *ei <<","); } assert(0 && "No edge calculated!"); } -#endif + } } - if (ei != ECs.size()) { + if (ReadCount != Counters.size()) { errs() << "WARNING: profile information is inconsistent with " << "the current program!\n"; } - NumEdgesRead = ei; + NumEdgesRead = ReadCount; } BlockInformation.clear(); - std::vector BCs = PIL.getRawBlockCounts(); - if (BCs.size() > 0) { - unsigned bi = 0; + Counters = PIL.getRawBlockCounts(); + if (Counters.size() > 0) { + ReadCount = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) - if (bi < BCs.size()) - BlockInformation[F][BB] = BCs[bi++]; + if (ReadCount < Counters.size()) + // Here the data realm changes from the unsigned of the file to the + // double of the ProfileInfo. This conversion is save because we know + // that everything thats representable in unsinged is also + // representable in double. + BlockInformation[F][BB] = (double)Counters[ReadCount++]; } - if (bi != BCs.size()) { + if (ReadCount != Counters.size()) { errs() << "WARNING: profile information is inconsistent with " << "the current program!\n"; } } FunctionInformation.clear(); - std::vector FCs = PIL.getRawFunctionCounts(); - if (FCs.size() > 0) { - unsigned fi = 0; + Counters = PIL.getRawFunctionCounts(); + if (Counters.size() > 0) { + ReadCount = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration()) continue; - if (fi < FCs.size()) - FunctionInformation[F] = FCs[fi++]; + if (ReadCount < Counters.size()) + // Here the data realm changes from the unsigned of the file to the + // double of the ProfileInfo. This conversion is save because we know + // that everything thats representable in unsinged is also + // representable in double. + FunctionInformation[F] = (double)Counters[ReadCount++]; } - if (fi != FCs.size()) { + if (ReadCount != Counters.size()) { errs() << "WARNING: profile information is inconsistent with " << "the current program!\n"; }