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