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 35 bool isEmpty() const { return Sections.empty(); } 36 37 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> 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> 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 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 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> 89 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> 100 ProfileList::isLocationExcluded(SourceLocation Loc, 101 CodeGenOptions::ProfileInstrKind Kind) const { 102 return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind); 103 } 104 105 llvm::Optional<bool> 106 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