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