4ea4ca3b18a15cae1fc0b14db5d0fc1ddaab9412
[oota-llvm.git] / lib / Analysis / ProfileInfoLoader.cpp
1 //===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
2 // 
3 //                      The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source 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/Module.h"
17 #include <cstdio>
18 using namespace llvm;
19
20 enum ProfilingType {
21   ArgumentInfo = 1,   // The command line argument block
22   FunctionInfo = 2,   // Function profiling information
23   BlockInfo    = 3,   // Block profiling information
24 };
25
26 // ByteSwap - Byteswap 'Var' if 'Really' is true.
27 //
28 static inline unsigned ByteSwap(unsigned Var, bool Really) {
29   if (!Really) return Var;
30   return ((Var & (255<< 0)) << 24) | 
31          ((Var & (255<< 8)) <<  8) | 
32          ((Var & (255<<16)) >>  8) | 
33          ((Var & (255<<24)) >> 24);
34 }
35
36 static void ReadProfilingBlock(const char *ToolName, FILE *F,
37                                bool ShouldByteSwap,
38                                std::vector<unsigned> &Data) {
39   // Read the number of entries...
40   unsigned NumEntries;
41   if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) {
42     std::cerr << ToolName << ": data packet truncated!\n";
43     perror(0);
44     exit(1);
45   }
46   NumEntries = ByteSwap(NumEntries, ShouldByteSwap);
47
48   // Read the counts...
49   std::vector<unsigned> TempSpace(NumEntries);
50
51   // Read in the block of data...
52   if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) {
53     std::cerr << ToolName << ": data packet truncated!\n";
54     perror(0);
55     exit(1);
56   }
57
58   // Make sure we have enough space...
59   if (Data.size() < NumEntries)
60     Data.resize(NumEntries);
61   
62   // Accumulate the data we just read into the data.
63   if (!ShouldByteSwap) {
64     for (unsigned i = 0; i != NumEntries; ++i)
65       Data[i] += TempSpace[i];
66   } else {
67     for (unsigned i = 0; i != NumEntries; ++i)
68       Data[i] += ByteSwap(TempSpace[i], true);
69   }
70 }
71
72 // ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
73 // program if the file is invalid or broken.
74 //
75 ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
76                                      const std::string &Filename,
77                                      Module &TheModule) : M(TheModule) {
78   FILE *F = fopen(Filename.c_str(), "r");
79   if (F == 0) {
80     std::cerr << ToolName << ": Error opening '" << Filename << ": ";
81     perror(0);
82     exit(1);
83   }
84
85   // Keep reading packets until we run out of them.
86   unsigned PacketType;
87   while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
88     // If the low eight bits of the packet are zero, we must be dealing with an
89     // endianness mismatch.  Byteswap all words read from the profiling
90     // information.
91     bool ShouldByteSwap = (char)PacketType == 0;
92     PacketType = ByteSwap(PacketType, ShouldByteSwap);
93
94     switch (PacketType) {
95     case ArgumentInfo: {
96       unsigned ArgLength;
97       if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) {
98         std::cerr << ToolName << ": arguments packet truncated!\n";
99         perror(0);
100         exit(1);
101       }
102       ArgLength = ByteSwap(ArgLength, ShouldByteSwap);
103
104       // Read in the arguments...
105       std::vector<char> Chars(ArgLength+4);
106
107       if (ArgLength)
108         if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) {
109           std::cerr << ToolName << ": arguments packet truncated!\n";
110           perror(0);
111           exit(1);
112         }
113       CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength]));
114       break;
115     }
116       
117     case FunctionInfo:
118       ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts);
119       break;
120       
121     case BlockInfo:
122       ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts);
123       break;
124
125     default:
126       std::cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n";
127       exit(1);
128     }
129   }
130   
131   fclose(F);
132 }
133
134
135 // getFunctionCounts - This method is used by consumers of function counting
136 // information.  If we do not directly have function count information, we
137 // compute it from other, more refined, types of profile information.
138 //
139 void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
140                                                       unsigned> > &Counts) {
141   if (FunctionCounts.empty()) {
142     // Synthesize function frequency information from the number of times their
143     // entry blocks were executed.
144     std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
145     getBlockCounts(BlockCounts);
146
147     for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
148       if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first)
149         Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
150                                         BlockCounts[i].second));
151     return;
152   }
153   
154   unsigned Counter = 0;
155   for (Module::iterator I = M.begin(), E = M.end();
156        I != E && Counter != FunctionCounts.size(); ++I)
157     if (!I->isExternal())
158       Counts.push_back(std::make_pair(I, FunctionCounts[Counter++]));
159 }
160
161 // getBlockCounts - This method is used by consumers of block counting
162 // information.  If we do not directly have block count information, we
163 // compute it from other, more refined, types of profile information.
164 //
165 void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
166                                                          unsigned> > &Counts) {
167   if (BlockCounts.empty()) {
168     std::cerr << "Block counts not available, and no synthesis "
169               << "is implemented yet!\n";
170     return;
171   }
172
173   unsigned Counter = 0;
174   for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
175     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
176       Counts.push_back(std::make_pair(BB, BlockCounts[Counter++]));
177       if (Counter == BlockCounts.size())
178         return;
179     }
180 }