1bb9eb198SPetr Hosek //===--- ProfileList.h - ProfileList filter ---------------------*- C++ -*-===//
2bb9eb198SPetr Hosek //
3bb9eb198SPetr Hosek // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bb9eb198SPetr Hosek // See https://llvm.org/LICENSE.txt for license information.
5bb9eb198SPetr Hosek // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bb9eb198SPetr Hosek //
7bb9eb198SPetr Hosek //===----------------------------------------------------------------------===//
8bb9eb198SPetr Hosek //
9bb9eb198SPetr Hosek // User-provided filters include/exclude profile instrumentation in certain
10bb9eb198SPetr Hosek // functions or files.
11bb9eb198SPetr Hosek //
12bb9eb198SPetr Hosek //===----------------------------------------------------------------------===//
13bb9eb198SPetr Hosek
14bb9eb198SPetr Hosek #include "clang/Basic/ProfileList.h"
15bb9eb198SPetr Hosek #include "clang/Basic/FileManager.h"
16bb9eb198SPetr Hosek #include "clang/Basic/SourceManager.h"
17bb9eb198SPetr Hosek #include "llvm/Support/SpecialCaseList.h"
18bb9eb198SPetr Hosek
19bb9eb198SPetr Hosek #include "llvm/Support/raw_ostream.h"
20bb9eb198SPetr Hosek
21bb9eb198SPetr Hosek using namespace clang;
22bb9eb198SPetr Hosek
23bb9eb198SPetr Hosek namespace clang {
24bb9eb198SPetr Hosek
25bb9eb198SPetr Hosek class ProfileSpecialCaseList : public llvm::SpecialCaseList {
26bb9eb198SPetr Hosek public:
27bb9eb198SPetr Hosek static std::unique_ptr<ProfileSpecialCaseList>
28bb9eb198SPetr Hosek create(const std::vector<std::string> &Paths, llvm::vfs::FileSystem &VFS,
29bb9eb198SPetr Hosek std::string &Error);
30bb9eb198SPetr Hosek
31bb9eb198SPetr Hosek static std::unique_ptr<ProfileSpecialCaseList>
32bb9eb198SPetr Hosek createOrDie(const std::vector<std::string> &Paths,
33bb9eb198SPetr Hosek llvm::vfs::FileSystem &VFS);
34bb9eb198SPetr Hosek
isEmpty() const35bb9eb198SPetr Hosek bool isEmpty() const { return Sections.empty(); }
36bb9eb198SPetr Hosek
hasPrefix(StringRef Prefix) const37bb9eb198SPetr Hosek bool hasPrefix(StringRef Prefix) const {
38bb9eb198SPetr Hosek for (auto &SectionIter : Sections)
39bb9eb198SPetr Hosek if (SectionIter.Entries.count(Prefix) > 0)
40bb9eb198SPetr Hosek return true;
41bb9eb198SPetr Hosek return false;
42bb9eb198SPetr Hosek }
43bb9eb198SPetr Hosek };
44bb9eb198SPetr Hosek
45bb9eb198SPetr Hosek std::unique_ptr<ProfileSpecialCaseList>
create(const std::vector<std::string> & Paths,llvm::vfs::FileSystem & VFS,std::string & Error)46bb9eb198SPetr Hosek ProfileSpecialCaseList::create(const std::vector<std::string> &Paths,
47bb9eb198SPetr Hosek llvm::vfs::FileSystem &VFS,
48bb9eb198SPetr Hosek std::string &Error) {
49bb9eb198SPetr Hosek auto PSCL = std::make_unique<ProfileSpecialCaseList>();
50bb9eb198SPetr Hosek if (PSCL->createInternal(Paths, VFS, Error))
51bb9eb198SPetr Hosek return PSCL;
52bb9eb198SPetr Hosek return nullptr;
53bb9eb198SPetr Hosek }
54bb9eb198SPetr Hosek
55bb9eb198SPetr Hosek std::unique_ptr<ProfileSpecialCaseList>
createOrDie(const std::vector<std::string> & Paths,llvm::vfs::FileSystem & VFS)56bb9eb198SPetr Hosek ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,
57bb9eb198SPetr Hosek llvm::vfs::FileSystem &VFS) {
58bb9eb198SPetr Hosek std::string Error;
59bb9eb198SPetr Hosek if (auto PSCL = create(Paths, VFS, Error))
60bb9eb198SPetr Hosek return PSCL;
61*b9b90bb5SSimon Pilgrim llvm::report_fatal_error(llvm::Twine(Error));
62bb9eb198SPetr Hosek }
63bb9eb198SPetr Hosek
64bb9eb198SPetr Hosek }
65bb9eb198SPetr Hosek
ProfileList(ArrayRef<std::string> Paths,SourceManager & SM)66bb9eb198SPetr Hosek ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM)
67bb9eb198SPetr Hosek : SCL(ProfileSpecialCaseList::createOrDie(
68bb9eb198SPetr Hosek Paths, SM.getFileManager().getVirtualFileSystem())),
69bb9eb198SPetr Hosek Empty(SCL->isEmpty()),
70bb9eb198SPetr Hosek Default(SCL->hasPrefix("fun") || SCL->hasPrefix("src")), SM(SM) {}
71bb9eb198SPetr Hosek
72bb9eb198SPetr Hosek ProfileList::~ProfileList() = default;
73bb9eb198SPetr Hosek
getSectionName(CodeGenOptions::ProfileInstrKind Kind)74bb9eb198SPetr Hosek static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) {
75bb9eb198SPetr Hosek switch (Kind) {
76bb9eb198SPetr Hosek case CodeGenOptions::ProfileNone:
77bb9eb198SPetr Hosek return "";
78bb9eb198SPetr Hosek case CodeGenOptions::ProfileClangInstr:
79bb9eb198SPetr Hosek return "clang";
80bb9eb198SPetr Hosek case CodeGenOptions::ProfileIRInstr:
81bb9eb198SPetr Hosek return "llvm";
82bb9eb198SPetr Hosek case CodeGenOptions::ProfileCSIRInstr:
83bb9eb198SPetr Hosek return "csllvm";
84bb9eb198SPetr Hosek }
85da83b869SSimon Pilgrim llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum");
86bb9eb198SPetr Hosek }
87bb9eb198SPetr Hosek
88bb9eb198SPetr Hosek llvm::Optional<bool>
isFunctionExcluded(StringRef FunctionName,CodeGenOptions::ProfileInstrKind Kind) const89bb9eb198SPetr Hosek ProfileList::isFunctionExcluded(StringRef FunctionName,
90bb9eb198SPetr Hosek CodeGenOptions::ProfileInstrKind Kind) const {
91bb9eb198SPetr Hosek StringRef Section = getSectionName(Kind);
92bb9eb198SPetr Hosek if (SCL->inSection(Section, "!fun", FunctionName))
93bb9eb198SPetr Hosek return true;
94bb9eb198SPetr Hosek if (SCL->inSection(Section, "fun", FunctionName))
95bb9eb198SPetr Hosek return false;
96bb9eb198SPetr Hosek return None;
97bb9eb198SPetr Hosek }
98bb9eb198SPetr Hosek
99bb9eb198SPetr Hosek llvm::Optional<bool>
isLocationExcluded(SourceLocation Loc,CodeGenOptions::ProfileInstrKind Kind) const100bb9eb198SPetr Hosek ProfileList::isLocationExcluded(SourceLocation Loc,
101bb9eb198SPetr Hosek CodeGenOptions::ProfileInstrKind Kind) const {
102bb9eb198SPetr Hosek return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind);
103bb9eb198SPetr Hosek }
104bb9eb198SPetr Hosek
105bb9eb198SPetr Hosek llvm::Optional<bool>
isFileExcluded(StringRef FileName,CodeGenOptions::ProfileInstrKind Kind) const106bb9eb198SPetr Hosek ProfileList::isFileExcluded(StringRef FileName,
107bb9eb198SPetr Hosek CodeGenOptions::ProfileInstrKind Kind) const {
108bb9eb198SPetr Hosek StringRef Section = getSectionName(Kind);
109bb9eb198SPetr Hosek if (SCL->inSection(Section, "!src", FileName))
110bb9eb198SPetr Hosek return true;
111bb9eb198SPetr Hosek if (SCL->inSection(Section, "src", FileName))
112bb9eb198SPetr Hosek return false;
113bb9eb198SPetr Hosek return None;
114bb9eb198SPetr Hosek }
115