summaryrefslogtreecommitdiff
path: root/clang/lib/Basic/ProfileList.cpp
diff options
context:
space:
mode:
authorPetr Hosek <phosek@google.com>2021-01-15 01:14:37 -0800
committerPetr Hosek <phosek@google.com>2021-01-26 17:13:34 -0800
commitbb9eb198298099742c823dce11c5edacc9c48d4e (patch)
tree4d997db42ad6bcd384b6326bef0b2409cdb734b1 /clang/lib/Basic/ProfileList.cpp
parentfc3192026b3156d39c223cc092297c39dd8013f3 (diff)
Support for instrumenting only selected files or functions
This change implements support for applying profile instrumentation only to selected files or functions. The implementation uses the sanitizer special case list format to select which files and functions to instrument, and relies on the new noprofile IR attribute to exclude functions from instrumentation. Differential Revision: https://reviews.llvm.org/D94820
Diffstat (limited to 'clang/lib/Basic/ProfileList.cpp')
-rw-r--r--clang/lib/Basic/ProfileList.cpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/clang/lib/Basic/ProfileList.cpp b/clang/lib/Basic/ProfileList.cpp
new file mode 100644
index 000000000000..56bc37a79301
--- /dev/null
+++ b/clang/lib/Basic/ProfileList.cpp
@@ -0,0 +1,113 @@
+//===--- 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(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::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;
+}