mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Profile: Add a library for the instrumentation based profiling format
This provides a library to work with the instrumentation based profiling format that is used by clang's -fprofile-instr-* options and by the llvm-profdata tool. This is a binary format, rather than the textual one that's currently in use. The tests are in the subsequent commits that use this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203703 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		
							
								
								
									
										71
									
								
								lib/Profile/ProfileDataWriter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								lib/Profile/ProfileDataWriter.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| //=-- ProfileDataWriter.cpp - Instrumented profiling writer -----------------=// | ||||
| // | ||||
| //                     The LLVM Compiler Infrastructure | ||||
| // | ||||
| // This file is distributed under the University of Illinois Open Source | ||||
| // License. See LICENSE.TXT for details. | ||||
| // | ||||
| //===----------------------------------------------------------------------===// | ||||
| // | ||||
| // This file contains support for writing profiling data for clang's | ||||
| // instrumentation based PGO and coverage. | ||||
| // | ||||
| //===----------------------------------------------------------------------===// | ||||
|  | ||||
| #include "llvm/Profile/ProfileDataWriter.h" | ||||
| #include "llvm/Profile/ProfileData.h" | ||||
| #include "llvm/Support/Endian.h" | ||||
|  | ||||
| using namespace llvm; | ||||
|  | ||||
| template <typename T> | ||||
| struct LEBytes { | ||||
|   const T &Data; | ||||
|   LEBytes(const T &Data) : Data(Data) {} | ||||
|   void print(raw_ostream &OS) const { | ||||
|     for (uint32_t Shift = 0; Shift < sizeof(Data); ++Shift) | ||||
|       OS << (char)((Data >> (8 * Shift)) & 0xFF); | ||||
|   } | ||||
| }; | ||||
| template <typename T> | ||||
| static raw_ostream &operator<<(raw_ostream &OS, const LEBytes<T> &Bytes) { | ||||
|   Bytes.print(OS); | ||||
|   return OS; | ||||
| } | ||||
|  | ||||
| void ProfileDataWriter::addFunctionCounts(StringRef FuncName, | ||||
|                                           uint64_t FunctionHash, | ||||
|                                           uint64_t NumCounters, | ||||
|                                           const uint64_t *Counters) { | ||||
|   DataStart += 2 * sizeof(uint32_t) + FuncName.size(); | ||||
|   FunctionOffsets[FuncName] = FunctionData.size() * sizeof(uint64_t); | ||||
|   FunctionData.push_back(FunctionHash); | ||||
|   FunctionData.push_back(NumCounters); | ||||
|   assert(NumCounters > 0 && "Function call counter missing!"); | ||||
|   if (Counters[0] > MaxFunctionCount) | ||||
|     MaxFunctionCount = Counters[0]; | ||||
|   for (uint64_t I = 0; I < NumCounters; ++I) | ||||
|     FunctionData.push_back(Counters[I]); | ||||
| } | ||||
|  | ||||
| void ProfileDataWriter::write(raw_ostream &OS) { | ||||
|   for (char C : PROFILEDATA_MAGIC) | ||||
|     OS << C; | ||||
|   OS << LEBytes<uint32_t>(PROFILEDATA_VERSION); | ||||
|   OS << LEBytes<uint32_t>(DataStart); | ||||
|   OS << LEBytes<uint32_t>(0); | ||||
|   OS << LEBytes<uint64_t>(MaxFunctionCount); | ||||
|  | ||||
|   for (const auto &I : FunctionOffsets) { | ||||
|     StringRef Name = I.getKey(); | ||||
|     OS << LEBytes<uint32_t>(Name.size()); | ||||
|     OS << Name; | ||||
|     OS << LEBytes<uint32_t>(I.getValue()); | ||||
|   } | ||||
|  | ||||
|   for (unsigned I = 0; I < sizeof(uint64_t) - DataStart % sizeof(uint64_t); ++I) | ||||
|     OS << '\0'; | ||||
|  | ||||
|   for (uint64_t Value : FunctionData) | ||||
|     OS << LEBytes<uint64_t>(Value); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user