LLVM API Documentation

ProfileInfoLoader.cpp

Go to the documentation of this file.
00001 //===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
00002 //
00003 //                      The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // The ProfileInfoLoader class is used to load and represent profiling
00011 // information read in from the dump file.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/Analysis/ProfileInfoLoader.h"
00016 #include "llvm/Analysis/ProfileInfoTypes.h"
00017 #include "llvm/Module.h"
00018 #include "llvm/InstrTypes.h"
00019 #include <cstdio>
00020 #include <iostream>
00021 #include <map>
00022 
00023 using namespace llvm;
00024 
00025 // ByteSwap - Byteswap 'Var' if 'Really' is true.
00026 //
00027 static inline unsigned ByteSwap(unsigned Var, bool Really) {
00028   if (!Really) return Var;
00029   return ((Var & (255<< 0)) << 24) |
00030          ((Var & (255<< 8)) <<  8) |
00031          ((Var & (255<<16)) >>  8) |
00032          ((Var & (255<<24)) >> 24);
00033 }
00034 
00035 static void ReadProfilingBlock(const char *ToolName, FILE *F,
00036                                bool ShouldByteSwap,
00037                                std::vector<unsigned> &Data) {
00038   // Read the number of entries...
00039   unsigned NumEntries;
00040   if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) {
00041     std::cerr << ToolName << ": data packet truncated!\n";
00042     perror(0);
00043     exit(1);
00044   }
00045   NumEntries = ByteSwap(NumEntries, ShouldByteSwap);
00046 
00047   // Read the counts...
00048   std::vector<unsigned> TempSpace(NumEntries);
00049 
00050   // Read in the block of data...
00051   if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) {
00052     std::cerr << ToolName << ": data packet truncated!\n";
00053     perror(0);
00054     exit(1);
00055   }
00056 
00057   // Make sure we have enough space...
00058   if (Data.size() < NumEntries)
00059     Data.resize(NumEntries);
00060 
00061   // Accumulate the data we just read into the data.
00062   if (!ShouldByteSwap) {
00063     for (unsigned i = 0; i != NumEntries; ++i)
00064       Data[i] += TempSpace[i];
00065   } else {
00066     for (unsigned i = 0; i != NumEntries; ++i)
00067       Data[i] += ByteSwap(TempSpace[i], true);
00068   }
00069 }
00070 
00071 // ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
00072 // program if the file is invalid or broken.
00073 //
00074 ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
00075                                      const std::string &Filename,
00076                                      Module &TheModule) : M(TheModule) {
00077   FILE *F = fopen(Filename.c_str(), "r");
00078   if (F == 0) {
00079     std::cerr << ToolName << ": Error opening '" << Filename << "': ";
00080     perror(0);
00081     exit(1);
00082   }
00083 
00084   // Keep reading packets until we run out of them.
00085   unsigned PacketType;
00086   while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
00087     // If the low eight bits of the packet are zero, we must be dealing with an
00088     // endianness mismatch.  Byteswap all words read from the profiling
00089     // information.
00090     bool ShouldByteSwap = (char)PacketType == 0;
00091     PacketType = ByteSwap(PacketType, ShouldByteSwap);
00092 
00093     switch (PacketType) {
00094     case ArgumentInfo: {
00095       unsigned ArgLength;
00096       if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) {
00097         std::cerr << ToolName << ": arguments packet truncated!\n";
00098         perror(0);
00099         exit(1);
00100       }
00101       ArgLength = ByteSwap(ArgLength, ShouldByteSwap);
00102 
00103       // Read in the arguments...
00104       std::vector<char> Chars(ArgLength+4);
00105 
00106       if (ArgLength)
00107         if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) {
00108           std::cerr << ToolName << ": arguments packet truncated!\n";
00109           perror(0);
00110           exit(1);
00111         }
00112       CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength]));
00113       break;
00114     }
00115 
00116     case FunctionInfo:
00117       ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts);
00118       break;
00119 
00120     case BlockInfo:
00121       ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts);
00122       break;
00123 
00124     case EdgeInfo:
00125       ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
00126       break;
00127 
00128     case BBTraceInfo:
00129       ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace);
00130       break;
00131 
00132     default:
00133       std::cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n";
00134       exit(1);
00135     }
00136   }
00137 
00138   fclose(F);
00139 }
00140 
00141 
00142 // getFunctionCounts - This method is used by consumers of function counting
00143 // information.  If we do not directly have function count information, we
00144 // compute it from other, more refined, types of profile information.
00145 //
00146 void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
00147                                                       unsigned> > &Counts) {
00148   if (FunctionCounts.empty()) {
00149     if (hasAccurateBlockCounts()) {
00150       // Synthesize function frequency information from the number of times
00151       // their entry blocks were executed.
00152       std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
00153       getBlockCounts(BlockCounts);
00154 
00155       for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
00156         if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first)
00157           Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
00158                                           BlockCounts[i].second));
00159     } else {
00160       std::cerr << "Function counts are not available!\n";
00161     }
00162     return;
00163   }
00164 
00165   unsigned Counter = 0;
00166   for (Module::iterator I = M.begin(), E = M.end();
00167        I != E && Counter != FunctionCounts.size(); ++I)
00168     if (!I->isExternal())
00169       Counts.push_back(std::make_pair(I, FunctionCounts[Counter++]));
00170 }
00171 
00172 // getBlockCounts - This method is used by consumers of block counting
00173 // information.  If we do not directly have block count information, we
00174 // compute it from other, more refined, types of profile information.
00175 //
00176 void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
00177                                                          unsigned> > &Counts) {
00178   if (BlockCounts.empty()) {
00179     if (hasAccurateEdgeCounts()) {
00180       // Synthesize block count information from edge frequency information.
00181       // The block execution frequency is equal to the sum of the execution
00182       // frequency of all outgoing edges from a block.
00183       //
00184       // If a block has no successors, this will not be correct, so we have to
00185       // special case it. :(
00186       std::vector<std::pair<Edge, unsigned> > EdgeCounts;
00187       getEdgeCounts(EdgeCounts);
00188 
00189       std::map<BasicBlock*, unsigned> InEdgeFreqs;
00190 
00191       BasicBlock *LastBlock = 0;
00192       TerminatorInst *TI = 0;
00193       for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) {
00194         if (EdgeCounts[i].first.first != LastBlock) {
00195           LastBlock = EdgeCounts[i].first.first;
00196           TI = LastBlock->getTerminator();
00197           Counts.push_back(std::make_pair(LastBlock, 0));
00198         }
00199         Counts.back().second += EdgeCounts[i].second;
00200         unsigned SuccNum = EdgeCounts[i].first.second;
00201         if (SuccNum >= TI->getNumSuccessors()) {
00202           static bool Warned = false;
00203           if (!Warned) {
00204             std::cerr << "WARNING: profile info doesn't seem to match"
00205                       << " the program!\n";
00206             Warned = true;
00207           }
00208         } else {
00209           // If this successor has no successors of its own, we will never
00210           // compute an execution count for that block.  Remember the incoming
00211           // edge frequencies to add later.
00212           BasicBlock *Succ = TI->getSuccessor(SuccNum);
00213           if (Succ->getTerminator()->getNumSuccessors() == 0)
00214             InEdgeFreqs[Succ] += EdgeCounts[i].second;
00215         }
00216       }
00217 
00218       // Now we have to accumulate information for those blocks without
00219       // successors into our table.
00220       for (std::map<BasicBlock*, unsigned>::iterator I = InEdgeFreqs.begin(),
00221              E = InEdgeFreqs.end(); I != E; ++I) {
00222         unsigned i = 0;
00223         for (; i != Counts.size() && Counts[i].first != I->first; ++i)
00224           /*empty*/;
00225         if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0));
00226         Counts[i].second += I->second;
00227       }
00228 
00229     } else {
00230       std::cerr << "Block counts are not available!\n";
00231     }
00232     return;
00233   }
00234 
00235   unsigned Counter = 0;
00236   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
00237     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00238       Counts.push_back(std::make_pair(BB, BlockCounts[Counter++]));
00239       if (Counter == BlockCounts.size())
00240         return;
00241     }
00242 }
00243 
00244 // getEdgeCounts - This method is used by consumers of edge counting
00245 // information.  If we do not directly have edge count information, we compute
00246 // it from other, more refined, types of profile information.
00247 //
00248 void ProfileInfoLoader::getEdgeCounts(std::vector<std::pair<Edge,
00249                                                   unsigned> > &Counts) {
00250   if (EdgeCounts.empty()) {
00251     std::cerr << "Edge counts not available, and no synthesis "
00252               << "is implemented yet!\n";
00253     return;
00254   }
00255 
00256   unsigned Counter = 0;
00257   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
00258     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
00259       for (unsigned i = 0, e = BB->getTerminator()->getNumSuccessors();
00260            i != e; ++i) {
00261         Counts.push_back(std::make_pair(Edge(BB, i), EdgeCounts[Counter++]));
00262         if (Counter == EdgeCounts.size())
00263           return;
00264       }
00265 }
00266 
00267 // getBBTrace - This method is used by consumers of basic-block trace
00268 // information.
00269 //
00270 void ProfileInfoLoader::getBBTrace(std::vector<BasicBlock *> &Trace) {
00271   if (BBTrace.empty ()) {
00272     std::cerr << "Basic block trace is not available!\n";
00273     return;
00274   }
00275   std::cerr << "Basic block trace loading is not implemented yet!\n";
00276 }
00277