//===--- 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(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;
}