| //===--- ProfileList.h - ProfileList filter ---------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // User-provided filters include/exclude profile instrumentation in certain |
| // functions or files. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/Basic/ProfileList.h" |
| #include "clang/Basic/FileManager.h" |
| #include "clang/Basic/SourceManager.h" |
| #include "llvm/Support/SpecialCaseList.h" |
| |
| #include "llvm/Support/raw_ostream.h" |
| |
| using namespace clang; |
| |
| namespace clang { |
| |
| class ProfileSpecialCaseList : public llvm::SpecialCaseList { |
| public: |
| static std::unique_ptr<ProfileSpecialCaseList> |
| create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &VFS, |
| std::string &Error); |
| |
| static std::unique_ptr<ProfileSpecialCaseList> |
| createOrDie(const std::vector<std::string> &Paths, |
| llvm::vfs::FileSystem &VFS); |
| |
| bool isEmpty() const { return Sections.empty(); } |
| |
| bool hasPrefix(StringRef Prefix) const { |
| for (auto &SectionIter : Sections) |
| if (SectionIter.Entries.count(Prefix) > 0) |
| return true; |
| return false; |
| } |
| }; |
| |
| std::unique_ptr<ProfileSpecialCaseList> |
| ProfileSpecialCaseList::create(const std::vector<std::string> &Paths, |
| llvm::vfs::FileSystem &VFS, |
| std::string &Error) { |
| auto PSCL = std::make_unique<ProfileSpecialCaseList>(); |
| if (PSCL->createInternal(Paths, VFS, Error)) |
| return PSCL; |
| return nullptr; |
| } |
| |
| std::unique_ptr<ProfileSpecialCaseList> |
| ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths, |
| llvm::vfs::FileSystem &VFS) { |
| std::string Error; |
| if (auto PSCL = create(Paths, VFS, Error)) |
| return PSCL; |
| llvm::report_fatal_error(llvm::Twine(Error)); |
| } |
| |
| } |
| |
| ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM) |
| : SCL(ProfileSpecialCaseList::createOrDie( |
| Paths, SM.getFileManager().getVirtualFileSystem())), |
| Empty(SCL->isEmpty()), |
| Default(SCL->hasPrefix("fun") || SCL->hasPrefix("src")), SM(SM) {} |
| |
| ProfileList::~ProfileList() = default; |
| |
| static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) { |
| switch (Kind) { |
| case CodeGenOptions::ProfileNone: |
| return ""; |
| case CodeGenOptions::ProfileClangInstr: |
| return "clang"; |
| case CodeGenOptions::ProfileIRInstr: |
| return "llvm"; |
| case CodeGenOptions::ProfileCSIRInstr: |
| return "csllvm"; |
| } |
| llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum"); |
| } |
| |
| llvm::Optional<bool> |
| ProfileList::isFunctionExcluded(StringRef FunctionName, |
| CodeGenOptions::ProfileInstrKind Kind) const { |
| StringRef Section = getSectionName(Kind); |
| if (SCL->inSection(Section, "!fun", FunctionName)) |
| return true; |
| if (SCL->inSection(Section, "fun", FunctionName)) |
| return false; |
| return None; |
| } |
| |
| llvm::Optional<bool> |
| ProfileList::isLocationExcluded(SourceLocation Loc, |
| CodeGenOptions::ProfileInstrKind Kind) const { |
| return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind); |
| } |
| |
| llvm::Optional<bool> |
| ProfileList::isFileExcluded(StringRef FileName, |
| CodeGenOptions::ProfileInstrKind Kind) const { |
| StringRef Section = getSectionName(Kind); |
| if (SCL->inSection(Section, "!src", FileName)) |
| return true; |
| if (SCL->inSection(Section, "src", FileName)) |
| return false; |
| return None; |
| } |