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