Skip to content

Commit 97f4336

Browse files
authored
[BOLT][NFC] Speedup merge-fdata (#119942)
Eliminate splitting the buffer into lines, and use `std::getline` directly. Simplify no_lbr and boltedcollection handling as well. Test Plan: For a large fdata file (200MB), fstream version is ~10% faster.
1 parent fe9f2ac commit 97f4336

File tree

3 files changed

+24
-39
lines changed

3 files changed

+24
-39
lines changed

bolt/test/merge-fdata-mixed-bat-no-lbr.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# RUN: split-file %s %t
66
# RUN: not merge-fdata %t/a.fdata %t/b.fdata 2>&1 | FileCheck %s
77

8-
# CHECK: cannot mix profile collected in BOLT and non-BOLT deployments
8+
# CHECK: cannot mix profile with and without boltedcollection
99

1010
#--- a.fdata
1111
boltedcollection

bolt/test/merge-fdata-mixed-mode.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# RUN: split-file %s %t
77
# RUN: not merge-fdata %t/a.fdata %t/b.fdata 2>&1 | FileCheck %s
88

9-
# CHECK: cannot mix 'no_lbr' and 'lbr' profiles.
9+
# CHECK: cannot mix profile with and without no_lbr
1010

1111
#--- a.fdata
1212
no_lbr

bolt/tools/merge-fdata/merge-fdata.cpp

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Support/Signals.h"
2323
#include "llvm/Support/ThreadPool.h"
2424
#include <algorithm>
25+
#include <fstream>
2526
#include <mutex>
2627
#include <unordered_map>
2728

@@ -274,52 +275,36 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
274275

275276
if (isYAML(Filename))
276277
report_error(Filename, "cannot mix YAML and legacy formats");
277-
ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
278-
MemoryBuffer::getFileOrSTDIN(Filename);
279-
if (std::error_code EC = MB.getError())
280-
report_error(Filename, EC);
281278

282-
StringRef Buf = MB.get()->getBuffer();
279+
std::ifstream FdataFile(Filename, std::ios::in);
280+
std::string FdataLine;
281+
std::getline(FdataFile, FdataLine);
282+
283+
auto checkMode = [&](const std::string &Key, std::optional<bool> &Flag) {
284+
const bool KeyIsSet = FdataLine.rfind(Key, 0) == 0;
285+
286+
if (!Flag.has_value())
287+
Flag = KeyIsSet;
288+
else if (*Flag != KeyIsSet)
289+
report_error(Filename, "cannot mix profile with and without " + Key);
290+
if (KeyIsSet)
291+
// Advance line
292+
std::getline(FdataFile, FdataLine);
293+
};
294+
283295
ProfileTy *Profile;
284296
{
285297
std::lock_guard<std::mutex> Lock(BoltedCollectionMutex);
286298
// Check if the string "boltedcollection" is in the first line
287-
if (Buf.starts_with("boltedcollection\n")) {
288-
if (!BoltedCollection.value_or(true))
289-
report_error(
290-
Filename,
291-
"cannot mix profile collected in BOLT and non-BOLT deployments");
292-
BoltedCollection = true;
293-
Buf = Buf.drop_front(17);
294-
} else {
295-
if (BoltedCollection.value_or(false))
296-
report_error(
297-
Filename,
298-
"cannot mix profile collected in BOLT and non-BOLT deployments");
299-
BoltedCollection = false;
300-
}
299+
checkMode("boltedcollection", BoltedCollection);
301300
// Check if the string "no_lbr" is in the first line
302301
// (or second line if BoltedCollection is true)
303-
size_t CheckNoLBRPos = Buf.find('\n');
304-
if (CheckNoLBRPos != StringRef::npos) {
305-
StringRef FirstLine = Buf.substr(0, CheckNoLBRPos);
306-
if (FirstLine.contains("no_lbr")) {
307-
if (!NoLBRCollection.value_or(true))
308-
report_error(Filename, "cannot mix 'no_lbr' and 'lbr' profiles");
309-
NoLBRCollection = true;
310-
Buf = Buf.drop_front(CheckNoLBRPos + 1);
311-
} else {
312-
if (NoLBRCollection.value_or(false))
313-
report_error(Filename, "cannot mix 'no_lbr' and 'lbr' profiles");
314-
NoLBRCollection = false;
315-
}
316-
}
302+
checkMode("no_lbr", NoLBRCollection);
317303
Profile = &Profiles[tid];
318304
}
319305

320-
SmallVector<StringRef> Lines;
321-
SplitString(Buf, Lines, "\n");
322-
for (StringRef Line : Lines) {
306+
do {
307+
StringRef Line(FdataLine);
323308
size_t Pos = Line.rfind(" ");
324309
if (Pos == StringRef::npos)
325310
report_error(Filename, "Malformed / corrupted profile");
@@ -329,7 +314,7 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
329314
report_error(Filename, "Malformed / corrupted profile counter");
330315
Count += Profile->lookup(Signature);
331316
Profile->insert_or_assign(Signature, Count);
332-
}
317+
} while (std::getline(FdataFile, FdataLine));
333318
};
334319

335320
// The final reduction has non-trivial cost, make sure each thread has at

0 commit comments

Comments
 (0)