InstrProf: Add a missing const_cast from r248833
[oota-llvm.git] / include / llvm / ProfileData / InstrProf.h
1 //=-- InstrProf.h - Instrumented profiling format support ---------*- C++ -*-=//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Instrumentation-based profiling data is generated by instrumented
11 // binaries through library functions in compiler-rt, and read by the clang
12 // frontend to feed PGO.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_PROFILEDATA_INSTRPROF_H_
17 #define LLVM_PROFILEDATA_INSTRPROF_H_
18
19 #include "llvm/ADT/StringSet.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include <cstdint>
22 #include <list>
23 #include <system_error>
24 #include <vector>
25
26 namespace llvm {
27 const std::error_category &instrprof_category();
28
29 enum class instrprof_error {
30   success = 0,
31   eof,
32   bad_magic,
33   bad_header,
34   unsupported_version,
35   unsupported_hash_type,
36   too_large,
37   truncated,
38   malformed,
39   unknown_function,
40   hash_mismatch,
41   count_mismatch,
42   counter_overflow,
43   value_site_count_mismatch
44 };
45
46 inline std::error_code make_error_code(instrprof_error E) {
47   return std::error_code(static_cast<int>(E), instrprof_category());
48 }
49
50 enum InstrProfValueKind : uint32_t {
51   IPVK_IndirectCallTarget = 0,
52
53   IPVK_First = IPVK_IndirectCallTarget,
54   IPVK_Last = IPVK_IndirectCallTarget
55 };
56
57 struct InstrProfStringTable {
58   // Set of string values in profiling data.
59   StringSet<> StringValueSet;
60   InstrProfStringTable() { StringValueSet.clear(); }
61   // Get a pointer to internal storage of a string in set
62   const char *getStringData(StringRef Str) {
63     auto Result = StringValueSet.find(Str);
64     return (Result == StringValueSet.end()) ? nullptr : Result->first().data();
65   }
66   // Insert a string to StringTable
67   const char *insertString(StringRef Str) {
68     auto Result = StringValueSet.insert(Str);
69     return Result.first->first().data();
70   }
71 };
72
73 struct InstrProfValueSiteRecord {
74   /// Typedef for a single TargetValue-NumTaken pair.
75   typedef std::pair<uint64_t, uint64_t> ValueDataPair;
76   /// Value profiling data pairs at a given value site.
77   std::list<ValueDataPair> ValueData;
78
79   InstrProfValueSiteRecord() { ValueData.clear(); }
80
81   /// Sort ValueData ascending by TargetValue
82   void sortByTargetValues() {
83     ValueData.sort([](const ValueDataPair &left, const ValueDataPair &right) {
84       return left.first < right.first;
85     });
86   }
87
88   /// Merge data from another InstrProfValueSiteRecord
89   void mergeValueData(InstrProfValueSiteRecord &Input) {
90     this->sortByTargetValues();
91     Input.sortByTargetValues();
92     auto I = ValueData.begin();
93     auto IE = ValueData.end();
94     for (auto J = Input.ValueData.begin(), JE = Input.ValueData.end(); J != JE;
95          ++J) {
96       while (I != IE && I->first < J->first)
97         ++I;
98       if (I != IE && I->first == J->first) {
99         I->second += J->second;
100         ++I;
101         continue;
102       }
103       ValueData.insert(I, *J);
104     }
105   }
106 };
107
108 /// Profiling information for a single function.
109 struct InstrProfRecord {
110   InstrProfRecord() {}
111   InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts)
112       : Name(Name), Hash(Hash), Counts(std::move(Counts)) {}
113   StringRef Name;
114   uint64_t Hash;
115   std::vector<uint64_t> Counts;
116   std::vector<InstrProfValueSiteRecord> IndirectCallSites;
117
118   const std::vector<InstrProfValueSiteRecord> &
119   getValueSitesForKind(uint32_t ValueKind) const {
120     switch (ValueKind) {
121     case IPVK_IndirectCallTarget:
122       return IndirectCallSites;
123     }
124     llvm_unreachable("Unknown value kind!");
125   }
126
127   std::vector<InstrProfValueSiteRecord> &
128   getValueSitesForKind(uint32_t ValueKind) {
129     return const_cast<std::vector<InstrProfValueSiteRecord> &>(
130         const_cast<const InstrProfRecord *>(this)
131             ->getValueSitesForKind(ValueKind));
132   }
133 };
134
135 } // end namespace llvm
136
137 namespace std {
138 template <>
139 struct is_error_code_enum<llvm::instrprof_error> : std::true_type {};
140 }
141
142 #endif // LLVM_PROFILEDATA_INSTRPROF_H_