brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · f311d6d Raw
122 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "mlir/Debug/ExecutionContext.h"10 11#include "llvm/ADT/ScopeExit.h"12#include "llvm/Support/FormatVariadic.h"13 14using namespace mlir;15using namespace mlir::tracing;16 17//===----------------------------------------------------------------------===//18// ActionActiveStack19//===----------------------------------------------------------------------===//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// ExecutionContext47//===----------------------------------------------------------------------===//48 49static const LLVM_THREAD_LOCAL ActionActiveStack *actionStack = nullptr;50 51void ExecutionContext::registerObserver(Observer *observer) {52  observers.push_back(observer);53}54 55void ExecutionContext::operator()(llvm::function_ref<void()> transform,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) {72    case ExecutionContext::Apply:73      depthToBreak = std::nullopt;74      return true;75    case ExecutionContext::Skip:76      depthToBreak = std::nullopt;77      return false;78    case ExecutionContext::Step:79      depthToBreak = depth + 1;80      return true;81    case ExecutionContext::Next:82      depthToBreak = depth;83      return true;84    case ExecutionContext::Finish: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 the102  // 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}122