MLIR 24.0.0git
ExecutionContext.h
Go to the documentation of this file.
1//===- ExecutionContext.h - Execution Context Support *- C++ -*-=============//
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
9#ifndef MLIR_TRACING_EXECUTIONCONTEXT_H
10#define MLIR_TRACING_EXECUTIONCONTEXT_H
11
13#include "mlir/IR/Action.h"
14#include "llvm/ADT/SmallVector.h"
15
16namespace mlir {
17namespace tracing {
18
19/// This class is used to keep track of the active actions in the stack.
20/// It provides the current action but also access to the parent entry in the
21/// stack. This allows to keep track of the nested nature in which actions may
22/// be executed.
24public:
25 ActionActiveStack(const ActionActiveStack *parent, const Action &action,
26 int depth)
27 : parent(parent), action(action), depth(depth) {}
28 const ActionActiveStack *getParent() const { return parent; }
29 const Action &getAction() const { return action; }
30 int getDepth() const { return depth; }
31 void print(raw_ostream &os, bool withContext) const;
32#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
33 LLVM_DUMP_METHOD void dump() const;
34#endif
35 Breakpoint *getBreakpoint() const { return breakpoint; }
36 void setBreakpoint(Breakpoint *breakpoint) { this->breakpoint = breakpoint; }
37
38private:
39 Breakpoint *breakpoint = nullptr;
40 const ActionActiveStack *parent;
41 const Action &action;
42 int depth;
43};
44
45/// The ExecutionContext is the main orchestration of the infrastructure, it
46/// acts as a handler in the MLIRContext for executing an Action. When an action
47/// is dispatched, it'll query its set of Breakpoints managers for a breakpoint
48/// matching this action. If a breakpoint is hit, it passes the action and the
49/// breakpoint information to a callback. The callback is responsible for
50/// controlling the execution of the action through an enum value it returns.
51/// Optionally, observers can be registered to be notified before and after the
52/// callback is executed.
54public:
55 /// Enum that allows the client of the context to control the execution of the
56 /// action.
57 /// - Apply: The action is executed.
58 /// - Skip: The action is skipped.
59 /// - Step: The action is executed and the execution is paused before the next
60 /// action, including for nested actions encountered before the
61 /// current action finishes.
62 /// - Next: The action is executed and the execution is paused after the
63 /// current action finishes before the next action.
64 /// - Finish: The action is executed and the execution is paused only when we
65 /// reach the parent/enclosing operation. If there are no enclosing
66 /// operation, the execution continues without stopping.
67 /// - Rerun: The action gets executed again immediately after it finishes.
68 enum Control {
69 Apply = 1,
70 Skip = 2,
71 Step = 3,
72 Next = 4,
73 Finish = 5,
75 };
76
77 /// The type of the callback that is used to control the execution.
78 /// The callback is passed the current action.
80
81 /// Create an ExecutionContext with a callback that is used to control the
82 /// execution.
83 ExecutionContext(CallbackTy callback) { setCallback(callback); }
84 ExecutionContext() = default;
85
86 /// Set the callback that is used to control the execution.
87 void setCallback(CallbackTy callback) {
88 onBreakpointControlExecutionCallback = callback;
89 }
90
91 /// This abstract class defines the interface used to observe an Action
92 /// execution. It allows to be notified before and after the callback is
93 /// processed, but can't affect the execution.
94 struct Observer {
95 virtual ~Observer() = default;
96 /// This method is called before the Action is executed
97 /// If a breakpoint was hit, it is passed as an argument to the callback.
98 /// The `willExecute` argument indicates whether the action will be executed
99 /// or not.
100 /// Note that this method will be called from multiple threads concurrently
101 /// when MLIR multi-threading is enabled.
102 virtual void beforeExecute(const ActionActiveStack *action,
103 Breakpoint *breakpoint, bool willExecute) {}
104
105 /// This method is called after the Action is executed, if it was executed.
106 /// It is not called if the action is skipped.
107 /// Note that this method will be called from multiple threads concurrently
108 /// when MLIR multi-threading is enabled.
109 virtual void afterExecute(const ActionActiveStack *action) {}
110 };
111
112 /// Register a new `Observer` on this context. It'll be notified before and
113 /// after executing an action. Note that this method is not thread-safe: it
114 /// isn't supported to add a new observer while actions may be executed.
115 void registerObserver(Observer *observer);
116
117 /// Register a new `BreakpointManager` on this context. It'll have a chance to
118 /// match an action before it gets executed. Note that this method is not
119 /// thread-safe: it isn't supported to add a new manager while actions may be
120 /// executed.
122 breakpoints.push_back(manager);
123 }
124
125 /// Process the given action. This is the operator called by MLIRContext on
126 /// `executeAction()`.
127 void operator()(function_ref<void()> transform, const Action &action);
128
129private:
130 /// Callback that is executed when a breakpoint is hit and allows the client
131 /// to control the execution.
132 CallbackTy onBreakpointControlExecutionCallback;
133
134 /// Next point to stop execution as describe by `Control` enum.
135 /// This is handle by indicating at which levels of depth the next
136 /// break should happen.
137 std::optional<int> depthToBreak;
138
139 /// Observers that are notified before and after the callback is executed.
140 SmallVector<Observer *> observers;
141
142 /// The list of managers that are queried for breakpoints.
144
145 /// Stack of depths of actions that should be rerun.
146 SmallVector<int> rerunControlStack;
147};
148
149} // namespace tracing
150} // namespace mlir
151
152#endif // MLIR_TRACING_EXECUTIONCONTEXT_H
An action is a specific action that is to be taken by the compiler, that can be toggled and controlle...
Definition Action.h:38
A breakpoint manager is responsible for managing a set of breakpoints and matching them to a given ac...
This abstract class represents a breakpoint.
void registerObserver(Observer *observer)
Register a new Observer on this context.
function_ref< Control(const ActionActiveStack *)> CallbackTy
The type of the callback that is used to control the execution.
Control
Enum that allows the client of the context to control the execution of the action.
ExecutionContext(CallbackTy callback)
Create an ExecutionContext with a callback that is used to control the execution.
void addBreakpointManager(BreakpointManager *manager)
Register a new BreakpointManager on this context.
void setCallback(CallbackTy callback)
Set the callback that is used to control the execution.
void operator()(function_ref< void()> transform, const Action &action)
Process the given action.
Include the generated interface declarations.
llvm::function_ref< Fn > function_ref
Definition LLVM.h:155
This class is used to keep track of the active actions in the stack.
const Action & getAction() const
void setBreakpoint(Breakpoint *breakpoint)
const ActionActiveStack * getParent() const
void print(raw_ostream &os, bool withContext) const
LLVM_DUMP_METHOD void dump() const
ActionActiveStack(const ActionActiveStack *parent, const Action &action, int depth)
This abstract class defines the interface used to observe an Action execution.
virtual void afterExecute(const ActionActiveStack *action)
This method is called after the Action is executed, if it was executed.
virtual void beforeExecute(const ActionActiveStack *action, Breakpoint *breakpoint, bool willExecute)
This method is called before the Action is executed If a breakpoint was hit, it is passed as an argum...