136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//=-- InstrProfWriter.h - Instrumented profiling writer -----------*- C++ -*-=// 236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The LLVM Compiler Infrastructure 436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source 636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details. 736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file contains support for writing profiling data for instrumentation 1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// based PGO and coverage. 1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_PROFILEDATA_INSTRPROFWRITER_H 1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_PROFILEDATA_INSTRPROFWRITER_H 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/ADT/DenseMap.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ProfileData/InstrProf.h" 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/DataTypes.h" 21ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/MemoryBuffer.h" 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/raw_ostream.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm { 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Writer for instrumentation based profile data. 27de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass ProfOStream; 28de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarclass InstrProfRecordWriterTrait; 29de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass InstrProfWriter { 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar typedef SmallDenseMap<uint64_t, InstrProfRecord, 1> ProfilingData; 33de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar enum ProfKind { PF_Unknown = 0, PF_FE, PF_IRLevel }; 34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate: 36de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool Sparse; 37f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar StringMap<ProfilingData> FunctionData; 38de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ProfKind ProfileKind; 39de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar // Use raw pointer here for the incomplete type object. 40de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar InstrProfRecordWriterTrait *InfoObj; 41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 43de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar InstrProfWriter(bool Sparse = false); 44de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ~InstrProfWriter(); 4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Add function counts for the given function. If there are already counts 4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// for this function and the hash and number of counts match, each counter is 48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// summed. Optionally scale counts by \p Weight. 49de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error addRecord(InstrProfRecord &&I, uint64_t Weight = 1); 50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// Write the profile to \c OS 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void write(raw_fd_ostream &OS); 52f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// Write the profile in text format to \c OS 53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void writeText(raw_fd_ostream &OS); 54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// Write \c Record in text format to \c OS 55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar static void writeRecordInText(const InstrProfRecord &Record, 56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar InstrProfSymtab &Symtab, raw_fd_ostream &OS); 57ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// Write the profile, returning the raw data. For testing. 58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<MemoryBuffer> writeBuffer(); 59ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar /// Set the ProfileKind. Report error if mixing FE and IR level profiles. 61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar Error setIsIRLevelProfile(bool IsIRLevel) { 62de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar if (ProfileKind == PF_Unknown) { 63de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ProfileKind = IsIRLevel ? PF_IRLevel: PF_FE; 64de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return Error::success(); 65de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 66de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar return (IsIRLevel == (ProfileKind == PF_IRLevel)) 67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar ? Error::success() 68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar : make_error<InstrProfError>( 69de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar instrprof_error::unsupported_version); 70de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar } 71de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar 72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Internal interface for testing purpose only. 73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void setValueProfDataEndianness(support::endianness Endianness); 74de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void setOutputSparse(bool Sparse); 75f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesprivate: 77de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar bool shouldEncodeData(const ProfilingData &PD); 78de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar void writeImpl(ProfOStream &OS); 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end namespace llvm 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#endif 84