Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/test/tools/llvm-remarkutil/instruction-count.test
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ RUN: llvm-remarkutil instruction-count --parser=yaml %p/Inputs/instruction-count
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/instruction-count.yaml | llvm-remarkutil instruction-count --parser=bitstream | FileCheck %s
RUN: llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function --remark-name="InstructionCount" %p/Inputs/instruction-count.yaml | FileCheck %s --check-prefix=COUNT-CHECK
RUN: llvm-remarkutil yaml2bitstream %p/Inputs/instruction-count.yaml | llvm-remarkutil count --parser=bitstream --count-by=arg --group-by=function --remark-name="InstructionCount" | FileCheck %s --check-prefix=COUNT-CHECK
RUN: not llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function --rremark-name=* %p/Inputs/instruction-count.yaml 2>&1 | FileCheck %s --check-prefix=ERROR -DARG=rremark-name
RUN: not llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function --rpass-name=* %p/Inputs/instruction-count.yaml 2>&1 | FileCheck %s --check-prefix=ERROR -DARG=rpass-name
RUN: not llvm-remarkutil count --parser=yaml --count-by=arg --group-by=function --rfilter-arg-by=* %p/Inputs/instruction-count.yaml 2>&1 | FileCheck %s --check-prefix=ERROR -DARG=rfilter-arg-by

; CHECK-LABEL: Function,InstructionCount
; CHECK: func1,1
Expand All @@ -12,3 +15,5 @@ RUN: llvm-remarkutil yaml2bitstream %p/Inputs/instruction-count.yaml | llvm-rem
; COUNT-CHECK: func1,1
; COUNT-CHECK: func2,2
; COUNT-CHECK: func3,3

; ERROR: error: invalid argument '--[[ARG]]=*': repetition-operator operand invalid
70 changes: 38 additions & 32 deletions llvm/tools/llvm-remarkutil/RemarkCounter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,6 @@ static unsigned getValForKey(StringRef Key, const Remark &Remark) {
return *RemarkArg->getValAsInt();
}

Error Filters::regexArgumentsValid() {
if (RemarkNameFilter && RemarkNameFilter->IsRegex)
if (auto E = checkRegex(RemarkNameFilter->FilterRE))
return E;
if (PassNameFilter && PassNameFilter->IsRegex)
if (auto E = checkRegex(PassNameFilter->FilterRE))
return E;
if (ArgFilter && ArgFilter->IsRegex)
if (auto E = checkRegex(ArgFilter->FilterRE))
return E;
return Error::success();
}

bool Filters::filterRemark(const Remark &Remark) {
if (RemarkNameFilter && !RemarkNameFilter->match(Remark.RemarkName))
return false;
Expand Down Expand Up @@ -250,27 +237,42 @@ Error RemarkCounter::print(StringRef OutputFileName) {
Expected<Filters> getRemarkFilter() {
// Create Filter properties.
std::optional<FilterMatcher> RemarkNameFilter;
if (!RemarkNameOpt.empty())
RemarkNameFilter = FilterMatcher::createExact(RemarkNameOpt);
else if (!RemarkNameOptRE.empty()) {
auto FM = FilterMatcher::createRE(RemarkNameOptRE);
if (!FM)
return FM.takeError();
RemarkNameFilter = std::move(*FM);
}

std::optional<FilterMatcher> PassNameFilter;
if (!PassNameOpt.empty())
PassNameFilter = FilterMatcher::createExact(PassNameOpt);
else if (!PassNameOptRE.empty()) {
auto FM = FilterMatcher::createRE(PassNameOptRE);
if (!FM)
return FM.takeError();
PassNameFilter = std::move(*FM);
}

std::optional<FilterMatcher> RemarkArgFilter;
if (!RemarkFilterArgByOpt.empty())
RemarkArgFilter = FilterMatcher::createExact(RemarkFilterArgByOpt);
else if (!RemarkArgFilterOptRE.empty()) {
auto FM = FilterMatcher::createRE(RemarkArgFilterOptRE);
if (!FM)
return FM.takeError();
RemarkArgFilter = std::move(*FM);
}

std::optional<Type> RemarkType;
if (!RemarkNameOpt.empty())
RemarkNameFilter = {RemarkNameOpt, false};
else if (!RemarkNameOptRE.empty())
RemarkNameFilter = {RemarkNameOptRE, true};
if (!PassNameOpt.empty())
PassNameFilter = {PassNameOpt, false};
else if (!PassNameOptRE.empty())
PassNameFilter = {PassNameOptRE, true};
if (RemarkTypeOpt != Type::Failure)
RemarkType = RemarkTypeOpt;
if (!RemarkFilterArgByOpt.empty())
RemarkArgFilter = {RemarkFilterArgByOpt, false};
else if (!RemarkArgFilterOptRE.empty())
RemarkArgFilter = {RemarkArgFilterOptRE, true};

// Create RemarkFilter.
return Filters::createRemarkFilter(std::move(RemarkNameFilter),
std::move(PassNameFilter),
std::move(RemarkArgFilter), RemarkType);
return Filters{std::move(RemarkNameFilter), std::move(PassNameFilter),
std::move(RemarkArgFilter), RemarkType};
}

Error useCollectRemark(StringRef Buffer, Counter &Counter, Filters &Filter) {
Expand Down Expand Up @@ -313,12 +315,16 @@ static Error collectRemarks() {
SmallVector<FilterMatcher, 4> ArgumentsVector;
if (!Keys.empty()) {
for (auto &Key : Keys)
ArgumentsVector.push_back({Key, false});
ArgumentsVector.push_back(FilterMatcher::createExact(Key));
} else if (!RKeys.empty())
for (auto Key : RKeys)
ArgumentsVector.push_back({Key, true});
for (auto Key : RKeys) {
auto FM = FilterMatcher::createRE(Key, RKeys);
if (!FM)
return FM.takeError();
ArgumentsVector.push_back(std::move(*FM));
}
else
ArgumentsVector.push_back({".*", true});
ArgumentsVector.push_back(FilterMatcher::createAny());

Expected<ArgumentCounter> AC = ArgumentCounter::createArgumentCounter(
GroupByOpt, ArgumentsVector, Buffer, Filter);
Expand Down
56 changes: 1 addition & 55 deletions llvm/tools/llvm-remarkutil/RemarkCounter.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,66 +45,18 @@ inline std::string groupByToStr(GroupBy GroupBy) {
}
}

/// Filter object which can be either a string or a regex to match with the
/// remark properties.
struct FilterMatcher {
Regex FilterRE;
std::string FilterStr;
bool IsRegex;
FilterMatcher(std::string Filter, bool IsRegex) : IsRegex(IsRegex) {
if (IsRegex)
FilterRE = Regex(Filter);
else
FilterStr = Filter;
}

bool match(StringRef StringToMatch) const {
if (IsRegex)
return FilterRE.match(StringToMatch);
return FilterStr == StringToMatch.trim().str();
}
};

/// Filter out remarks based on remark properties based on name, pass name,
/// argument and type.
struct Filters {
std::optional<FilterMatcher> RemarkNameFilter;
std::optional<FilterMatcher> PassNameFilter;
std::optional<FilterMatcher> ArgFilter;
std::optional<Type> RemarkTypeFilter;
/// Returns a filter object if all the arguments provided are valid regex
/// types otherwise return an error.
static Expected<Filters>
createRemarkFilter(std::optional<FilterMatcher> RemarkNameFilter,
std::optional<FilterMatcher> PassNameFilter,
std::optional<FilterMatcher> ArgFilter,
std::optional<Type> RemarkTypeFilter) {
Filters Filter;
Filter.RemarkNameFilter = std::move(RemarkNameFilter);
Filter.PassNameFilter = std::move(PassNameFilter);
Filter.ArgFilter = std::move(ArgFilter);
Filter.RemarkTypeFilter = std::move(RemarkTypeFilter);
if (auto E = Filter.regexArgumentsValid())
return std::move(E);
return std::move(Filter);
}

/// Returns true if \p Remark satisfies all the provided filters.
bool filterRemark(const Remark &Remark);

private:
/// Check if arguments can be parsed as valid regex types.
Error regexArgumentsValid();
};

/// Convert Regex string error to an error object.
inline Error checkRegex(const Regex &Regex) {
std::string Error;
if (!Regex.isValid(Error))
return createStringError(make_error_code(std::errc::invalid_argument),
Twine("Regex: ", Error));
return Error::success();
}

/// Abstract counter class used to define the general required methods for
/// counting a remark.
struct Counter {
Expand Down Expand Up @@ -160,12 +112,6 @@ struct ArgumentCounter : Counter {
StringRef Buffer, Filters &Filter) {
ArgumentCounter AC;
AC.Group = Group;
for (auto &Arg : Arguments) {
if (Arg.IsRegex) {
if (auto E = checkRegex(Arg.FilterRE))
return std::move(E);
}
}
if (auto E = AC.getAllMatchingArgumentsInRemark(Buffer, Arguments, Filter))
return std::move(E);
return AC;
Expand Down
22 changes: 22 additions & 0 deletions llvm/tools/llvm-remarkutil/RemarkUtilHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,27 @@ getOutputFileForRemarks(StringRef OutputFileName, Format OutputFormat) {
? sys::fs::OF_TextWithCRLF
: sys::fs::OF_None);
}

Expected<FilterMatcher>
FilterMatcher::createRE(const llvm::cl::opt<std::string> &Arg) {
return createRE(Arg.ArgStr, Arg);
}

Expected<FilterMatcher>
FilterMatcher::createRE(StringRef Filter, const cl::list<std::string> &Arg) {
return createRE(Arg.ArgStr, Filter);
}

Expected<FilterMatcher> FilterMatcher::createRE(StringRef Arg,
StringRef Value) {
FilterMatcher FM(Value, true);
std::string Error;
if (!FM.FilterRE.isValid(Error))
return createStringError(make_error_code(std::errc::invalid_argument),
"invalid argument '--" + Arg + "=" + Value +
"': " + Error);
return std::move(FM);
}

} // namespace remarks
} // namespace llvm
33 changes: 33 additions & 0 deletions llvm/tools/llvm-remarkutil/RemarkUtilHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
#include "llvm/Remarks/RemarkFormat.h"
#include "llvm/Remarks/RemarkParser.h"
#include "llvm/Remarks/YAMLRemarkSerializer.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/ToolOutputFile.h"

// Keep input + output help + names consistent across the various modes via a
Expand Down Expand Up @@ -55,5 +57,36 @@ Expected<std::unique_ptr<ToolOutputFile>>
getOutputFileWithFlags(StringRef OutputFileName, sys::fs::OpenFlags Flags);
Expected<std::unique_ptr<ToolOutputFile>>
getOutputFileForRemarks(StringRef OutputFileName, Format OutputFormat);

/// 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 FilterMatcher createAny() { return {".*", true}; }

bool match(StringRef StringToMatch) const {
if (IsRegex)
return FilterRE.match(StringToMatch);
return FilterStr == StringToMatch.trim().str();
}
};

} // namespace remarks
} // namespace llvm