Home | History | Annotate | Download | only in Analysis
      1 //===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
      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 // The ProfileInfoLoader class is used to load and represent profiling
     11 // information read in from the dump file.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "llvm/Analysis/ProfileInfoLoader.h"
     16 #include "llvm/Analysis/ProfileInfoTypes.h"
     17 #include "llvm/Module.h"
     18 #include "llvm/InstrTypes.h"
     19 #include "llvm/Support/raw_ostream.h"
     20 #include <cstdio>
     21 #include <cstdlib>
     22 using namespace llvm;
     23 
     24 // ByteSwap - Byteswap 'Var' if 'Really' is true.
     25 //
     26 static inline unsigned ByteSwap(unsigned Var, bool Really) {
     27   if (!Really) return Var;
     28   return ((Var & (255U<< 0U)) << 24U) |
     29          ((Var & (255U<< 8U)) <<  8U) |
     30          ((Var & (255U<<16U)) >>  8U) |
     31          ((Var & (255U<<24U)) >> 24U);
     32 }
     33 
     34 static unsigned AddCounts(unsigned A, unsigned B) {
     35   // If either value is undefined, use the other.
     36   if (A == ProfileInfoLoader::Uncounted) return B;
     37   if (B == ProfileInfoLoader::Uncounted) return A;
     38   return A + B;
     39 }
     40 
     41 static void ReadProfilingBlock(const char *ToolName, FILE *F,
     42                                bool ShouldByteSwap,
     43                                std::vector<unsigned> &Data) {
     44   // Read the number of entries...
     45   unsigned NumEntries;
     46   if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) {
     47     errs() << ToolName << ": data packet truncated!\n";
     48     perror(0);
     49     exit(1);
     50   }
     51   NumEntries = ByteSwap(NumEntries, ShouldByteSwap);
     52 
     53   // Read the counts...
     54   std::vector<unsigned> TempSpace(NumEntries);
     55 
     56   // Read in the block of data...
     57   if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) {
     58     errs() << ToolName << ": data packet truncated!\n";
     59     perror(0);
     60     exit(1);
     61   }
     62 
     63   // Make sure we have enough space... The space is initialised to -1 to
     64   // facitiltate the loading of missing values for OptimalEdgeProfiling.
     65   if (Data.size() < NumEntries)
     66     Data.resize(NumEntries, ProfileInfoLoader::Uncounted);
     67 
     68   // Accumulate the data we just read into the data.
     69   if (!ShouldByteSwap) {
     70     for (unsigned i = 0; i != NumEntries; ++i) {
     71       Data[i] = AddCounts(TempSpace[i], Data[i]);
     72     }
     73   } else {
     74     for (unsigned i = 0; i != NumEntries; ++i) {
     75       Data[i] = AddCounts(ByteSwap(TempSpace[i], true), Data[i]);
     76     }
     77   }
     78 }
     79 
     80 const unsigned ProfileInfoLoader::Uncounted = ~0U;
     81 
     82 // ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
     83 // program if the file is invalid or broken.
     84 //
     85 ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
     86                                      const std::string &Filename,
     87                                      Module &TheModule) :
     88                                      Filename(Filename),
     89                                      M(TheModule), Warned(false) {
     90   FILE *F = fopen(Filename.c_str(), "rb");
     91   if (F == 0) {
     92     errs() << ToolName << ": Error opening '" << Filename << "': ";
     93     perror(0);
     94     exit(1);
     95   }
     96 
     97   // Keep reading packets until we run out of them.
     98   unsigned PacketType;
     99   while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
    100     // If the low eight bits of the packet are zero, we must be dealing with an
    101     // endianness mismatch.  Byteswap all words read from the profiling
    102     // information.
    103     bool ShouldByteSwap = (char)PacketType == 0;
    104     PacketType = ByteSwap(PacketType, ShouldByteSwap);
    105 
    106     switch (PacketType) {
    107     case ArgumentInfo: {
    108       unsigned ArgLength;
    109       if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) {
    110         errs() << ToolName << ": arguments packet truncated!\n";
    111         perror(0);
    112         exit(1);
    113       }
    114       ArgLength = ByteSwap(ArgLength, ShouldByteSwap);
    115 
    116       // Read in the arguments...
    117       std::vector<char> Chars(ArgLength+4);
    118 
    119       if (ArgLength)
    120         if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) {
    121           errs() << ToolName << ": arguments packet truncated!\n";
    122           perror(0);
    123           exit(1);
    124         }
    125       CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength]));
    126       break;
    127     }
    128 
    129     case FunctionInfo:
    130       ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts);
    131       break;
    132 
    133     case BlockInfo:
    134       ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts);
    135       break;
    136 
    137     case EdgeInfo:
    138       ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
    139       break;
    140 
    141     case OptEdgeInfo:
    142       ReadProfilingBlock(ToolName, F, ShouldByteSwap, OptimalEdgeCounts);
    143       break;
    144 
    145     case BBTraceInfo:
    146       ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace);
    147       break;
    148 
    149     default:
    150       errs() << ToolName << ": Unknown packet type #" << PacketType << "!\n";
    151       exit(1);
    152     }
    153   }
    154 
    155   fclose(F);
    156 }
    157 
    158