brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 8727057 Raw
151 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// User-provided filters include/exclude profile instrumentation in certain10// 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 <optional>20 21using namespace clang;22 23namespace clang {24 25class ProfileSpecialCaseList : public llvm::SpecialCaseList {26public: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 (const auto &It : sections())39      if (It.hasPrefix(Prefix))40        return true;41    return false;42  }43};44 45std::unique_ptr<ProfileSpecialCaseList>46ProfileSpecialCaseList::create(const std::vector<std::string> &Paths,47                               llvm::vfs::FileSystem &VFS, std::string &Error) {48  auto PSCL = std::make_unique<ProfileSpecialCaseList>();49  if (PSCL->createInternal(Paths, VFS, Error))50    return PSCL;51  return nullptr;52}53 54std::unique_ptr<ProfileSpecialCaseList>55ProfileSpecialCaseList::createOrDie(const std::vector<std::string> &Paths,56                                    llvm::vfs::FileSystem &VFS) {57  std::string Error;58  if (auto PSCL = create(Paths, VFS, Error))59    return PSCL;60  llvm::report_fatal_error(llvm::Twine(Error));61}62 63} // namespace clang64 65ProfileList::ProfileList(ArrayRef<std::string> Paths, SourceManager &SM)66    : SCL(ProfileSpecialCaseList::createOrDie(67          Paths, SM.getFileManager().getVirtualFileSystem())),68      Empty(SCL->isEmpty()), SM(SM) {}69 70ProfileList::~ProfileList() = default;71 72static StringRef getSectionName(llvm::driver::ProfileInstrKind Kind) {73  switch (Kind) {74  case llvm::driver::ProfileInstrKind::ProfileNone:75    return "";76  case llvm::driver::ProfileInstrKind::ProfileClangInstr:77    return "clang";78  case llvm::driver::ProfileInstrKind::ProfileIRInstr:79    return "llvm";80  case llvm::driver::ProfileInstrKind::ProfileCSIRInstr:81    return "csllvm";82  case llvm::driver::ProfileInstrKind::ProfileIRSampleColdCov:83    return "sample-coldcov";84  }85  llvm_unreachable("Unhandled llvm::driver::ProfileInstrKind enum");86}87 88ProfileList::ExclusionType89ProfileList::getDefault(llvm::driver::ProfileInstrKind Kind) const {90  StringRef Section = getSectionName(Kind);91  // Check for "default:<type>"92  if (SCL->inSection(Section, "default", "allow"))93    return Allow;94  if (SCL->inSection(Section, "default", "skip"))95    return Skip;96  if (SCL->inSection(Section, "default", "forbid"))97    return Forbid;98  // If any cases use "fun" or "src", set the default to FORBID.99  if (SCL->hasPrefix("fun") || SCL->hasPrefix("src"))100    return Forbid;101  return Allow;102}103 104std::optional<ProfileList::ExclusionType>105ProfileList::inSection(StringRef Section, StringRef Prefix,106                       StringRef Query) const {107  if (SCL->inSection(Section, Prefix, Query, "allow"))108    return Allow;109  if (SCL->inSection(Section, Prefix, Query, "skip"))110    return Skip;111  if (SCL->inSection(Section, Prefix, Query, "forbid"))112    return Forbid;113  if (SCL->inSection(Section, Prefix, Query))114    return Allow;115  return std::nullopt;116}117 118std::optional<ProfileList::ExclusionType>119ProfileList::isFunctionExcluded(StringRef FunctionName,120                                llvm::driver::ProfileInstrKind Kind) const {121  StringRef Section = getSectionName(Kind);122  // Check for "function:<regex>=<case>"123  if (auto V = inSection(Section, "function", FunctionName))124    return V;125  if (SCL->inSection(Section, "!fun", FunctionName))126    return Forbid;127  if (SCL->inSection(Section, "fun", FunctionName))128    return Allow;129  return std::nullopt;130}131 132std::optional<ProfileList::ExclusionType>133ProfileList::isLocationExcluded(SourceLocation Loc,134                                llvm::driver::ProfileInstrKind Kind) const {135  return isFileExcluded(SM.getFilename(SM.getFileLoc(Loc)), Kind);136}137 138std::optional<ProfileList::ExclusionType>139ProfileList::isFileExcluded(StringRef FileName,140                            llvm::driver::ProfileInstrKind Kind) const {141  StringRef Section = getSectionName(Kind);142  // Check for "source:<regex>=<case>"143  if (auto V = inSection(Section, "source", FileName))144    return V;145  if (SCL->inSection(Section, "!src", FileName))146    return Forbid;147  if (SCL->inSection(Section, "src", FileName))148    return Allow;149  return std::nullopt;150}151