diff --git a/bolt/test/merge-fdata-mixed-bat-no-lbr.test b/bolt/test/merge-fdata-mixed-bat-no-lbr.test index b59773d2d5054..eeb3a0e23b0cc 100644 --- a/bolt/test/merge-fdata-mixed-bat-no-lbr.test +++ b/bolt/test/merge-fdata-mixed-bat-no-lbr.test @@ -5,7 +5,7 @@ # RUN: split-file %s %t # RUN: not merge-fdata %t/a.fdata %t/b.fdata 2>&1 | FileCheck %s -# CHECK: cannot mix profile collected in BOLT and non-BOLT deployments +# CHECK: cannot mix profile with and without boltedcollection #--- a.fdata boltedcollection diff --git a/bolt/test/merge-fdata-mixed-mode.test b/bolt/test/merge-fdata-mixed-mode.test index 3e1a3bfcb9454..f897fec5d9db4 100644 --- a/bolt/test/merge-fdata-mixed-mode.test +++ b/bolt/test/merge-fdata-mixed-mode.test @@ -6,7 +6,7 @@ # RUN: split-file %s %t # RUN: not merge-fdata %t/a.fdata %t/b.fdata 2>&1 | FileCheck %s -# CHECK: cannot mix 'no_lbr' and 'lbr' profiles. +# CHECK: cannot mix profile with and without no_lbr #--- a.fdata no_lbr diff --git a/bolt/tools/merge-fdata/merge-fdata.cpp b/bolt/tools/merge-fdata/merge-fdata.cpp index 39f58a7e8800e..318ef0950e560 100644 --- a/bolt/tools/merge-fdata/merge-fdata.cpp +++ b/bolt/tools/merge-fdata/merge-fdata.cpp @@ -22,6 +22,7 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/ThreadPool.h" #include +#include #include #include @@ -274,52 +275,36 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { if (isYAML(Filename)) report_error(Filename, "cannot mix YAML and legacy formats"); - ErrorOr> MB = - MemoryBuffer::getFileOrSTDIN(Filename); - if (std::error_code EC = MB.getError()) - report_error(Filename, EC); - StringRef Buf = MB.get()->getBuffer(); + std::ifstream FdataFile(Filename, std::ios::in); + std::string FdataLine; + std::getline(FdataFile, FdataLine); + + auto checkMode = [&](const std::string &Key, std::optional &Flag) { + const bool KeyIsSet = FdataLine.rfind(Key, 0) == 0; + + if (!Flag.has_value()) + Flag = KeyIsSet; + else if (*Flag != KeyIsSet) + report_error(Filename, "cannot mix profile with and without " + Key); + if (KeyIsSet) + // Advance line + std::getline(FdataFile, FdataLine); + }; + ProfileTy *Profile; { std::lock_guard Lock(BoltedCollectionMutex); // Check if the string "boltedcollection" is in the first line - if (Buf.starts_with("boltedcollection\n")) { - if (!BoltedCollection.value_or(true)) - report_error( - Filename, - "cannot mix profile collected in BOLT and non-BOLT deployments"); - BoltedCollection = true; - Buf = Buf.drop_front(17); - } else { - if (BoltedCollection.value_or(false)) - report_error( - Filename, - "cannot mix profile collected in BOLT and non-BOLT deployments"); - BoltedCollection = false; - } + checkMode("boltedcollection", BoltedCollection); // Check if the string "no_lbr" is in the first line // (or second line if BoltedCollection is true) - size_t CheckNoLBRPos = Buf.find('\n'); - if (CheckNoLBRPos != StringRef::npos) { - StringRef FirstLine = Buf.substr(0, CheckNoLBRPos); - if (FirstLine.contains("no_lbr")) { - if (!NoLBRCollection.value_or(true)) - report_error(Filename, "cannot mix 'no_lbr' and 'lbr' profiles"); - NoLBRCollection = true; - Buf = Buf.drop_front(CheckNoLBRPos + 1); - } else { - if (NoLBRCollection.value_or(false)) - report_error(Filename, "cannot mix 'no_lbr' and 'lbr' profiles"); - NoLBRCollection = false; - } - } + checkMode("no_lbr", NoLBRCollection); Profile = &Profiles[tid]; } - SmallVector Lines; - SplitString(Buf, Lines, "\n"); - for (StringRef Line : Lines) { + do { + StringRef Line(FdataLine); size_t Pos = Line.rfind(" "); if (Pos == StringRef::npos) report_error(Filename, "Malformed / corrupted profile"); @@ -329,7 +314,7 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { report_error(Filename, "Malformed / corrupted profile counter"); Count += Profile->lookup(Signature); Profile->insert_or_assign(Signature, Count); - } + } while (std::getline(FdataFile, FdataLine)); }; // The final reduction has non-trivial cost, make sure each thread has at