15#include "llvm/ADT/DenseMap.h"
16#include "llvm/ADT/DenseSet.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/StringExtras.h"
19#include "llvm/ADT/StringRef.h"
30 llvm::raw_string_ostream os(
val);
35 llvm::raw_string_ostream os(
val);
40 llvm::raw_string_ostream os(
val);
49 llvm::erase_if(
args, [](
const Arg &arg) {
return arg.
isLink; });
66 for (
size_t i = 0; i < sorted.size(); ++i) {
67 const auto &a = sorted[i];
70 llvm::StringRef val(a.
val);
71 bool needsQuote = val.contains(
' ') || val.contains(
',') ||
72 val.contains(
'{') || val.contains(
'}');
74 os <<
'"' << val <<
'"';
78 if (i + 1 < sorted.size())
95 os <<
'[' << type <<
"] ";
103 if (
auto flc =
getLocation()->findInstanceOf<FileLineColLoc>()) {
104 os <<
" @" << flc.getFilename() <<
":" << flc.getLine() <<
":"
114 llvm::raw_string_ostream os(s);
133 llvm_unreachable(
"Unknown remark kind");
139 return llvm::remarks::Type::Unknown;
141 return llvm::remarks::Type::Passed;
143 return llvm::remarks::Type::Missed;
145 return llvm::remarks::Type::Failure;
147 return llvm::remarks::Type::Analysis;
149 llvm_unreachable(
"Unknown remark kind");
153 auto locLambda = [&]() -> llvm::remarks::RemarkLocation {
156 if (
auto flc =
getLocation()->findInstanceOf<FileLineColLoc>())
157 return {flc.getFilename(), flc.getLine(), flc.getColumn()};
158 return {
"<unknown file>", 0, 0};
161 llvm::remarks::Remark r;
170 r.Args.emplace_back();
171 r.Args.back().Key = arg.key;
172 r.Args.back().Val = arg.val;
183 owner->report(std::move(*remark));
191template <
typename RemarkT>
193 static_assert(std::is_base_of_v<Remark, RemarkT>,
194 "RemarkT must derive from Remark");
195 auto remark = std::make_unique<RemarkT>(
loc, opts);
196 remark->setId(generateRemarkId());
200template <
typename RemarkT>
204 return (this->*isEnabled)(opts.
categoryName) ? makeRemark<RemarkT>(
loc, opts)
213 return passedFilter && passedFilter->match(
categoryName);
217 return analysisFilter && analysisFilter->match(
categoryName);
221 return failedFilter && failedFilter->match(
categoryName);
238 llvm_unreachable(
"Unknown remark kind");
243 return emitIfEnabled<OptRemarkPass>(
loc, opts,
249 return emitIfEnabled<OptRemarkMissed>(
255 return emitIfEnabled<OptRemarkFailure>(
261 return emitIfEnabled<OptRemarkAnalysis>(
271 if (remarkStreamer) {
272 remarkStreamer->streamOptimizationRemark(
remark);
276 if (printAsEmitRemarks)
281 if (remarkEmittingPolicy)
282 remarkEmittingPolicy->reportRemark(
remark);
286 if (remarkEmittingPolicy)
287 remarkEmittingPolicy->finalize();
290 remarkStreamer->finalize();
294 std::unique_ptr<MLIRRemarkStreamerBase> streamer,
295 std::unique_ptr<RemarkEmittingPolicyBase> remarkEmittingPolicy,
296 std::string *errMsg) {
297 remarkStreamer = std::move(streamer);
299 auto reportFunc = llvm::bind_front<&RemarkEngine::reportImpl>(
this);
300 remarkEmittingPolicy->initialize(
ReportFn(std::move(reportFunc)));
302 this->remarkEmittingPolicy = std::move(remarkEmittingPolicy);
309 return s.starts_with(
"^") && s.ends_with(
"$");
316 return (llvm::Twine(
"^(") + filter +
")$").str();
322static std::optional<llvm::Regex>
324 const std::optional<std::string> &specific) {
326 if (cats.
all && !cats.
all->empty())
327 parts.emplace_back(*cats.
all);
328 if (specific && !specific->empty())
329 parts.emplace_back(*specific);
334 std::string joined = llvm::join(parts,
"|");
337 llvm::Regex rx(anchored);
339 if (!rx.isValid(err))
342 return std::make_optional<llvm::Regex>(std::move(rx));
347 : printAsEmitRemarks(printAsEmitRemarks) {
359 MLIRContext &ctx, std::unique_ptr<detail::MLIRRemarkStreamerBase> streamer,
360 std::unique_ptr<detail::RemarkEmittingPolicyBase> remarkEmittingPolicy,
363 std::make_unique<detail::RemarkEngine>(printAsEmitRemarks, cats);
366 if (
failed(engine->initialize(std::move(streamer),
367 std::move(remarkEmittingPolicy), &errMsg))) {
368 llvm::report_fatal_error(
369 llvm::Twine(
"Failed to initialize remark engine. Error: ") + errMsg);
387 if (discardedIds.empty())
389 auto ids = llvm::to_vector(
remark.getRelatedRemarkIds());
391 ids, [&](
RemarkId id) {
return discardedIds.contains(
id.getValue()); });
392 if (ids.size() !=
remark.getRelatedRemarkIds().size())
393 remark.setRelatedRemarkIds(ids);
398 std::scoped_lock<std::mutex> lock(mutex);
399 auto previous = pendingRemarks.find(
copy);
400 if (previous != pendingRemarks.end()) {
401 if (previous->getId() && previous->getId() !=
copy.getId())
402 discardedIds.insert(previous->getId().getValue());
403 pendingRemarks.erase(previous);
405 pendingRemarks.insert(std::move(
copy));
409 assert(
reportImpl &&
"reportImpl is not set");
414 std::scoped_lock<std::mutex> lock(mutex);
415 remarks = llvm::to_vector<0>(pendingRemarks);
416 pendingRemarks.clear();
417 discarded.swap(discardedIds);
421 for (
const auto &
remark : remarks)
423 discarded.erase(
remark.getId().getValue());
424 for (
auto &
remark : remarks)
427 llvm::sort(remarks, [](
const auto &lhs,
const auto &rhs) {
432 return lhs.getId().getValue() < rhs.getId().getValue();
439 for (
const auto &
remark : remarks) {
442 for (
auto relId :
remark.getRelatedRemarkIds())
443 childIds.insert(relId.getValue());
450 worklist.push_back(&root);
451 while (!worklist.empty()) {
452 const auto *
remark = worklist.pop_back_val();
453 if (!emitted.insert(
remark).second)
457 if (
const auto *related = idMap.lookup(
id.getValue()))
458 worklist.push_back(related);
462 for (
const auto &
remark : remarks) {
463 if (
remark.getId() && childIds.contains(
remark.getId().getValue()))
468 for (
const auto &
remark : remarks)
469 if (!emitted.contains(&
remark))
if(failed(verifyVectorMemoryOp(getOperation(), memrefType, getVectorType()))) return failure()
static void copy(Location loc, Value dst, Value src, Value size, OpBuilder &builder)
Copies the given number of bytes from src to dst pointers.
static LogicalResult emit(SolverOp solver, const SMTEmissionOptions &options, mlir::raw_indented_ostream &stream)
Emit the SMT operations in the given 'solver' to the 'stream'.
Attributes are known-constant values of operations.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
void setRemarkEngine(std::unique_ptr< remark::detail::RemarkEngine > engine)
Set the remark engine for this context.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
InFlightDiagnostic emitRemark(Location loc)
Utility method to emit a remark message using this location.