1 //===- CLOptionsSetup.cpp - Helpers to setup debug CL options ---*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "mlir/Debug/CLOptionsSetup.h"
11 #include "mlir/Debug/Counter.h"
12 #include "mlir/Debug/DebuggerExecutionContextHook.h"
13 #include "mlir/Debug/ExecutionContext.h"
14 #include "mlir/Debug/Observers/ActionLogging.h"
15 #include "mlir/Debug/Observers/ActionProfiler.h"
16 #include "mlir/IR/MLIRContext.h"
17 #include "mlir/Support/FileUtilities.h"
18 #include "llvm/Support/CommandLine.h"
19 #include "llvm/Support/ManagedStatic.h"
20 #include "llvm/Support/ToolOutputFile.h"
23 using namespace mlir::tracing
;
27 struct DebugConfigCLOptions
: public DebugConfig
{
28 DebugConfigCLOptions() {
29 static cl::opt
<std::string
, /*ExternalStorage=*/true> logActionsTo
{
31 cl::desc("Log action execution to a file, or stderr if "
33 cl::location(logActionsToFlag
)};
35 static cl::opt
<std::string
, /*ExternalStorage=*/true> profileActionsTo
{
37 cl::desc("Profile action execution to a file, or stderr if "
39 cl::location(profileActionsToFlag
)};
41 static cl::list
<std::string
> logActionLocationFilter(
42 "log-mlir-actions-filter",
44 "Comma separated list of locations to filter actions from logging"),
46 cl::cb
<void, std::string
>([&](const std::string
&location
) {
47 static bool registerOnce
= [&] {
48 addLogActionLocFilter(&locBreakpointManager
);
52 static std::vector
<std::string
> locations
;
53 locations
.push_back(location
);
54 StringRef locStr
= locations
.back();
56 // Parse the individual location filters and set the breakpoints.
57 auto diag
= [](Twine msg
) { llvm::errs() << msg
<< "\n"; };
59 tracing::FileLineColLocBreakpoint::parseFromString(locStr
, diag
);
60 if (failed(locBreakpoint
)) {
61 llvm::errs() << "Invalid location filter: " << locStr
<< "\n";
64 auto [file
, line
, col
] = *locBreakpoint
;
65 locBreakpointManager
.addBreakpoint(file
, line
, col
);
68 tracing::FileLineColLocBreakpointManager locBreakpointManager
;
73 static ManagedStatic
<DebugConfigCLOptions
> clOptionsConfig
;
74 void DebugConfig::registerCLOptions() { *clOptionsConfig
; }
76 DebugConfig
DebugConfig::createFromCLOptions() { return *clOptionsConfig
; }
78 class InstallDebugHandler::Impl
{
80 Impl(MLIRContext
&context
, const DebugConfig
&config
) {
81 if (config
.getLogActionsTo().empty() &&
82 config
.getProfileActionsTo().empty() &&
83 !config
.isDebuggerActionHookEnabled()) {
84 if (tracing::DebugCounter::isActivated())
85 context
.registerActionHandler(tracing::DebugCounter());
88 errs() << "ExecutionContext registered on the context";
89 if (tracing::DebugCounter::isActivated())
90 emitError(UnknownLoc::get(&context
),
91 "Debug counters are incompatible with --log-actions-to and "
92 "--mlir-enable-debugger-hook options and are disabled");
93 if (!config
.getLogActionsTo().empty()) {
94 std::string errorMessage
;
95 logActionsFile
= openOutputFile(config
.getLogActionsTo(), &errorMessage
);
96 if (!logActionsFile
) {
97 emitError(UnknownLoc::get(&context
),
98 "Opening file for --log-actions-to failed: ")
99 << errorMessage
<< "\n";
102 logActionsFile
->keep();
103 raw_fd_ostream
&logActionsStream
= logActionsFile
->os();
104 actionLogger
= std::make_unique
<tracing::ActionLogger
>(logActionsStream
);
105 for (const auto *locationBreakpoint
: config
.getLogActionsLocFilters())
106 actionLogger
->addBreakpointManager(locationBreakpoint
);
107 executionContext
.registerObserver(actionLogger
.get());
110 if (!config
.getProfileActionsTo().empty()) {
111 std::string errorMessage
;
113 openOutputFile(config
.getProfileActionsTo(), &errorMessage
);
114 if (!profileActionsFile
) {
115 emitError(UnknownLoc::get(&context
),
116 "Opening file for --profile-actions-to failed: ")
117 << errorMessage
<< "\n";
120 profileActionsFile
->keep();
121 raw_fd_ostream
&profileActionsStream
= profileActionsFile
->os();
123 std::make_unique
<tracing::ActionProfiler
>(profileActionsStream
);
124 executionContext
.registerObserver(actionProfiler
.get());
127 if (config
.isDebuggerActionHookEnabled()) {
128 errs() << " (with Debugger hook)";
129 setupDebuggerExecutionContextHook(executionContext
);
132 context
.registerActionHandler(executionContext
);
136 std::unique_ptr
<ToolOutputFile
> logActionsFile
;
137 tracing::ExecutionContext executionContext
;
138 std::unique_ptr
<tracing::ActionLogger
> actionLogger
;
139 std::vector
<std::unique_ptr
<tracing::FileLineColLocBreakpoint
>>
141 std::unique_ptr
<ToolOutputFile
> profileActionsFile
;
142 std::unique_ptr
<tracing::ActionProfiler
> actionProfiler
;
145 InstallDebugHandler::InstallDebugHandler(MLIRContext
&context
,
146 const DebugConfig
&config
)
147 : impl(std::make_unique
<Impl
>(context
, config
)) {}
149 InstallDebugHandler::~InstallDebugHandler() = default;