138 lines
4.9 KiB
C++
138 lines
4.9 KiB
C++
//===- FileLineColLocBreakpointManager.h - TODO: add message ----*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef MLIR_TRACING_BREAKPOINTMANAGERS_FILELINECOLLOCBREAKPOINTMANAGER_H
|
|
#define MLIR_TRACING_BREAKPOINTMANAGERS_FILELINECOLLOCBREAKPOINTMANAGER_H
|
|
|
|
#include "mlir/Debug/BreakpointManager.h"
|
|
#include "mlir/Debug/ExecutionContext.h"
|
|
#include "mlir/IR/Action.h"
|
|
#include "mlir/IR/Location.h"
|
|
#include "mlir/IR/Operation.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include <memory>
|
|
#include <optional>
|
|
|
|
namespace mlir {
|
|
namespace tracing {
|
|
|
|
/// This breakpoing intends to match a FileLineColLocation, that is a tuple of
|
|
/// file name, line number, and column number. Using -1 for the column and the
|
|
/// line number will match any column and line number respectively.
|
|
class FileLineColLocBreakpoint
|
|
: public BreakpointBase<FileLineColLocBreakpoint> {
|
|
public:
|
|
FileLineColLocBreakpoint(StringRef file, int64_t line, int64_t col)
|
|
: line(line), col(col) {}
|
|
|
|
void print(raw_ostream &os) const override {
|
|
os << "Location: " << file << ':' << line << ':' << col;
|
|
}
|
|
|
|
/// Parse a string representation in the form of "<file>:<line>:<col>". Return
|
|
/// a tuple with these three elements, the first one is a StringRef pointing
|
|
/// into the original string.
|
|
static FailureOr<std::tuple<StringRef, int64_t, int64_t>> parseFromString(
|
|
StringRef str, llvm::function_ref<void(Twine)> diag = [](Twine) {});
|
|
|
|
private:
|
|
/// A filename on which to break.
|
|
StringRef file;
|
|
|
|
/// A particular line on which to break, or -1 to break on any line.
|
|
int64_t line;
|
|
|
|
/// A particular column on which to break, or -1 to break on any column
|
|
int64_t col;
|
|
|
|
friend class FileLineColLocBreakpointManager;
|
|
};
|
|
|
|
/// This breakpoint manager is responsible for matching
|
|
/// FileLineColLocBreakpoint. It'll extract the location from the action context
|
|
/// looking for a FileLineColLocation, and match it against the registered
|
|
/// breakpoints.
|
|
class FileLineColLocBreakpointManager
|
|
: public BreakpointManagerBase<FileLineColLocBreakpointManager> {
|
|
public:
|
|
Breakpoint *match(const Action &action) const override {
|
|
for (const IRUnit &unit : action.getContextIRUnits()) {
|
|
if (auto *op = llvm::dyn_cast_if_present<Operation *>(unit)) {
|
|
if (auto match = matchFromLocation(op->getLoc()))
|
|
return *match;
|
|
continue;
|
|
}
|
|
if (auto *block = llvm::dyn_cast_if_present<Block *>(unit)) {
|
|
for (auto &op : block->getOperations()) {
|
|
if (auto match = matchFromLocation(op.getLoc()))
|
|
return *match;
|
|
}
|
|
continue;
|
|
}
|
|
if (Region *region = llvm::dyn_cast_if_present<Region *>(unit)) {
|
|
if (auto match = matchFromLocation(region->getLoc()))
|
|
return *match;
|
|
continue;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
|
|
FileLineColLocBreakpoint *addBreakpoint(StringRef file, int64_t line,
|
|
int64_t col = -1) {
|
|
auto &breakpoint = breakpoints[std::make_tuple(file, line, col)];
|
|
if (!breakpoint)
|
|
breakpoint = std::make_unique<FileLineColLocBreakpoint>(file, line, col);
|
|
return breakpoint.get();
|
|
}
|
|
|
|
private:
|
|
std::optional<Breakpoint *> matchFromLocation(Location initialLoc) const {
|
|
std::optional<Breakpoint *> match = std::nullopt;
|
|
initialLoc->walk([&](Location loc) {
|
|
auto fileLoc = dyn_cast<FileLineColLoc>(loc);
|
|
if (!fileLoc)
|
|
return WalkResult::advance();
|
|
StringRef file = fileLoc.getFilename();
|
|
int64_t line = fileLoc.getLine();
|
|
int64_t col = fileLoc.getColumn();
|
|
auto lookup = breakpoints.find(std::make_tuple(file, line, col));
|
|
if (lookup != breakpoints.end() && lookup->second->isEnabled()) {
|
|
match = lookup->second.get();
|
|
return WalkResult::interrupt();
|
|
}
|
|
// If not found, check with the -1 key if we have a breakpoint for any
|
|
// col.
|
|
lookup = breakpoints.find(std::make_tuple(file, line, -1));
|
|
if (lookup != breakpoints.end() && lookup->second->isEnabled()) {
|
|
match = lookup->second.get();
|
|
return WalkResult::interrupt();
|
|
}
|
|
// If not found, check with the -1 key if we have a breakpoint for any
|
|
// line.
|
|
lookup = breakpoints.find(std::make_tuple(file, -1, -1));
|
|
if (lookup != breakpoints.end() && lookup->second->isEnabled()) {
|
|
match = lookup->second.get();
|
|
return WalkResult::interrupt();
|
|
}
|
|
return WalkResult::advance();
|
|
});
|
|
return match;
|
|
}
|
|
|
|
/// A map from a (filename, line, column) -> breakpoint.
|
|
DenseMap<std::tuple<StringRef, int64_t, int64_t>,
|
|
std::unique_ptr<FileLineColLocBreakpoint>>
|
|
breakpoints;
|
|
};
|
|
|
|
} // namespace tracing
|
|
} // namespace mlir
|
|
|
|
#endif // MLIR_TRACING_BREAKPOINTMANAGERS_FILELINECOLLOCBREAKPOINTMANAGER_H
|