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