MLIR 22.0.0git
ExecutionContext.cpp
Go to the documentation of this file.
1//===- ExecutionContext.cpp - Debug Execution Context Support -------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "llvm/ADT/ScopeExit.h"
12#include "llvm/Support/FormatVariadic.h"
13
14using namespace mlir;
15using namespace mlir::tracing;
16
17//===----------------------------------------------------------------------===//
18// ActionActiveStack
19//===----------------------------------------------------------------------===//
20
21void ActionActiveStack::print(raw_ostream &os, bool withContext) const {
22 os << "ActionActiveStack depth " << getDepth() << "\n";
23 const ActionActiveStack *current = this;
24 int count = 0;
25 while (current) {
26 llvm::errs() << llvm::formatv("#{0,3}: ", count++);
27 current->action.print(llvm::errs());
28 llvm::errs() << "\n";
29 ArrayRef<IRUnit> context = current->action.getContextIRUnits();
30 if (withContext && !context.empty()) {
31 llvm::errs() << "Context:\n";
32 llvm::interleave(
33 current->action.getContextIRUnits(),
34 [&](const IRUnit &unit) {
35 llvm::errs() << " - ";
36 unit.print(llvm::errs());
37 },
38 [&]() { llvm::errs() << "\n"; });
39 llvm::errs() << "\n";
40 }
41 current = current->parent;
42 }
43}
44
45//===----------------------------------------------------------------------===//
46// ExecutionContext
47//===----------------------------------------------------------------------===//
48
49static const LLVM_THREAD_LOCAL ActionActiveStack *actionStack = nullptr;
50
52 observers.push_back(observer);
53}
54
56 const Action &action) {
57 // Update the top of the stack with the current action.
58 int depth = 0;
59 if (actionStack)
60 depth = actionStack->getDepth() + 1;
61 ActionActiveStack info{actionStack, action, depth};
62 actionStack = &info;
63 auto raii = llvm::make_scope_exit([&]() { actionStack = info.getParent(); });
64 Breakpoint *breakpoint = nullptr;
65
66 // Invoke the callback here and handles control requests here.
67 auto handleUserInput = [&]() -> bool {
68 if (!onBreakpointControlExecutionCallback)
69 return true;
70 auto todoNext = onBreakpointControlExecutionCallback(actionStack);
71 switch (todoNext) {
73 depthToBreak = std::nullopt;
74 return true;
76 depthToBreak = std::nullopt;
77 return false;
79 depthToBreak = depth + 1;
80 return true;
82 depthToBreak = depth;
83 return true;
85 depthToBreak = depth - 1;
86 return true;
87 }
88 llvm::report_fatal_error("Unknown control request");
89 };
90
91 // Try to find a breakpoint that would hit on this action.
92 // Right now there is no way to collect them all, we stop at the first one.
93 for (auto *breakpointManager : breakpoints) {
94 breakpoint = breakpointManager->match(action);
95 if (breakpoint)
96 break;
97 }
98 info.setBreakpoint(breakpoint);
99
100 bool shouldExecuteAction = true;
101 // If we have a breakpoint, or if `depthToBreak` was previously set and the
102 // current depth matches, we invoke the user-provided callback.
103 if (breakpoint || (depthToBreak && depth <= depthToBreak))
104 shouldExecuteAction = handleUserInput();
105
106 // Notify the observers about the current action.
107 for (auto *observer : observers)
108 observer->beforeExecute(actionStack, breakpoint, shouldExecuteAction);
109
110 if (shouldExecuteAction) {
111 // Execute the action here.
112 transform();
113
114 // Notify the observers about completion of the action.
115 for (auto *observer : observers)
116 observer->afterExecute(actionStack);
117 }
118
119 if (depthToBreak && depth <= depthToBreak)
120 handleUserInput();
121}
static const LLVM_THREAD_LOCAL ActionActiveStack * actionStack
IRUnit is a union of the different types of IR objects that constitute the IR structure (other than T...
Definition Unit.h:28
An action is a specific action that is to be taken by the compiler, that can be toggled and controlle...
Definition Action.h:38
virtual void print(raw_ostream &os) const
Definition Action.h:50
virtual ArrayRef< IRUnit > getContextIRUnits() const
Return the set of IR units that are associated with this action.
Definition Action.h:55
This abstract class represents a breakpoint.
void registerObserver(Observer *observer)
Register a new Observer on this context.
void operator()(function_ref< void()> transform, const Action &action)
Process the given action.
Include the generated interface declarations.
This class is used to keep track of the active actions in the stack.
void setBreakpoint(Breakpoint *breakpoint)
const ActionActiveStack * getParent() const
void print(raw_ostream &os, bool withContext) const
ActionActiveStack(const ActionActiveStack *parent, const Action &action, int depth)
This abstract class defines the interface used to observe an Action execution.