blob: 3c19f5e9b9fdd5665c471bb24d7eb0c491fe4c70 [file] [log] [blame]
Chris Lattnerbc44aa62004-02-11 05:54:25 +00001//===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
Misha Brukman2b37d7c2005-04-21 21:13:18 +00002//
Chris Lattnerbc44aa62004-02-11 05:54:25 +00003// 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.
Misha Brukman2b37d7c2005-04-21 21:13:18 +00007//
Chris Lattnerbc44aa62004-02-11 05:54:25 +00008//===----------------------------------------------------------------------===//
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"
Brian Gaeke660ef702004-05-04 16:53:07 +000016#include "llvm/Analysis/ProfileInfoTypes.h"
Chris Lattnerbc44aa62004-02-11 05:54:25 +000017#include "llvm/Module.h"
Chris Lattner01945c12004-03-08 18:20:18 +000018#include "llvm/InstrTypes.h"
Bill Wendling6f81b512006-11-28 22:46:12 +000019#include "llvm/Support/Streams.h"
Chris Lattnerbc44aa62004-02-11 05:54:25 +000020#include <cstdio>
Chris Lattnerdbbbfef2004-03-08 20:03:52 +000021#include <map>
Chris Lattnerbc44aa62004-02-11 05:54:25 +000022using namespace llvm;
23
Chris Lattnerbc44aa62004-02-11 05:54:25 +000024// ByteSwap - Byteswap 'Var' if 'Really' is true.
25//
26static inline unsigned ByteSwap(unsigned Var, bool Really) {
27 if (!Really) return Var;
Misha Brukman2b37d7c2005-04-21 21:13:18 +000028 return ((Var & (255<< 0)) << 24) |
29 ((Var & (255<< 8)) << 8) |
30 ((Var & (255<<16)) >> 8) |
Chris Lattnerbc44aa62004-02-11 05:54:25 +000031 ((Var & (255<<24)) >> 24);
32}
33
34static void ReadProfilingBlock(const char *ToolName, FILE *F,
35 bool ShouldByteSwap,
36 std::vector<unsigned> &Data) {
37 // Read the number of entries...
38 unsigned NumEntries;
39 if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) {
Bill Wendling6f81b512006-11-28 22:46:12 +000040 llvm_cerr << ToolName << ": data packet truncated!\n";
Chris Lattnerbc44aa62004-02-11 05:54:25 +000041 perror(0);
42 exit(1);
43 }
44 NumEntries = ByteSwap(NumEntries, ShouldByteSwap);
45
46 // Read the counts...
47 std::vector<unsigned> TempSpace(NumEntries);
48
49 // Read in the block of data...
50 if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) {
Bill Wendling6f81b512006-11-28 22:46:12 +000051 llvm_cerr << ToolName << ": data packet truncated!\n";
Chris Lattnerbc44aa62004-02-11 05:54:25 +000052 perror(0);
53 exit(1);
54 }
55
56 // Make sure we have enough space...
57 if (Data.size() < NumEntries)
58 Data.resize(NumEntries);
Misha Brukman2b37d7c2005-04-21 21:13:18 +000059
Chris Lattnerbc44aa62004-02-11 05:54:25 +000060 // Accumulate the data we just read into the data.
61 if (!ShouldByteSwap) {
62 for (unsigned i = 0; i != NumEntries; ++i)
63 Data[i] += TempSpace[i];
64 } else {
65 for (unsigned i = 0; i != NumEntries; ++i)
66 Data[i] += ByteSwap(TempSpace[i], true);
67 }
68}
69
70// ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
71// program if the file is invalid or broken.
72//
73ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
74 const std::string &Filename,
75 Module &TheModule) : M(TheModule) {
76 FILE *F = fopen(Filename.c_str(), "r");
77 if (F == 0) {
Bill Wendling6f81b512006-11-28 22:46:12 +000078 llvm_cerr << ToolName << ": Error opening '" << Filename << "': ";
Chris Lattnerbc44aa62004-02-11 05:54:25 +000079 perror(0);
80 exit(1);
81 }
82
83 // Keep reading packets until we run out of them.
84 unsigned PacketType;
85 while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
86 // If the low eight bits of the packet are zero, we must be dealing with an
87 // endianness mismatch. Byteswap all words read from the profiling
88 // information.
89 bool ShouldByteSwap = (char)PacketType == 0;
90 PacketType = ByteSwap(PacketType, ShouldByteSwap);
91
92 switch (PacketType) {
93 case ArgumentInfo: {
94 unsigned ArgLength;
95 if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) {
Bill Wendling6f81b512006-11-28 22:46:12 +000096 llvm_cerr << ToolName << ": arguments packet truncated!\n";
Chris Lattnerbc44aa62004-02-11 05:54:25 +000097 perror(0);
98 exit(1);
99 }
100 ArgLength = ByteSwap(ArgLength, ShouldByteSwap);
101
102 // Read in the arguments...
103 std::vector<char> Chars(ArgLength+4);
104
105 if (ArgLength)
106 if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) {
Bill Wendling6f81b512006-11-28 22:46:12 +0000107 llvm_cerr << ToolName << ": arguments packet truncated!\n";
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000108 perror(0);
109 exit(1);
110 }
111 CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength]));
112 break;
113 }
Misha Brukman2b37d7c2005-04-21 21:13:18 +0000114
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000115 case FunctionInfo:
116 ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts);
117 break;
Misha Brukman2b37d7c2005-04-21 21:13:18 +0000118
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000119 case BlockInfo:
120 ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts);
121 break;
122
Chris Lattner01945c12004-03-08 18:20:18 +0000123 case EdgeInfo:
124 ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
125 break;
126
Brian Gaekeb171d792004-05-04 17:11:14 +0000127 case BBTraceInfo:
128 ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace);
129 break;
130
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000131 default:
Bill Wendling6f81b512006-11-28 22:46:12 +0000132 llvm_cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n";
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000133 exit(1);
134 }
135 }
Misha Brukman2b37d7c2005-04-21 21:13:18 +0000136
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000137 fclose(F);
138}
139
140
141// getFunctionCounts - This method is used by consumers of function counting
142// information. If we do not directly have function count information, we
143// compute it from other, more refined, types of profile information.
144//
145void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
146 unsigned> > &Counts) {
147 if (FunctionCounts.empty()) {
Chris Lattnerdbbbfef2004-03-08 20:03:52 +0000148 if (hasAccurateBlockCounts()) {
149 // Synthesize function frequency information from the number of times
150 // their entry blocks were executed.
151 std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
152 getBlockCounts(BlockCounts);
Misha Brukman2b37d7c2005-04-21 21:13:18 +0000153
Chris Lattnerdbbbfef2004-03-08 20:03:52 +0000154 for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
155 if (&BlockCounts[i].first->getParent()->front() == BlockCounts[i].first)
156 Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
157 BlockCounts[i].second));
158 } else {
Bill Wendling6f81b512006-11-28 22:46:12 +0000159 llvm_cerr << "Function counts are not available!\n";
Chris Lattnerdbbbfef2004-03-08 20:03:52 +0000160 }
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000161 return;
162 }
Misha Brukman2b37d7c2005-04-21 21:13:18 +0000163
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000164 unsigned Counter = 0;
165 for (Module::iterator I = M.begin(), E = M.end();
166 I != E && Counter != FunctionCounts.size(); ++I)
167 if (!I->isExternal())
168 Counts.push_back(std::make_pair(I, FunctionCounts[Counter++]));
169}
170
171// getBlockCounts - This method is used by consumers of block counting
172// information. If we do not directly have block count information, we
173// compute it from other, more refined, types of profile information.
174//
175void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
176 unsigned> > &Counts) {
177 if (BlockCounts.empty()) {
Chris Lattnerdbbbfef2004-03-08 20:03:52 +0000178 if (hasAccurateEdgeCounts()) {
179 // Synthesize block count information from edge frequency information.
180 // The block execution frequency is equal to the sum of the execution
181 // frequency of all outgoing edges from a block.
182 //
183 // If a block has no successors, this will not be correct, so we have to
184 // special case it. :(
185 std::vector<std::pair<Edge, unsigned> > EdgeCounts;
186 getEdgeCounts(EdgeCounts);
187
188 std::map<BasicBlock*, unsigned> InEdgeFreqs;
189
190 BasicBlock *LastBlock = 0;
191 TerminatorInst *TI = 0;
192 for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) {
193 if (EdgeCounts[i].first.first != LastBlock) {
194 LastBlock = EdgeCounts[i].first.first;
195 TI = LastBlock->getTerminator();
196 Counts.push_back(std::make_pair(LastBlock, 0));
197 }
198 Counts.back().second += EdgeCounts[i].second;
199 unsigned SuccNum = EdgeCounts[i].first.second;
200 if (SuccNum >= TI->getNumSuccessors()) {
201 static bool Warned = false;
202 if (!Warned) {
Bill Wendling6f81b512006-11-28 22:46:12 +0000203 llvm_cerr << "WARNING: profile info doesn't seem to match"
Chris Lattnerdbbbfef2004-03-08 20:03:52 +0000204 << " the program!\n";
205 Warned = true;
206 }
207 } else {
208 // If this successor has no successors of its own, we will never
209 // compute an execution count for that block. Remember the incoming
210 // edge frequencies to add later.
211 BasicBlock *Succ = TI->getSuccessor(SuccNum);
212 if (Succ->getTerminator()->getNumSuccessors() == 0)
213 InEdgeFreqs[Succ] += EdgeCounts[i].second;
214 }
215 }
216
217 // Now we have to accumulate information for those blocks without
218 // successors into our table.
219 for (std::map<BasicBlock*, unsigned>::iterator I = InEdgeFreqs.begin(),
220 E = InEdgeFreqs.end(); I != E; ++I) {
221 unsigned i = 0;
222 for (; i != Counts.size() && Counts[i].first != I->first; ++i)
223 /*empty*/;
224 if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0));
225 Counts[i].second += I->second;
226 }
227
228 } else {
Bill Wendling6f81b512006-11-28 22:46:12 +0000229 llvm_cerr << "Block counts are not available!\n";
Chris Lattnerdbbbfef2004-03-08 20:03:52 +0000230 }
Chris Lattnerbc44aa62004-02-11 05:54:25 +0000231 return;
232 }
233
234 unsigned Counter = 0;
235 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
236 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
237 Counts.push_back(std::make_pair(BB, BlockCounts[Counter++]));
238 if (Counter == BlockCounts.size())
239 return;
240 }
241}
Chris Lattner01945c12004-03-08 18:20:18 +0000242
243// getEdgeCounts - This method is used by consumers of edge counting
244// information. If we do not directly have edge count information, we compute
245// it from other, more refined, types of profile information.
246//
247void ProfileInfoLoader::getEdgeCounts(std::vector<std::pair<Edge,
248 unsigned> > &Counts) {
249 if (EdgeCounts.empty()) {
Bill Wendling6f81b512006-11-28 22:46:12 +0000250 llvm_cerr << "Edge counts not available, and no synthesis "
Chris Lattner01945c12004-03-08 18:20:18 +0000251 << "is implemented yet!\n";
252 return;
253 }
254
255 unsigned Counter = 0;
256 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
257 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
258 for (unsigned i = 0, e = BB->getTerminator()->getNumSuccessors();
259 i != e; ++i) {
260 Counts.push_back(std::make_pair(Edge(BB, i), EdgeCounts[Counter++]));
261 if (Counter == EdgeCounts.size())
262 return;
263 }
264}
Brian Gaekeb171d792004-05-04 17:11:14 +0000265
266// getBBTrace - This method is used by consumers of basic-block trace
267// information.
268//
269void ProfileInfoLoader::getBBTrace(std::vector<BasicBlock *> &Trace) {
270 if (BBTrace.empty ()) {
Bill Wendling6f81b512006-11-28 22:46:12 +0000271 llvm_cerr << "Basic block trace is not available!\n";
Brian Gaekeb171d792004-05-04 17:11:14 +0000272 return;
273 }
Bill Wendling6f81b512006-11-28 22:46:12 +0000274 llvm_cerr << "Basic block trace loading is not implemented yet!\n";
Brian Gaekeb171d792004-05-04 17:11:14 +0000275}
276