//===- CLOptionsSetup.cpp - Helpers to setup debug CL options ---*- 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 // //===----------------------------------------------------------------------===// #include "mlir/Debug/CLOptionsSetup.h" #include "mlir/Debug/Counter.h" #include "mlir/Debug/DebuggerExecutionContextHook.h" #include "mlir/Debug/ExecutionContext.h" #include "mlir/Debug/Observers/ActionLogging.h" #include "mlir/Debug/Observers/ActionProfiler.h" #include "mlir/IR/MLIRContext.h" #include "mlir/Support/FileUtilities.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/ToolOutputFile.h" using namespace mlir; using namespace mlir::tracing; using namespace llvm; namespace { struct DebugConfigCLOptions : public DebugConfig { DebugConfigCLOptions() { static cl::opt logActionsTo{ "log-actions-to", cl::desc("Log action execution to a file, or stderr if " " '-' is passed"), cl::location(logActionsToFlag)}; static cl::opt profileActionsTo{ "profile-actions-to", cl::desc("Profile action execution to a file, or stderr if " " '-' is passed"), cl::location(profileActionsToFlag)}; static cl::list logActionLocationFilter( "log-mlir-actions-filter", cl::desc( "Comma separated list of locations to filter actions from logging"), cl::CommaSeparated, cl::cb([&](const std::string &location) { static bool registerOnce = [&] { addLogActionLocFilter(&locBreakpointManager); return true; }(); (void)registerOnce; static std::vector locations; locations.push_back(location); StringRef locStr = locations.back(); // Parse the individual location filters and set the breakpoints. auto diag = [](Twine msg) { llvm::errs() << msg << "\n"; }; auto locBreakpoint = tracing::FileLineColLocBreakpoint::parseFromString(locStr, diag); if (failed(locBreakpoint)) { llvm::errs() << "Invalid location filter: " << locStr << "\n"; exit(1); } auto [file, line, col] = *locBreakpoint; locBreakpointManager.addBreakpoint(file, line, col); })); } tracing::FileLineColLocBreakpointManager locBreakpointManager; }; } // namespace static ManagedStatic clOptionsConfig; void DebugConfig::registerCLOptions() { *clOptionsConfig; } DebugConfig DebugConfig::createFromCLOptions() { return *clOptionsConfig; } class InstallDebugHandler::Impl { public: Impl(MLIRContext &context, const DebugConfig &config) { if (config.getLogActionsTo().empty() && config.getProfileActionsTo().empty() && !config.isDebuggerActionHookEnabled()) { if (tracing::DebugCounter::isActivated()) context.registerActionHandler(tracing::DebugCounter()); return; } errs() << "ExecutionContext registered on the context"; if (tracing::DebugCounter::isActivated()) emitError(UnknownLoc::get(&context), "Debug counters are incompatible with --log-actions-to and " "--mlir-enable-debugger-hook options and are disabled"); if (!config.getLogActionsTo().empty()) { std::string errorMessage; logActionsFile = openOutputFile(config.getLogActionsTo(), &errorMessage); if (!logActionsFile) { emitError(UnknownLoc::get(&context), "Opening file for --log-actions-to failed: ") << errorMessage << "\n"; return; } logActionsFile->keep(); raw_fd_ostream &logActionsStream = logActionsFile->os(); actionLogger = std::make_unique(logActionsStream); for (const auto *locationBreakpoint : config.getLogActionsLocFilters()) actionLogger->addBreakpointManager(locationBreakpoint); executionContext.registerObserver(actionLogger.get()); } if (!config.getProfileActionsTo().empty()) { std::string errorMessage; profileActionsFile = openOutputFile(config.getProfileActionsTo(), &errorMessage); if (!profileActionsFile) { emitError(UnknownLoc::get(&context), "Opening file for --profile-actions-to failed: ") << errorMessage << "\n"; return; } profileActionsFile->keep(); raw_fd_ostream &profileActionsStream = profileActionsFile->os(); actionProfiler = std::make_unique(profileActionsStream); executionContext.registerObserver(actionProfiler.get()); } if (config.isDebuggerActionHookEnabled()) { errs() << " (with Debugger hook)"; setupDebuggerExecutionContextHook(executionContext); } errs() << "\n"; context.registerActionHandler(executionContext); } private: std::unique_ptr logActionsFile; tracing::ExecutionContext executionContext; std::unique_ptr actionLogger; std::vector> locationBreakpoints; std::unique_ptr profileActionsFile; std::unique_ptr actionProfiler; }; InstallDebugHandler::InstallDebugHandler(MLIRContext &context, const DebugConfig &config) : impl(std::make_unique(context, config)) {} InstallDebugHandler::~InstallDebugHandler() = default;