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