1 //===--- ProfileList.h - ProfileList filter ---------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // User-provided filters include/exclude profile instrumentation in certain
10 // functions or files.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Basic/ProfileList.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/SourceManager.h"
17 #include "llvm/Support/SpecialCaseList.h"
19 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
26 class ProfileSpecialCaseList : public llvm::SpecialCaseList {
28 static std::unique_ptr<ProfileSpecialCaseList>
29 create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &VFS,
32 static std::unique_ptr<ProfileSpecialCaseList>
33 createOrDie(const std::vector<std::string> &Paths,
34 llvm::vfs::FileSystem &VFS);
36 bool isEmpty() const { return Sections.empty(); }
38 bool hasPrefix(StringRef Prefix) const {
39 for (auto &SectionIter : Sections)
40 if (SectionIter.Entries.count(Prefix) > 0)
46 std::unique_ptr<ProfileSpecialCaseList>
47 ProfileSpecialCaseList::create(const std::vector<std::string> &Paths,
48 llvm::vfs::FileSystem &VFS,
50 auto PSCL = std::make_unique<ProfileSpecialCaseList>();
51 if (PSCL->createInternal(Paths, VFS, Error))
56 std::unique_ptr<ProfileSpecialCaseList>
57 ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
58 llvm::vfs::FileSystem &VFS) {
60 if (auto PSCL = create(Paths, VFS, Error))
62 llvm::report_fatal_error(llvm::Twine(Error));
67 ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM)
68 : SCL(ProfileSpecialCaseList::createOrDie(
69 Paths, SM.getFileManager().getVirtualFileSystem())),
70 Empty(SCL->isEmpty()), SM(SM) {}
72 ProfileList::~ProfileList() = default;
74 static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) {
76 case CodeGenOptions::ProfileNone:
78 case CodeGenOptions::ProfileClangInstr:
80 case CodeGenOptions::ProfileIRInstr:
82 case CodeGenOptions::ProfileCSIRInstr:
85 llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum");
88 ProfileList::ExclusionType
89 ProfileList::getDefault(CodeGenOptions::ProfileInstrKind Kind) const {
90 StringRef Section = getSectionName(Kind);
91 // Check for "default:<type>"
92 if (SCL->inSection(Section, "default", "allow"))
94 if (SCL->inSection(Section, "default", "skip"))
96 if (SCL->inSection(Section, "default", "forbid"))
98 // If any cases use "fun" or "src", set the default to FORBID.
99 if (SCL->hasPrefix("fun") || SCL->hasPrefix("src"))
104 std::optional<ProfileList::ExclusionType>
105 ProfileList::inSection(StringRef Section, StringRef Prefix,
106 StringRef Query) const {
107 if (SCL->inSection(Section, Prefix, Query, "allow"))
109 if (SCL->inSection(Section, Prefix, Query, "skip"))
111 if (SCL->inSection(Section, Prefix, Query, "forbid"))
113 if (SCL->inSection(Section, Prefix, Query))
118 std::optional<ProfileList::ExclusionType>
119 ProfileList::isFunctionExcluded(StringRef FunctionName,
120 CodeGenOptions::ProfileInstrKind Kind) const {
121 StringRef Section = getSectionName(Kind);
122 // Check for "function:<regex>=<case>"
123 if (auto V = inSection(Section, "function", FunctionName))
125 if (SCL->inSection(Section, "!fun", FunctionName))
127 if (SCL->inSection(Section, "fun", FunctionName))
132 std::optional<ProfileList::ExclusionType>
133 ProfileList::isLocationExcluded(SourceLocation Loc,
134 CodeGenOptions::ProfileInstrKind Kind) const {
135 return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind);
138 std::optional<ProfileList::ExclusionType>
139 ProfileList::isFileExcluded(StringRef FileName,
140 CodeGenOptions::ProfileInstrKind Kind) const {
141 StringRef Section = getSectionName(Kind);
142 // Check for "source:<regex>=<case>"
143 if (auto V = inSection(Section, "source", FileName))
145 if (SCL->inSection(Section, "!src", FileName))
147 if (SCL->inSection(Section, "src", FileName))