1 //===- ProfileInfoLoaderPass.cpp - LLVM Pass to load profile info ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements a concrete implementation of profiling information that 11 // loads the information from a profile dump file. 12 // 13 //===----------------------------------------------------------------------===// 14 #define DEBUG_TYPE "profile-loader" 15 #include "llvm/Analysis/Passes.h" 16 #include "llvm/ADT/SmallSet.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/Analysis/ProfileInfo.h" 19 #include "llvm/Analysis/ProfileInfoLoader.h" 20 #include "llvm/IR/BasicBlock.h" 21 #include "llvm/IR/InstrTypes.h" 22 #include "llvm/IR/Module.h" 23 #include "llvm/Pass.h" 24 #include "llvm/Support/CFG.h" 25 #include "llvm/Support/CommandLine.h" 26 #include "llvm/Support/Debug.h" 27 #include "llvm/Support/Format.h" 28 #include "llvm/Support/raw_ostream.h" 29 #include <set> 30 using namespace llvm; 31 32 STATISTIC(NumEdgesRead, "The # of edges read."); 33 34 static cl::opt<std::string> 35 ProfileInfoFilename("profile-info-file", cl::init("llvmprof.out"), 36 cl::value_desc("filename"), 37 cl::desc("Profile file loaded by -profile-loader")); 38 39 namespace { 40 class LoaderPass : public ModulePass, public ProfileInfo { 41 std::string Filename; 42 std::set<Edge> SpanningTree; 43 std::set<const BasicBlock*> BBisUnvisited; 44 unsigned ReadCount; 45 public: 46 static char ID; // Class identification, replacement for typeinfo 47 explicit LoaderPass(const std::string &filename = "") 48 : ModulePass(ID), Filename(filename) { 49 initializeLoaderPassPass(*PassRegistry::getPassRegistry()); 50 if (filename.empty()) Filename = ProfileInfoFilename; 51 } 52 53 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 54 AU.setPreservesAll(); 55 } 56 57 virtual const char *getPassName() const { 58 return "Profiling information loader"; 59 } 60 61 // recurseBasicBlock() - Calculates the edge weights for as much basic 62 // blocks as possbile. 63 virtual void recurseBasicBlock(const BasicBlock *BB); 64 virtual void readEdgeOrRemember(Edge, Edge&, unsigned &, double &); 65 virtual void readEdge(ProfileInfo::Edge, std::vector<unsigned>&); 66 67 /// getAdjustedAnalysisPointer - This method is used when a pass implements 68 /// an analysis interface through multiple inheritance. If needed, it 69 /// should override this to adjust the this pointer as needed for the 70 /// specified pass info. 71 virtual void *getAdjustedAnalysisPointer(AnalysisID PI) { 72 if (PI == &ProfileInfo::ID) 73 return (ProfileInfo*)this; 74 return this; 75 } 76 77 /// run - Load the profile information from the specified file. 78 virtual bool runOnModule(Module &M); 79 }; 80 } // End of anonymous namespace 81 82 char LoaderPass::ID = 0; 83 INITIALIZE_AG_PASS(LoaderPass, ProfileInfo, "profile-loader", 84 "Load profile information from llvmprof.out", false, true, false) 85 86 char &llvm::ProfileLoaderPassID = LoaderPass::ID; 87 88 ModulePass *llvm::createProfileLoaderPass() { return new LoaderPass(); } 89 90 /// createProfileLoaderPass - This function returns a Pass that loads the 91 /// profiling information for the module from the specified filename, making it 92 /// available to the optimizers. 93 Pass *llvm::createProfileLoaderPass(const std::string &Filename) { 94 return new LoaderPass(Filename); 95 } 96 97 void LoaderPass::readEdgeOrRemember(Edge edge, Edge &tocalc, 98 unsigned &uncalc, double &count) { 99 double w; 100 if ((w = getEdgeWeight(edge)) == MissingValue) { 101 tocalc = edge; 102 uncalc++; 103 } else { 104 count+=w; 105 } 106 } 107 108 // recurseBasicBlock - Visits all neighbours of a block and then tries to 109 // calculate the missing edge values. 110 void LoaderPass::recurseBasicBlock(const BasicBlock *BB) { 111 112 // break recursion if already visited 113 if (BBisUnvisited.find(BB) == BBisUnvisited.end()) return; 114 BBisUnvisited.erase(BB); 115 if (!BB) return; 116 117 for (succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB); 118 bbi != bbe; ++bbi) { 119 recurseBasicBlock(*bbi); 120 } 121 for (const_pred_iterator bbi = pred_begin(BB), bbe = pred_end(BB); 122 bbi != bbe; ++bbi) { 123 recurseBasicBlock(*bbi); 124 } 125 126 Edge tocalc; 127 if (CalculateMissingEdge(BB, tocalc)) { 128 SpanningTree.erase(tocalc); 129 } 130 } 131 132 void LoaderPass::readEdge(ProfileInfo::Edge e, 133 std::vector<unsigned> &ECs) { 134 if (ReadCount < ECs.size()) { 135 double weight = ECs[ReadCount++]; 136 if (weight != ProfileInfoLoader::Uncounted) { 137 // Here the data realm changes from the unsigned of the file to the 138 // double of the ProfileInfo. This conversion is save because we know 139 // that everything thats representable in unsinged is also representable 140 // in double. 141 EdgeInformation[getFunction(e)][e] += (double)weight; 142 143 DEBUG(dbgs() << "--Read Edge Counter for " << e 144 << " (# "<< (ReadCount-1) << "): " 145 << (unsigned)getEdgeWeight(e) << "\n"); 146 } else { 147 // This happens only if reading optimal profiling information, not when 148 // reading regular profiling information. 149 SpanningTree.insert(e); 150 } 151 } 152 } 153 154 bool LoaderPass::runOnModule(Module &M) { 155 ProfileInfoLoader PIL("profile-loader", Filename); 156 157 EdgeInformation.clear(); 158 std::vector<unsigned> Counters = PIL.getRawEdgeCounts(); 159 if (Counters.size() > 0) { 160 ReadCount = 0; 161 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 162 if (F->isDeclaration()) continue; 163 DEBUG(dbgs() << "Working on " << F->getName() << "\n"); 164 readEdge(getEdge(0,&F->getEntryBlock()), Counters); 165 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 166 TerminatorInst *TI = BB->getTerminator(); 167 for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { 168 readEdge(getEdge(BB,TI->getSuccessor(s)), Counters); 169 } 170 } 171 } 172 if (ReadCount != Counters.size()) { 173 errs() << "WARNING: profile information is inconsistent with " 174 << "the current program!\n"; 175 } 176 NumEdgesRead = ReadCount; 177 } 178 179 Counters = PIL.getRawOptimalEdgeCounts(); 180 if (Counters.size() > 0) { 181 ReadCount = 0; 182 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 183 if (F->isDeclaration()) continue; 184 DEBUG(dbgs() << "Working on " << F->getName() << "\n"); 185 readEdge(getEdge(0,&F->getEntryBlock()), Counters); 186 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 187 TerminatorInst *TI = BB->getTerminator(); 188 if (TI->getNumSuccessors() == 0) { 189 readEdge(getEdge(BB,0), Counters); 190 } 191 for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { 192 readEdge(getEdge(BB,TI->getSuccessor(s)), Counters); 193 } 194 } 195 while (SpanningTree.size() > 0) { 196 197 unsigned size = SpanningTree.size(); 198 199 BBisUnvisited.clear(); 200 for (std::set<Edge>::iterator ei = SpanningTree.begin(), 201 ee = SpanningTree.end(); ei != ee; ++ei) { 202 BBisUnvisited.insert(ei->first); 203 BBisUnvisited.insert(ei->second); 204 } 205 while (BBisUnvisited.size() > 0) { 206 recurseBasicBlock(*BBisUnvisited.begin()); 207 } 208 209 if (SpanningTree.size() == size) { 210 DEBUG(dbgs()<<"{"); 211 for (std::set<Edge>::iterator ei = SpanningTree.begin(), 212 ee = SpanningTree.end(); ei != ee; ++ei) { 213 DEBUG(dbgs()<< *ei <<","); 214 } 215 assert(0 && "No edge calculated!"); 216 } 217 218 } 219 } 220 if (ReadCount != Counters.size()) { 221 errs() << "WARNING: profile information is inconsistent with " 222 << "the current program!\n"; 223 } 224 NumEdgesRead = ReadCount; 225 } 226 227 BlockInformation.clear(); 228 Counters = PIL.getRawBlockCounts(); 229 if (Counters.size() > 0) { 230 ReadCount = 0; 231 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 232 if (F->isDeclaration()) continue; 233 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) 234 if (ReadCount < Counters.size()) 235 // Here the data realm changes from the unsigned of the file to the 236 // double of the ProfileInfo. This conversion is save because we know 237 // that everything thats representable in unsinged is also 238 // representable in double. 239 BlockInformation[F][BB] = (double)Counters[ReadCount++]; 240 } 241 if (ReadCount != Counters.size()) { 242 errs() << "WARNING: profile information is inconsistent with " 243 << "the current program!\n"; 244 } 245 } 246 247 FunctionInformation.clear(); 248 Counters = PIL.getRawFunctionCounts(); 249 if (Counters.size() > 0) { 250 ReadCount = 0; 251 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { 252 if (F->isDeclaration()) continue; 253 if (ReadCount < Counters.size()) 254 // Here the data realm changes from the unsigned of the file to the 255 // double of the ProfileInfo. This conversion is save because we know 256 // that everything thats representable in unsinged is also 257 // representable in double. 258 FunctionInformation[F] = (double)Counters[ReadCount++]; 259 } 260 if (ReadCount != Counters.size()) { 261 errs() << "WARNING: profile information is inconsistent with " 262 << "the current program!\n"; 263 } 264 } 265 266 return false; 267 } 268