diff options
-rw-r--r-- | include/llvm/ProfileData/InstrProf.h | 15 | ||||
-rw-r--r-- | include/llvm/ProfileData/InstrProfReader.h | 6 | ||||
-rw-r--r-- | include/llvm/ProfileData/InstrProfWriter.h | 2 | ||||
-rw-r--r-- | lib/ProfileData/Coverage/CoverageMappingReader.cpp | 2 | ||||
-rw-r--r-- | lib/ProfileData/InstrProf.cpp | 12 | ||||
-rw-r--r-- | lib/ProfileData/InstrProfReader.cpp | 10 | ||||
-rw-r--r-- | lib/ProfileData/InstrProfWriter.cpp | 6 | ||||
-rw-r--r-- | lib/Transforms/Instrumentation/IndirectCallPromotion.cpp | 7 | ||||
-rw-r--r-- | tools/llvm-profdata/llvm-profdata.cpp | 8 | ||||
-rw-r--r-- | unittests/ProfileData/InstrProfTest.cpp | 16 |
10 files changed, 57 insertions, 27 deletions
diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index 0dbb2cf9f269..23b7366f5cec 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -450,11 +450,11 @@ public: /// decls from module \c M. This interface is used by transformation /// passes such as indirect function call promotion. Variable \c InLTO /// indicates if this is called from LTO optimization passes. - void create(Module &M, bool InLTO = false); + Error create(Module &M, bool InLTO = false); /// Create InstrProfSymtab from a set of names iteratable from /// \p IterRange. This interface is used by IndexedProfReader. - template <typename NameIterRange> void create(const NameIterRange &IterRange); + template <typename NameIterRange> Error create(const NameIterRange &IterRange); // If the symtab is created by a series of calls to \c addFuncName, \c // finalizeSymtab needs to be called before looking up function names. @@ -464,11 +464,14 @@ public: /// Update the symtab by adding \p FuncName to the table. This interface /// is used by the raw and text profile readers. - void addFuncName(StringRef FuncName) { + Error addFuncName(StringRef FuncName) { + if (FuncName.empty()) + return make_error<InstrProfError>(instrprof_error::malformed); auto Ins = NameTab.insert(FuncName); if (Ins.second) MD5NameMap.push_back(std::make_pair( IndexedInstrProf::ComputeHash(FuncName), Ins.first->getKey())); + return Error::success(); } /// Map a function address to its name's MD5 hash. This interface @@ -511,11 +514,13 @@ Error InstrProfSymtab::create(StringRef NameStrings) { } template <typename NameIterRange> -void InstrProfSymtab::create(const NameIterRange &IterRange) { +Error InstrProfSymtab::create(const NameIterRange &IterRange) { for (auto Name : IterRange) - addFuncName(Name); + if (Error E = addFuncName(Name)) + return E; finalizeSymtab(); + return Error::success(); } void InstrProfSymtab::finalizeSymtab() { diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h index 1d85a7149afc..19d478e94cf2 100644 --- a/include/llvm/ProfileData/InstrProfReader.h +++ b/include/llvm/ProfileData/InstrProfReader.h @@ -343,7 +343,7 @@ struct InstrProfReaderIndexBase { virtual void setValueProfDataEndianness(support::endianness Endianness) = 0; virtual uint64_t getVersion() const = 0; virtual bool isIRLevelProfile() const = 0; - virtual void populateSymtab(InstrProfSymtab &) = 0; + virtual Error populateSymtab(InstrProfSymtab &) = 0; }; typedef OnDiskIterableChainedHashTable<InstrProfLookupTrait> @@ -383,8 +383,8 @@ public: return (FormatVersion & VARIANT_MASK_IR_PROF) != 0; } - void populateSymtab(InstrProfSymtab &Symtab) override { - Symtab.create(HashTable->keys()); + Error populateSymtab(InstrProfSymtab &Symtab) override { + return Symtab.create(HashTable->keys()); } }; diff --git a/include/llvm/ProfileData/InstrProfWriter.h b/include/llvm/ProfileData/InstrProfWriter.h index 10742c0228eb..4d818bad51aa 100644 --- a/include/llvm/ProfileData/InstrProfWriter.h +++ b/include/llvm/ProfileData/InstrProfWriter.h @@ -58,7 +58,7 @@ public: void write(raw_fd_ostream &OS); /// Write the profile in text format to \c OS - void writeText(raw_fd_ostream &OS); + Error writeText(raw_fd_ostream &OS); /// Write \c Record in text format to \c OS static void writeRecordInText(const InstrProfRecord &Record, diff --git a/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/lib/ProfileData/Coverage/CoverageMappingReader.cpp index a34f359cd542..fa42fce4751c 100644 --- a/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -419,6 +419,8 @@ class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader { StringRef FuncName; if (Error Err = CFR->template getFuncName<Endian>(ProfileNames, FuncName)) return Err; + if (FuncName.empty()) + return make_error<InstrProfError>(instrprof_error::malformed); Records.emplace_back(Version, FuncName, FuncHash, Mapping, FilenamesBegin, Filenames.size() - FilenamesBegin); return Error::success(); diff --git a/lib/ProfileData/InstrProf.cpp b/lib/ProfileData/InstrProf.cpp index c9b82c303e33..005061c4f068 100644 --- a/lib/ProfileData/InstrProf.cpp +++ b/lib/ProfileData/InstrProf.cpp @@ -330,14 +330,15 @@ GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName) { return createPGOFuncNameVar(*F.getParent(), F.getLinkage(), PGOFuncName); } -void InstrProfSymtab::create(Module &M, bool InLTO) { +Error InstrProfSymtab::create(Module &M, bool InLTO) { for (Function &F : M) { // Function may not have a name: like using asm("") to overwrite the name. // Ignore in this case. if (!F.hasName()) continue; const std::string &PGOFuncName = getPGOFuncName(F, InLTO); - addFuncName(PGOFuncName); + if (Error E = addFuncName(PGOFuncName)) + return E; MD5FuncMap.emplace_back(Function::getGUID(PGOFuncName), &F); // In ThinLTO, local function may have been promoted to global and have // suffix added to the function name. We need to add the stripped function @@ -346,13 +347,15 @@ void InstrProfSymtab::create(Module &M, bool InLTO) { auto pos = PGOFuncName.find('.'); if (pos != std::string::npos) { const std::string &OtherFuncName = PGOFuncName.substr(0, pos); - addFuncName(OtherFuncName); + if (Error E = addFuncName(OtherFuncName)) + return E; MD5FuncMap.emplace_back(Function::getGUID(OtherFuncName), &F); } } } finalizeSymtab(); + return Error::success(); } Error collectPGOFuncNameStrings(ArrayRef<std::string> NameStrs, @@ -447,7 +450,8 @@ Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) { SmallVector<StringRef, 0> Names; NameStrings.split(Names, getInstrProfNameSeparator()); for (StringRef &Name : Names) - Symtab.addFuncName(Name); + if (Error E = Symtab.addFuncName(Name)) + return E; while (P < EndP && *P == 0) P++; diff --git a/lib/ProfileData/InstrProfReader.cpp b/lib/ProfileData/InstrProfReader.cpp index d9f599f400da..b9b3e1612768 100644 --- a/lib/ProfileData/InstrProfReader.cpp +++ b/lib/ProfileData/InstrProfReader.cpp @@ -200,7 +200,8 @@ TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) { std::pair<StringRef, StringRef> VD = Line->rsplit(':'); uint64_t TakenCount, Value; if (ValueKind == IPVK_IndirectCallTarget) { - Symtab->addFuncName(VD.first); + if (Error E = Symtab->addFuncName(VD.first)) + return E; Value = IndexedInstrProf::ComputeHash(VD.first); } else { READ_NUM(VD.first, Value); @@ -232,7 +233,8 @@ Error TextInstrProfReader::readNextRecord(InstrProfRecord &Record) { // Read the function name. Record.Name = *Line++; - Symtab->addFuncName(Record.Name); + if (Error E = Symtab->addFuncName(Record.Name)) + return E; // Read the function hash. if (Line.is_at_end()) @@ -694,7 +696,9 @@ InstrProfSymtab &IndexedInstrProfReader::getSymtab() { return *Symtab.get(); std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>(); - Index->populateSymtab(*NewSymtab.get()); + if (Error E = Index->populateSymtab(*NewSymtab.get())) { + consumeError(error(InstrProfError::take(std::move(E)))); + } Symtab = std::move(NewSymtab); return *Symtab.get(); diff --git a/lib/ProfileData/InstrProfWriter.cpp b/lib/ProfileData/InstrProfWriter.cpp index b3402a6ea956..1a92e8a8a382 100644 --- a/lib/ProfileData/InstrProfWriter.cpp +++ b/lib/ProfileData/InstrProfWriter.cpp @@ -363,17 +363,19 @@ void InstrProfWriter::writeRecordInText(const InstrProfRecord &Func, OS << "\n"; } -void InstrProfWriter::writeText(raw_fd_ostream &OS) { +Error InstrProfWriter::writeText(raw_fd_ostream &OS) { if (ProfileKind == PF_IRLevel) OS << "# IR level Instrumentation Flag\n:ir\n"; InstrProfSymtab Symtab; for (const auto &I : FunctionData) if (shouldEncodeData(I.getValue())) - Symtab.addFuncName(I.getKey()); + if (Error E = Symtab.addFuncName(I.getKey())) + return E; Symtab.finalizeSymtab(); for (const auto &I : FunctionData) if (shouldEncodeData(I.getValue())) for (const auto &Func : I.getValue()) writeRecordInText(Func.second, Symtab, OS); + return Error::success(); } diff --git a/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp b/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp index 0d308810009d..4089d81ea3e1 100644 --- a/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp +++ b/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp @@ -642,7 +642,12 @@ static bool promoteIndirectCalls(Module &M, bool InLTO, bool SamplePGO) { if (DisableICP) return false; InstrProfSymtab Symtab; - Symtab.create(M, InLTO); + if (Error E = Symtab.create(M, InLTO)) { + std::string SymtabFailure = toString(std::move(E)); + DEBUG(dbgs() << "Failed to create symtab: " << SymtabFailure << "\n"); + (void)SymtabFailure; + return false; + } bool Changed = false; for (auto &F : M) { if (F.isDeclaration()) diff --git a/tools/llvm-profdata/llvm-profdata.cpp b/tools/llvm-profdata/llvm-profdata.cpp index 4867acf70983..e9bc2de82bdf 100644 --- a/tools/llvm-profdata/llvm-profdata.cpp +++ b/tools/llvm-profdata/llvm-profdata.cpp @@ -246,10 +246,12 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs, exitWithError(std::move(WC->Err), WC->ErrWhence); InstrProfWriter &Writer = Contexts[0]->Writer; - if (OutputFormat == PF_Text) - Writer.writeText(Output); - else + if (OutputFormat == PF_Text) { + if (Error E = Writer.writeText(Output)) + exitWithError(std::move(E)); + } else { Writer.write(Output); + } } static sampleprof::SampleProfileFormat FormatMap[] = { diff --git a/unittests/ProfileData/InstrProfTest.cpp b/unittests/ProfileData/InstrProfTest.cpp index b15029a08137..13436cc0d5b2 100644 --- a/unittests/ProfileData/InstrProfTest.cpp +++ b/unittests/ProfileData/InstrProfTest.cpp @@ -859,7 +859,7 @@ TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) { FuncNames.push_back("bar2"); FuncNames.push_back("bar3"); InstrProfSymtab Symtab; - Symtab.create(FuncNames); + NoError(Symtab.create(FuncNames)); StringRef R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func1")); ASSERT_EQ(StringRef("func1"), R); R = Symtab.getFuncName(IndexedInstrProf::ComputeHash("func2")); @@ -880,9 +880,9 @@ TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) { ASSERT_EQ(StringRef(), R); // Now incrementally update the symtab - Symtab.addFuncName("blah_1"); - Symtab.addFuncName("blah_2"); - Symtab.addFuncName("blah_3"); + NoError(Symtab.addFuncName("blah_1")); + NoError(Symtab.addFuncName("blah_2")); + NoError(Symtab.addFuncName("blah_3")); // Finalize it Symtab.finalizeSymtab(); @@ -907,6 +907,12 @@ TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_test) { ASSERT_EQ(StringRef("bar3"), R); } +// Test that we get an error when creating a bogus symtab. +TEST_P(MaybeSparseInstrProfTest, instr_prof_bogus_symtab_empty_func_name) { + InstrProfSymtab Symtab; + ErrorEquals(instrprof_error::malformed, Symtab.addFuncName("")); +} + // Testing symtab creator interface used by value profile transformer. TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) { LLVMContext Ctx; @@ -927,7 +933,7 @@ TEST_P(MaybeSparseInstrProfTest, instr_prof_symtab_module_test) { Function::Create(FTy, Function::WeakODRLinkage, "Wbar", M.get()); InstrProfSymtab ProfSymtab; - ProfSymtab.create(*M); + NoError(ProfSymtab.create(*M)); StringRef Funcs[] = {"Gfoo", "Gblah", "Gbar", "Ifoo", "Iblah", "Ibar", "Pfoo", "Pblah", "Pbar", "Wfoo", "Wblah", "Wbar"}; |