1 //===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // The ProfileInfoLoader class is used to load and represent profiling
11 // information read in from the dump file.
13 //===----------------------------------------------------------------------===//
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"
24 // ByteSwap - Byteswap 'Var' if 'Really' is true.
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);
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
;
41 static void ReadProfilingBlock(const char *ToolName
, FILE *F
,
43 std::vector
<unsigned> &Data
) {
44 // Read the number of entries...
46 if (fread(&NumEntries
, sizeof(unsigned), 1, F
) != 1) {
47 errs() << ToolName
<< ": data packet truncated!\n";
51 NumEntries
= ByteSwap(NumEntries
, ShouldByteSwap
);
54 std::vector
<unsigned> TempSpace(NumEntries
);
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";
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
);
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
]);
74 for (unsigned i
= 0; i
!= NumEntries
; ++i
) {
75 Data
[i
] = AddCounts(ByteSwap(TempSpace
[i
], true), Data
[i
]);
80 const unsigned ProfileInfoLoader::Uncounted
= ~0U;
82 // ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
83 // program if the file is invalid or broken.
85 ProfileInfoLoader::ProfileInfoLoader(const char *ToolName
,
86 const std::string
&Filename
,
89 M(TheModule
), Warned(false) {
90 FILE *F
= fopen(Filename
.c_str(), "rb");
92 errs() << ToolName
<< ": Error opening '" << Filename
<< "': ";
97 // Keep reading packets until we run out of them.
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
103 bool ShouldByteSwap
= (char)PacketType
== 0;
104 PacketType
= ByteSwap(PacketType
, ShouldByteSwap
);
106 switch (PacketType
) {
109 if (fread(&ArgLength
, sizeof(unsigned), 1, F
) != 1) {
110 errs() << ToolName
<< ": arguments packet truncated!\n";
114 ArgLength
= ByteSwap(ArgLength
, ShouldByteSwap
);
116 // Read in the arguments...
117 std::vector
<char> Chars(ArgLength
+4);
120 if (fread(&Chars
[0], (ArgLength
+3) & ~3, 1, F
) != 1) {
121 errs() << ToolName
<< ": arguments packet truncated!\n";
125 CommandLines
.push_back(std::string(&Chars
[0], &Chars
[ArgLength
]));
130 ReadProfilingBlock(ToolName
, F
, ShouldByteSwap
, FunctionCounts
);
134 ReadProfilingBlock(ToolName
, F
, ShouldByteSwap
, BlockCounts
);
138 ReadProfilingBlock(ToolName
, F
, ShouldByteSwap
, EdgeCounts
);
142 ReadProfilingBlock(ToolName
, F
, ShouldByteSwap
, OptimalEdgeCounts
);
146 ReadProfilingBlock(ToolName
, F
, ShouldByteSwap
, BBTrace
);
150 errs() << ToolName
<< ": Unknown packet type #" << PacketType
<< "!\n";