1bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner//===- ProfileInfoLoad.cpp - Load profile information from disk -----------===// 22b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman// 3bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// The LLVM Compiler Infrastructure 4bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 72b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman// 8bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner//===----------------------------------------------------------------------===// 9bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// 10bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// The ProfileInfoLoader class is used to load and represent profiling 11bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// information read in from the dump file. 12bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// 13bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner//===----------------------------------------------------------------------===// 14bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 15bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner#include "llvm/Analysis/ProfileInfoLoader.h" 16660ef70b6292e69456239f34eaefa81fd18761fbBrian Gaeke#include "llvm/Analysis/ProfileInfoTypes.h" 17bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner#include "llvm/Module.h" 1801945c17398ec5f2934f4a166a231e3aea17831bChris Lattner#include "llvm/InstrTypes.h" 19a81d29b3916c2eb87a17f800f3759ce21a4a96fdChris Lattner#include "llvm/Support/raw_ostream.h" 20bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner#include <cstdio> 21d68a07650cdb2e18f18f362ba533459aa10e01b6Dan Gohman#include <cstdlib> 22bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattnerusing namespace llvm; 23bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 24bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// ByteSwap - Byteswap 'Var' if 'Really' is true. 25bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// 26bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattnerstatic inline unsigned ByteSwap(unsigned Var, bool Really) { 27bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (!Really) return Var; 2818f13c66bfb9cb2116be0f339fa955949dd60dd1Duncan Sands return ((Var & (255U<< 0U)) << 24U) | 2918f13c66bfb9cb2116be0f339fa955949dd60dd1Duncan Sands ((Var & (255U<< 8U)) << 8U) | 3018f13c66bfb9cb2116be0f339fa955949dd60dd1Duncan Sands ((Var & (255U<<16U)) >> 8U) | 3118f13c66bfb9cb2116be0f339fa955949dd60dd1Duncan Sands ((Var & (255U<<24U)) >> 24U); 32bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner} 33bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 34f0d568d38b24cc157861b9cd1dc993efe07b3fe9Andreas Neustifterstatic unsigned AddCounts(unsigned A, unsigned B) { 354c2c53353e8998a94058c110bdddcbc84e3cd3fcAndreas Neustifter // If either value is undefined, use the other. 36923327267949b537d7a2fdad5b7a919bd90ce085Andreas Neustifter if (A == ProfileInfoLoader::Uncounted) return B; 37923327267949b537d7a2fdad5b7a919bd90ce085Andreas Neustifter if (B == ProfileInfoLoader::Uncounted) return A; 384c2c53353e8998a94058c110bdddcbc84e3cd3fcAndreas Neustifter return A + B; 394c2c53353e8998a94058c110bdddcbc84e3cd3fcAndreas Neustifter} 404c2c53353e8998a94058c110bdddcbc84e3cd3fcAndreas Neustifter 41bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattnerstatic void ReadProfilingBlock(const char *ToolName, FILE *F, 42bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner bool ShouldByteSwap, 43bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner std::vector<unsigned> &Data) { 44bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // Read the number of entries... 45bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner unsigned NumEntries; 46bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) { 47a81d29b3916c2eb87a17f800f3759ce21a4a96fdChris Lattner errs() << ToolName << ": data packet truncated!\n"; 48bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner perror(0); 49bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner exit(1); 50bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 51bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner NumEntries = ByteSwap(NumEntries, ShouldByteSwap); 52bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 53bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // Read the counts... 54bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner std::vector<unsigned> TempSpace(NumEntries); 55bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 56bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // Read in the block of data... 57bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) { 58a81d29b3916c2eb87a17f800f3759ce21a4a96fdChris Lattner errs() << ToolName << ": data packet truncated!\n"; 59bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner perror(0); 60bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner exit(1); 61bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 62bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 63da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter // Make sure we have enough space... The space is initialised to -1 to 64da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter // facitiltate the loading of missing values for OptimalEdgeProfiling. 65bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (Data.size() < NumEntries) 66923327267949b537d7a2fdad5b7a919bd90ce085Andreas Neustifter Data.resize(NumEntries, ProfileInfoLoader::Uncounted); 672b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman 68bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // Accumulate the data we just read into the data. 69bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (!ShouldByteSwap) { 70da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter for (unsigned i = 0; i != NumEntries; ++i) { 714c2c53353e8998a94058c110bdddcbc84e3cd3fcAndreas Neustifter Data[i] = AddCounts(TempSpace[i], Data[i]); 72da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter } 73bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } else { 74da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter for (unsigned i = 0; i != NumEntries; ++i) { 754c2c53353e8998a94058c110bdddcbc84e3cd3fcAndreas Neustifter Data[i] = AddCounts(ByteSwap(TempSpace[i], true), Data[i]); 76da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter } 77bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 78bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner} 79bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 80923327267949b537d7a2fdad5b7a919bd90ce085Andreas Neustifterconst unsigned ProfileInfoLoader::Uncounted = ~0U; 81923327267949b537d7a2fdad5b7a919bd90ce085Andreas Neustifter 82bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// ProfileInfoLoader ctor - Read the specified profiling data file, exiting the 83bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// program if the file is invalid or broken. 84bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner// 85bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris LattnerProfileInfoLoader::ProfileInfoLoader(const char *ToolName, 86bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner const std::string &Filename, 87ee16638bfc9c17068c4b3c2dc130277785a11e20Daniel Dunbar Module &TheModule) : 88ee16638bfc9c17068c4b3c2dc130277785a11e20Daniel Dunbar Filename(Filename), 89ee16638bfc9c17068c4b3c2dc130277785a11e20Daniel Dunbar M(TheModule), Warned(false) { 90cf48efcf3dc6c825a113448105763fab9de9aa53Andreas Neustifter FILE *F = fopen(Filename.c_str(), "rb"); 91bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (F == 0) { 92a81d29b3916c2eb87a17f800f3759ce21a4a96fdChris Lattner errs() << ToolName << ": Error opening '" << Filename << "': "; 93bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner perror(0); 94bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner exit(1); 95bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 96bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 97bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // Keep reading packets until we run out of them. 98bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner unsigned PacketType; 99bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) { 100bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // If the low eight bits of the packet are zero, we must be dealing with an 101bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // endianness mismatch. Byteswap all words read from the profiling 102bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // information. 103bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner bool ShouldByteSwap = (char)PacketType == 0; 104bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner PacketType = ByteSwap(PacketType, ShouldByteSwap); 105bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 106bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner switch (PacketType) { 107bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner case ArgumentInfo: { 108bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner unsigned ArgLength; 109bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) { 110a81d29b3916c2eb87a17f800f3759ce21a4a96fdChris Lattner errs() << ToolName << ": arguments packet truncated!\n"; 111bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner perror(0); 112bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner exit(1); 113bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 114bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner ArgLength = ByteSwap(ArgLength, ShouldByteSwap); 115bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 116bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner // Read in the arguments... 117bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner std::vector<char> Chars(ArgLength+4); 118bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 119bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (ArgLength) 120bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) { 121a81d29b3916c2eb87a17f800f3759ce21a4a96fdChris Lattner errs() << ToolName << ": arguments packet truncated!\n"; 122bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner perror(0); 123bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner exit(1); 124bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 125bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength])); 126bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner break; 127bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 1282b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman 129bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner case FunctionInfo: 130bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts); 131bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner break; 1322b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman 133bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner case BlockInfo: 134bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts); 135bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner break; 136bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 13701945c17398ec5f2934f4a166a231e3aea17831bChris Lattner case EdgeInfo: 13801945c17398ec5f2934f4a166a231e3aea17831bChris Lattner ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts); 13901945c17398ec5f2934f4a166a231e3aea17831bChris Lattner break; 14001945c17398ec5f2934f4a166a231e3aea17831bChris Lattner 141da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter case OptEdgeInfo: 142da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter ReadProfilingBlock(ToolName, F, ShouldByteSwap, OptimalEdgeCounts); 143da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter break; 144da5ea945545ca8864a873a5a33fd891ec381ec88Andreas Neustifter 145b171d7949df29d4676a1c3c5e62ae0b765eee850Brian Gaeke case BBTraceInfo: 146b171d7949df29d4676a1c3c5e62ae0b765eee850Brian Gaeke ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace); 147b171d7949df29d4676a1c3c5e62ae0b765eee850Brian Gaeke break; 148b171d7949df29d4676a1c3c5e62ae0b765eee850Brian Gaeke 149bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner default: 150a81d29b3916c2eb87a17f800f3759ce21a4a96fdChris Lattner errs() << ToolName << ": Unknown packet type #" << PacketType << "!\n"; 151bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner exit(1); 152bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 153bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner } 1542b37d7cf28b1382420b5e4007042feeb66d21ac8Misha Brukman 155bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner fclose(F); 156bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner} 157bc44aa61c41277e85f1daec2740a7a12ed8e62b6Chris Lattner 158