CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
263 lines
13 KiB
C++
263 lines
13 KiB
C++
//===- RemarkUtilHelpers.h ------------------------------------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Helpers for remark utilites
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Remarks/Remark.h"
|
|
#include "llvm/Remarks/RemarkFormat.h"
|
|
#include "llvm/Remarks/RemarkParser.h"
|
|
#include "llvm/Remarks/RemarkSerializer.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/Error.h"
|
|
#include "llvm/Support/FileSystem.h"
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
#include "llvm/Support/Regex.h"
|
|
#include "llvm/Support/StringSaver.h"
|
|
#include "llvm/Support/ToolOutputFile.h"
|
|
|
|
// Keep input + output help + names consistent across the various modes via a
|
|
// hideous macro.
|
|
#define OUTPUT_COMMAND_LINE_OPTIONS(SUBOPT) \
|
|
static cl::opt<std::string> OutputFileName( \
|
|
"o", cl::init("-"), cl::desc("Output"), cl::value_desc("filename"), \
|
|
cl::sub(SUBOPT));
|
|
#define INPUT_OUTPUT_COMMAND_LINE_OPTIONS(SUBOPT) \
|
|
static cl::opt<std::string> InputFileName(cl::Positional, cl::init("-"), \
|
|
cl::desc("<input file>"), \
|
|
cl::sub(SUBOPT)); \
|
|
OUTPUT_COMMAND_LINE_OPTIONS(SUBOPT)
|
|
|
|
// Keep Input format and names consistent accross the modes via a macro.
|
|
#define INPUT_FORMAT_COMMAND_LINE_OPTIONS(SUBOPT) \
|
|
static cl::opt<Format> InputFormat( \
|
|
"parser", cl::init(Format::Auto), \
|
|
cl::desc("Input remark format to parse"), \
|
|
cl::values( \
|
|
clEnumValN(Format::Auto, "auto", "Automatic detection (default)"), \
|
|
clEnumValN(Format::YAML, "yaml", "YAML"), \
|
|
clEnumValN(Format::Bitstream, "bitstream", "Bitstream")), \
|
|
cl::sub(SUBOPT));
|
|
|
|
#define OUTPUT_FORMAT_COMMAND_LINE_OPTIONS(SUBOPT) \
|
|
static cl::opt<Format> OutputFormat( \
|
|
"serializer", cl::init(Format::Auto), \
|
|
cl::desc("Output remark format to serialize"), \
|
|
cl::values(clEnumValN(Format::Auto, "auto", \
|
|
"Automatic detection based on output file " \
|
|
"extension or parser format (default)"), \
|
|
clEnumValN(Format::YAML, "yaml", "YAML"), \
|
|
clEnumValN(Format::Bitstream, "bitstream", "Bitstream")), \
|
|
cl::sub(SUBOPT));
|
|
|
|
#define DEBUG_LOC_INFO_COMMAND_LINE_OPTIONS(SUBOPT) \
|
|
static cl::opt<bool> UseDebugLoc( \
|
|
"use-debug-loc", \
|
|
cl::desc( \
|
|
"Add debug loc information when generating tables for " \
|
|
"functions. The loc is represented as (path:line number:column " \
|
|
"number)"), \
|
|
cl::init(false), cl::sub(SUBOPT));
|
|
|
|
#define REMARK_FILTER_COMMAND_LINE_OPTIONS(SUBOPT) \
|
|
static cl::opt<std::string> FunctionOpt( \
|
|
"function", cl::sub(SUBOPT), cl::ValueOptional, \
|
|
cl::desc("Optional function name to filter collection by.")); \
|
|
static cl::opt<std::string> FunctionOptRE( \
|
|
"rfunction", cl::sub(SUBOPT), cl::ValueOptional, \
|
|
cl::desc("Optional function name to filter collection by " \
|
|
"(accepts regular expressions).")); \
|
|
static cl::opt<std::string> RemarkNameOpt( \
|
|
"remark-name", \
|
|
cl::desc("Optional remark name to filter collection by."), \
|
|
cl::ValueOptional, cl::sub(SUBOPT)); \
|
|
static cl::opt<std::string> RemarkNameOptRE( \
|
|
"rremark-name", \
|
|
cl::desc("Optional remark name to filter collection by " \
|
|
"(accepts regular expressions)."), \
|
|
cl::ValueOptional, cl::sub(SUBOPT)); \
|
|
static cl::opt<std::string> PassNameOpt( \
|
|
"pass-name", cl::ValueOptional, \
|
|
cl::desc("Optional remark pass name to filter collection by."), \
|
|
cl::sub(SUBOPT)); \
|
|
static cl::opt<std::string> PassNameOptRE( \
|
|
"rpass-name", cl::ValueOptional, \
|
|
cl::desc("Optional remark pass name to filter collection " \
|
|
"by (accepts regular expressions)."), \
|
|
cl::sub(SUBOPT)); \
|
|
static cl::opt<Type> RemarkTypeOpt( \
|
|
"remark-type", \
|
|
cl::desc("Optional remark type to filter collection by."), \
|
|
cl::values(clEnumValN(Type::Unknown, "unknown", "UNKOWN"), \
|
|
clEnumValN(Type::Passed, "passed", "PASSED"), \
|
|
clEnumValN(Type::Missed, "missed", "MISSED"), \
|
|
clEnumValN(Type::Analysis, "analysis", "ANALYSIS"), \
|
|
clEnumValN(Type::AnalysisFPCommute, "analysis-fp-commute", \
|
|
"ANALYSIS_FP_COMMUTE"), \
|
|
clEnumValN(Type::AnalysisAliasing, "analysis-aliasing", \
|
|
"ANALYSIS_ALIASING"), \
|
|
clEnumValN(Type::Failure, "failure", "FAILURE")), \
|
|
cl::sub(SUBOPT)); \
|
|
static cl::opt<std::string> RemarkFilterArgByOpt( \
|
|
"filter-arg-by", \
|
|
cl::desc("Optional remark arg to filter collection by."), \
|
|
cl::ValueOptional, cl::sub(SUBOPT)); \
|
|
static cl::opt<std::string> RemarkArgFilterOptRE( \
|
|
"rfilter-arg-by", \
|
|
cl::desc("Optional remark arg to filter collection by " \
|
|
"(accepts regular expressions)."), \
|
|
cl::sub(SUBOPT), cl::ValueOptional);
|
|
|
|
#define REMARK_FILTER_SETUP_FUNC() \
|
|
static Expected<Filters> getRemarkFilters() { \
|
|
auto MaybeFunctionFilter = \
|
|
FilterMatcher::createExactOrRE(FunctionOpt, FunctionOptRE); \
|
|
if (!MaybeFunctionFilter) \
|
|
return MaybeFunctionFilter.takeError(); \
|
|
\
|
|
auto MaybeRemarkNameFilter = \
|
|
FilterMatcher::createExactOrRE(RemarkNameOpt, RemarkNameOptRE); \
|
|
if (!MaybeRemarkNameFilter) \
|
|
return MaybeRemarkNameFilter.takeError(); \
|
|
\
|
|
auto MaybePassNameFilter = \
|
|
FilterMatcher::createExactOrRE(PassNameOpt, PassNameOptRE); \
|
|
if (!MaybePassNameFilter) \
|
|
return MaybePassNameFilter.takeError(); \
|
|
\
|
|
auto MaybeRemarkArgFilter = FilterMatcher::createExactOrRE( \
|
|
RemarkFilterArgByOpt, RemarkArgFilterOptRE); \
|
|
if (!MaybeRemarkArgFilter) \
|
|
return MaybeRemarkArgFilter.takeError(); \
|
|
\
|
|
std::optional<Type> TypeFilter; \
|
|
if (RemarkTypeOpt.getNumOccurrences()) \
|
|
TypeFilter = RemarkTypeOpt.getValue(); \
|
|
\
|
|
return Filters{std::move(*MaybeFunctionFilter), \
|
|
std::move(*MaybeRemarkNameFilter), \
|
|
std::move(*MaybePassNameFilter), \
|
|
std::move(*MaybeRemarkArgFilter), TypeFilter}; \
|
|
}
|
|
|
|
namespace llvm {
|
|
namespace remarks {
|
|
Expected<std::unique_ptr<MemoryBuffer>>
|
|
getInputMemoryBuffer(StringRef InputFileName);
|
|
Expected<std::unique_ptr<ToolOutputFile>>
|
|
getOutputFileWithFlags(StringRef OutputFileName, sys::fs::OpenFlags Flags);
|
|
Expected<std::unique_ptr<ToolOutputFile>>
|
|
getOutputFileForRemarks(StringRef OutputFileName, Format OutputFormat);
|
|
|
|
/// Choose the serializer format. If \p SelectedFormat is Format::Auto, try to
|
|
/// detect the format based on the extension of \p OutputFileName or fall back
|
|
/// to \p DefaultFormat.
|
|
Format getSerializerFormat(StringRef OutputFileName, Format SelectedFormat,
|
|
Format DefaultFormat);
|
|
|
|
/// Filter object which can be either a string or a regex to match with the
|
|
/// remark properties.
|
|
class FilterMatcher {
|
|
Regex FilterRE;
|
|
std::string FilterStr;
|
|
bool IsRegex;
|
|
|
|
FilterMatcher(StringRef Filter, bool IsRegex)
|
|
: FilterRE(Filter), FilterStr(Filter), IsRegex(IsRegex) {}
|
|
|
|
static Expected<FilterMatcher> createRE(StringRef Arg, StringRef Value);
|
|
|
|
public:
|
|
static FilterMatcher createExact(StringRef Filter) { return {Filter, false}; }
|
|
|
|
static Expected<FilterMatcher>
|
|
createRE(const llvm::cl::opt<std::string> &Arg);
|
|
|
|
static Expected<FilterMatcher> createRE(StringRef Filter,
|
|
const cl::list<std::string> &Arg);
|
|
|
|
static Expected<std::optional<FilterMatcher>>
|
|
createExactOrRE(const llvm::cl::opt<std::string> &ExactArg,
|
|
const llvm::cl::opt<std::string> &REArg);
|
|
|
|
static FilterMatcher createAny() { return {".*", true}; }
|
|
|
|
bool match(StringRef StringToMatch) const {
|
|
if (IsRegex)
|
|
return FilterRE.match(StringToMatch);
|
|
return FilterStr == StringToMatch.trim().str();
|
|
}
|
|
};
|
|
|
|
/// Filter out remarks based on remark properties (function, remark name, pass
|
|
/// name, argument values and type).
|
|
struct Filters {
|
|
std::optional<FilterMatcher> FunctionFilter;
|
|
std::optional<FilterMatcher> RemarkNameFilter;
|
|
std::optional<FilterMatcher> PassNameFilter;
|
|
std::optional<FilterMatcher> ArgFilter;
|
|
std::optional<Type> RemarkTypeFilter;
|
|
|
|
/// Returns true if \p Remark satisfies all the provided filters.
|
|
bool filterRemark(const Remark &Remark);
|
|
};
|
|
|
|
/// Helper to construct Remarks using an API similar to DiagnosticInfo.
|
|
/// Once this is more fully featured, consider implementing DiagnosticInfo using
|
|
/// RemarkBuilder.
|
|
class RemarkBuilder {
|
|
BumpPtrAllocator Alloc;
|
|
UniqueStringSaver Strs;
|
|
|
|
public:
|
|
Remark R;
|
|
struct Argument {
|
|
std::string Key;
|
|
std::string Val;
|
|
std::optional<RemarkLocation> Loc;
|
|
Argument(StringRef Key, StringRef Val,
|
|
std::optional<RemarkLocation> Loc = std::nullopt)
|
|
: Key(Key), Val(Val), Loc(Loc) {}
|
|
Argument(StringRef Key, int Val,
|
|
std::optional<RemarkLocation> Loc = std::nullopt)
|
|
: Key(Key), Val(itostr(Val)), Loc(Loc) {}
|
|
};
|
|
|
|
RemarkBuilder(Type RemarkType, StringRef PassName, StringRef RemarkName,
|
|
StringRef FunctionName)
|
|
: Strs(Alloc) {
|
|
R.RemarkType = RemarkType;
|
|
R.PassName = Strs.save(PassName);
|
|
R.RemarkName = Strs.save(RemarkName);
|
|
R.FunctionName = Strs.save(FunctionName);
|
|
}
|
|
|
|
RemarkBuilder &operator<<(Argument &&Arg) {
|
|
auto &RArg = R.Args.emplace_back(Strs.save(Arg.Key), Strs.save(Arg.Val));
|
|
RArg.Loc = Arg.Loc;
|
|
return *this;
|
|
}
|
|
|
|
RemarkBuilder &operator<<(const char *Str) {
|
|
R.Args.emplace_back("String", Str);
|
|
return *this;
|
|
}
|
|
|
|
RemarkBuilder &operator<<(StringRef Str) {
|
|
R.Args.emplace_back("String", Strs.save(Str));
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
using NV = RemarkBuilder::Argument;
|
|
|
|
} // namespace remarks
|
|
} // namespace llvm
|