8
8
9
9
#include " bolt/Profile/BoltAddressTranslation.h"
10
10
#include " bolt/Core/BinaryFunction.h"
11
- #include " llvm/Support/DataExtractor.h"
12
11
#include " llvm/Support/Errc.h"
13
12
#include " llvm/Support/Error.h"
14
13
#include " llvm/Support/LEB128.h"
@@ -103,18 +102,42 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
103
102
}
104
103
}
105
104
106
- const uint32_t NumFuncs = Maps.size ();
105
+ writeMaps</* Cold=*/ false >(Maps, OS);
106
+ writeMaps</* Cold=*/ true >(Maps, OS);
107
+
108
+ outs () << " BOLT-INFO: Wrote " << Maps.size () << " BAT maps\n " ;
109
+ }
110
+
111
+ template <bool Cold>
112
+ void BoltAddressTranslation::writeMaps (std::map<uint64_t , MapTy> &Maps,
113
+ raw_ostream &OS) {
114
+ const uint32_t NumFuncs =
115
+ llvm::count_if (llvm::make_first_range (Maps), [&](const uint64_t Address) {
116
+ return Cold == ColdPartSource.count (Address);
117
+ });
107
118
encodeULEB128 (NumFuncs, OS);
108
- LLVM_DEBUG (dbgs () << " Writing " << NumFuncs << " functions for BAT.\n " );
119
+ LLVM_DEBUG (dbgs () << " Writing " << NumFuncs << (Cold ? " cold" : " " )
120
+ << " functions for BAT.\n " );
121
+ size_t PrevIndex = 0 ;
122
+ // Output addresses are delta-encoded
109
123
uint64_t PrevAddress = 0 ;
110
124
for (auto &MapEntry : Maps) {
111
125
const uint64_t Address = MapEntry.first ;
126
+ // Only process cold fragments in cold mode, and vice versa.
127
+ if (Cold != ColdPartSource.count (Address))
128
+ continue ;
112
129
MapTy &Map = MapEntry.second ;
113
130
const uint32_t NumEntries = Map.size ();
114
131
LLVM_DEBUG (dbgs () << " Writing " << NumEntries << " entries for 0x"
115
132
<< Twine::utohexstr (Address) << " .\n " );
116
133
encodeULEB128 (Address - PrevAddress, OS);
117
134
PrevAddress = Address;
135
+ if (Cold) {
136
+ size_t HotIndex =
137
+ std::distance (ColdPartSource.begin (), ColdPartSource.find (Address));
138
+ encodeULEB128 (HotIndex - PrevIndex, OS);
139
+ PrevIndex = HotIndex;
140
+ }
118
141
encodeULEB128 (NumEntries, OS);
119
142
uint64_t InOffset = 0 , OutOffset = 0 ;
120
143
// Output and Input addresses and delta-encoded
@@ -124,20 +147,6 @@ void BoltAddressTranslation::write(const BinaryContext &BC, raw_ostream &OS) {
124
147
std::tie (OutOffset, InOffset) = KeyVal;
125
148
}
126
149
}
127
- const uint32_t NumColdEntries = ColdPartSource.size ();
128
- LLVM_DEBUG (dbgs () << " Writing " << NumColdEntries
129
- << " cold part mappings.\n " );
130
- encodeULEB128 (NumColdEntries, OS);
131
- for (std::pair<const uint64_t , uint64_t > &ColdEntry : ColdPartSource) {
132
- encodeULEB128 (ColdEntry.first , OS);
133
- encodeULEB128 (ColdEntry.second , OS);
134
- LLVM_DEBUG (dbgs () << " " << Twine::utohexstr (ColdEntry.first ) << " -> "
135
- << Twine::utohexstr (ColdEntry.second ) << " \n " );
136
- }
137
-
138
- outs () << " BOLT-INFO: Wrote " << Maps.size () << " BAT maps\n " ;
139
- outs () << " BOLT-INFO: Wrote " << NumColdEntries
140
- << " BAT cold-to-hot entries\n " ;
141
150
}
142
151
143
152
std::error_code BoltAddressTranslation::parse (StringRef Buf) {
@@ -160,12 +169,31 @@ std::error_code BoltAddressTranslation::parse(StringRef Buf) {
160
169
return make_error_code (llvm::errc::io_error);
161
170
162
171
Error Err (Error::success ());
172
+ std::vector<uint64_t > HotFuncs;
173
+ parseMaps</* Cold=*/ false >(HotFuncs, DE, Offset, Err);
174
+ parseMaps</* Cold=*/ true >(HotFuncs, DE, Offset, Err);
175
+ outs () << " BOLT-INFO: Parsed " << Maps.size () << " BAT entries\n " ;
176
+ return errorToErrorCode (std::move (Err));
177
+ }
178
+
179
+ template <bool Cold>
180
+ void BoltAddressTranslation::parseMaps (std::vector<uint64_t > &HotFuncs,
181
+ DataExtractor &DE, uint64_t &Offset,
182
+ Error &Err) {
163
183
const uint32_t NumFunctions = DE.getULEB128 (&Offset, &Err);
164
- LLVM_DEBUG (dbgs () << " Parsing " << NumFunctions << " functions\n " );
184
+ LLVM_DEBUG (dbgs () << " Parsing " << NumFunctions << (Cold ? " cold" : " " )
185
+ << " functions\n " );
186
+ size_t HotIndex = 0 ;
165
187
uint64_t PrevAddress = 0 ;
166
188
for (uint32_t I = 0 ; I < NumFunctions; ++I) {
167
189
const uint64_t Address = PrevAddress + DE.getULEB128 (&Offset, &Err);
168
190
PrevAddress = Address;
191
+ if (Cold) {
192
+ HotIndex += DE.getULEB128 (&Offset, &Err);
193
+ ColdPartSource.emplace (Address, HotFuncs[HotIndex]);
194
+ } else {
195
+ HotFuncs.push_back (Address);
196
+ }
169
197
const uint32_t NumEntries = DE.getULEB128 (&Offset, &Err);
170
198
MapTy Map;
171
199
@@ -178,28 +206,14 @@ std::error_code BoltAddressTranslation::parse(StringRef Buf) {
178
206
OutputOffset += OutputDelta;
179
207
InputOffset += InputDelta;
180
208
Map.insert (std::pair<uint32_t , uint32_t >(OutputOffset, InputOffset));
181
- LLVM_DEBUG (dbgs () << Twine::utohexstr (OutputOffset) << " -> "
182
- << Twine::utohexstr (InputOffset) << " (" << OutputDelta
183
- << " , " << InputDelta << " )\n " );
209
+ LLVM_DEBUG (dbgs () << formatv (" {0:x} -> {1:x} ({2}/{3}b -> {4}/{5}b)\n " ,
210
+ OutputOffset, InputOffset, OutputDelta,
211
+ encodeULEB128 (OutputDelta, nulls ()),
212
+ InputDelta,
213
+ encodeSLEB128 (InputDelta, nulls ())));
184
214
}
185
215
Maps.insert (std::pair<uint64_t , MapTy>(Address, Map));
186
216
}
187
-
188
- const uint32_t NumColdEntries = DE.getULEB128 (&Offset, &Err);
189
- LLVM_DEBUG (dbgs () << " Parsing " << NumColdEntries << " cold part mappings\n " );
190
- for (uint32_t I = 0 ; I < NumColdEntries; ++I) {
191
- const uint32_t ColdAddress = DE.getULEB128 (&Offset, &Err);
192
- const uint32_t HotAddress = DE.getULEB128 (&Offset, &Err);
193
- ColdPartSource.insert (
194
- std::pair<uint64_t , uint64_t >(ColdAddress, HotAddress));
195
- LLVM_DEBUG (dbgs () << Twine::utohexstr (ColdAddress) << " -> "
196
- << Twine::utohexstr (HotAddress) << " \n " );
197
- }
198
- outs () << " BOLT-INFO: Parsed " << Maps.size () << " BAT entries\n " ;
199
- outs () << " BOLT-INFO: Parsed " << NumColdEntries
200
- << " BAT cold-to-hot entries\n " ;
201
-
202
- return errorToErrorCode (std::move (Err));
203
217
}
204
218
205
219
void BoltAddressTranslation::dump (raw_ostream &OS) {
0 commit comments