Files
gps/tools/local/circt/include/mlir/Debug/BreakpointManagers/FileLineColLocBreakpointManager.h
T
2026-07-12 11:01:51 +03:00

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