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