Files
gps/tools/local/circt/include/mlir/Analysis/SliceWalk.h
T
2026-07-12 11:01:51 +03:00

99 lines
3.7 KiB
C++

//===- SliceWalk.h - Helpers for performing IR slice walks ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_ANALYSIS_SLICEWALK_H
#define MLIR_ANALYSIS_SLICEWALK_H
#include "mlir/IR/ValueRange.h"
namespace mlir {
/// A class to signal how to proceed with the walk of the backward slice:
/// - Interrupt: Stops the walk.
/// - AdvanceTo: Continues the walk to user-specified values.
/// - Skip: Continues the walk, but skips the predecessors of the current value.
class WalkContinuation {
public:
enum class WalkAction {
/// Stops the walk.
Interrupt,
/// Continues the walk to user-specified values.
AdvanceTo,
/// Continues the walk, but skips the predecessors of the current value.
Skip
};
WalkContinuation(WalkAction action, mlir::ValueRange nextValues)
: action(action), nextValues(nextValues) {}
/// Allows diagnostics to interrupt the walk.
explicit WalkContinuation(mlir::Diagnostic &&)
: action(WalkAction::Interrupt) {}
/// Allows diagnostics to interrupt the walk.
explicit WalkContinuation(mlir::InFlightDiagnostic &&)
: action(WalkAction::Interrupt) {}
/// Creates a continuation that interrupts the walk.
static WalkContinuation interrupt() {
return WalkContinuation(WalkAction::Interrupt, {});
}
/// Creates a continuation that adds the user-specified `nextValues` to the
/// work list and advances the walk.
static WalkContinuation advanceTo(mlir::ValueRange nextValues) {
return WalkContinuation(WalkAction::AdvanceTo, nextValues);
}
/// Creates a continuation that advances the walk without adding any
/// predecessor values to the work list.
static WalkContinuation skip() {
return WalkContinuation(WalkAction::Skip, {});
}
/// Returns true if the walk was interrupted.
bool wasInterrupted() const { return action == WalkAction::Interrupt; }
/// Returns true if the walk was skipped.
bool wasSkipped() const { return action == WalkAction::Skip; }
/// Returns true if the walk was advanced to user-specified values.
bool wasAdvancedTo() const { return action == WalkAction::AdvanceTo; }
/// Returns the next values to continue the walk with.
mlir::ArrayRef<mlir::Value> getNextValues() const { return nextValues; }
private:
WalkAction action;
/// The next values to continue the walk with.
mlir::SmallVector<mlir::Value> nextValues;
};
/// A callback that is invoked for each value encountered during the walk of the
/// slice. The callback takes the current value, and returns the walk
/// continuation, which determines if the walk should proceed and if yes, with
/// which values.
using WalkCallback = mlir::function_ref<WalkContinuation(mlir::Value)>;
/// Walks the slice starting from the `rootValues` using a depth-first
/// traversal. The walk calls the provided `walkCallback` for each value
/// encountered in the slice and uses the returned walk continuation to
/// determine how to proceed.
WalkContinuation walkSlice(mlir::ValueRange rootValues,
WalkCallback walkCallback);
/// Computes a vector of all control predecessors of `value`. Relies on
/// RegionBranchOpInterface, BranchOpInterface, and SelectLikeOpInterface to
/// determine predecessors. Returns nullopt if `value` has no predecessors or
/// when the relevant operations are missing the interface implementations.
std::optional<SmallVector<Value>> getControlFlowPredecessors(Value value);
} // namespace mlir
#endif // MLIR_ANALYSIS_SLICEWALK_H