//===- 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 #include 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 { 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 "::". Return /// a tuple with these three elements, the first one is a StringRef pointing /// into the original string. static FailureOr> parseFromString( StringRef str, llvm::function_ref 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 { public: Breakpoint *match(const Action &action) const override { for (const IRUnit &unit : action.getContextIRUnits()) { if (auto *op = llvm::dyn_cast_if_present(unit)) { if (auto match = matchFromLocation(op->getLoc())) return *match; continue; } if (auto *block = llvm::dyn_cast_if_present(unit)) { for (auto &op : block->getOperations()) { if (auto match = matchFromLocation(op.getLoc())) return *match; } continue; } if (Region *region = llvm::dyn_cast_if_present(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(file, line, col); return breakpoint.get(); } private: std::optional matchFromLocation(Location initialLoc) const { std::optional match = std::nullopt; initialLoc->walk([&](Location loc) { auto fileLoc = dyn_cast(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::unique_ptr> breakpoints; }; } // namespace tracing } // namespace mlir #endif // MLIR_TRACING_BREAKPOINTMANAGERS_FILELINECOLLOCBREAKPOINTMANAGER_H