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 void dump() const {
33 print(llvm::errs(), /*withContext=*/true);
34 llvm::errs() << "\n";
35 }
36 Breakpoint *getBreakpoint() const { return breakpoint; }
37 void setBreakpoint(Breakpoint *breakpoint) { this->breakpoint = breakpoint; }
38
39private:
40 Breakpoint *breakpoint = nullptr;
41 const ActionActiveStack *parent;
42 const Action &action;
43 int depth;
44};
45
46/// The ExecutionContext is the main orchestration of the infrastructure, it
47/// acts as a handler in the MLIRContext for executing an Action. When an action
48/// is dispatched, it'll query its set of Breakpoints managers for a breakpoint
49/// matching this action. If a breakpoint is hit, it passes the action and the
50/// breakpoint information to a callback. The callback is responsible for
51/// controlling the execution of the action through an enum value it returns.
52/// Optionally, observers can be registered to be notified before and after the
53/// callback is executed.
55public:
56 /// Enum that allows the client of the context to control the execution of the
57 /// action.
58 /// - Apply: The action is executed.
59 /// - Skip: The action is skipped.
60 /// - Step: The action is executed and the execution is paused before the next
61 /// action, including for nested actions encountered before the
62 /// current action finishes.
63 /// - Next: The action is executed and the execution is paused after the
64 /// current action finishes before the next action.
65 /// - Finish: The action is executed and the execution is paused only when we
66 /// reach the parent/enclosing operation. If there are no enclosing
67 /// operation, the execution continues without stopping.
68 /// - Rerun: The action gets executed again immediately after it finishes.
69 enum Control {
70 Apply = 1,
71 Skip = 2,
72 Step = 3,
73 Next = 4,
74 Finish = 5,
76 };
77
78 /// The type of the callback that is used to control the execution.
79 /// The callback is passed the current action.
81
82 /// Create an ExecutionContext with a callback that is used to control the
83 /// execution.
84 ExecutionContext(CallbackTy callback) { setCallback(callback); }
85 ExecutionContext() = default;
86
87 /// Set the callback that is used to control the execution.
88 void setCallback(CallbackTy callback) {
89 onBreakpointControlExecutionCallback = callback;
90 }
91
92 /// This abstract class defines the interface used to observe an Action
93 /// execution. It allows to be notified before and after the callback is
94 /// processed, but can't affect the execution.
95 struct Observer {
96 virtual ~Observer() = default;
97 /// This method is called before the Action is executed
98 /// If a breakpoint was hit, it is passed as an argument to the callback.
99 /// The `willExecute` argument indicates whether the action will be executed
100 /// or not.
101 /// Note that this method will be called from multiple threads concurrently
102 /// when MLIR multi-threading is enabled.
103 virtual void beforeExecute(const ActionActiveStack *action,
104 Breakpoint *breakpoint, bool willExecute) {}
105
106 /// This method is called after the Action is executed, if it was executed.
107 /// It is not called if the action is skipped.
108 /// Note that this method will be called from multiple threads concurrently
109 /// when MLIR multi-threading is enabled.
110 virtual void afterExecute(const ActionActiveStack *action) {}
111 };
112
113 /// Register a new `Observer` on this context. It'll be notified before and
114 /// after executing an action. Note that this method is not thread-safe: it
115 /// isn't supported to add a new observer while actions may be executed.
116 void registerObserver(Observer *observer);
117
118 /// Register a new `BreakpointManager` on this context. It'll have a chance to
119 /// match an action before it gets executed. Note that this method is not
120 /// thread-safe: it isn't supported to add a new manager while actions may be
121 /// executed.
123 breakpoints.push_back(manager);
124 }
125
126 /// Process the given action. This is the operator called by MLIRContext on
127 /// `executeAction()`.
128 void operator()(function_ref<void()> transform, const Action &action);
129
130private:
131 /// Callback that is executed when a breakpoint is hit and allows the client
132 /// to control the execution.
133 CallbackTy onBreakpointControlExecutionCallback;
134
135 /// Next point to stop execution as describe by `Control` enum.
136 /// This is handle by indicating at which levels of depth the next
137 /// break should happen.
138 std::optional<int> depthToBreak;
139
140 /// Observers that are notified before and after the callback is executed.
141 SmallVector<Observer *> observers;
142
143 /// The list of managers that are queried for breakpoints.
145
146 /// Stack of depths of actions that should be rerun.
147 SmallVector<int> rerunControlStack;
148};
149
150} // namespace tracing
151} // namespace mlir
152
153#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:147
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
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...