Home | History | Annotate | Line # | Download | only in Basic
      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