//===- UseDefAnalysis.cpp - Analysis for Transitive UseDef chains ---------===// // // 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 // //===----------------------------------------------------------------------===// // // This file implements Analysis functions specific to slicing in Function. // //===----------------------------------------------------------------------===// #include "mlir/Analysis/SliceAnalysis.h" #include "mlir/Analysis/TopologicalSortUtils.h" #include "mlir/IR/Block.h" #include "mlir/IR/Operation.h" #include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" /// /// Implements Analysis functions specific to slicing in Function. /// usingnamespacemlir; static void getForwardSliceImpl(Operation *op, SetVector<Operation *> *forwardSlice, const SliceOptions::TransitiveFilter &filter = nullptr) { … } void mlir::getForwardSlice(Operation *op, SetVector<Operation *> *forwardSlice, const ForwardSliceOptions &options) { … } void mlir::getForwardSlice(Value root, SetVector<Operation *> *forwardSlice, const SliceOptions &options) { … } static void getBackwardSliceImpl(Operation *op, SetVector<Operation *> *backwardSlice, const BackwardSliceOptions &options) { … } void mlir::getBackwardSlice(Operation *op, SetVector<Operation *> *backwardSlice, const BackwardSliceOptions &options) { … } void mlir::getBackwardSlice(Value root, SetVector<Operation *> *backwardSlice, const BackwardSliceOptions &options) { … } SetVector<Operation *> mlir::getSlice(Operation *op, const BackwardSliceOptions &backwardSliceOptions, const ForwardSliceOptions &forwardSliceOptions) { … } /// Returns true if `value` (transitively) depends on iteration-carried values /// of the given `ancestorOp`. static bool dependsOnCarriedVals(Value value, ArrayRef<BlockArgument> iterCarriedArgs, Operation *ancestorOp) { … } /// Utility to match a generic reduction given a list of iteration-carried /// arguments, `iterCarriedArgs` and the position of the potential reduction /// argument within the list, `redPos`. If a reduction is matched, returns the /// reduced value and the topologically-sorted list of combiner operations /// involved in the reduction. Otherwise, returns a null value. /// /// The matching algorithm relies on the following invariants, which are subject /// to change: /// 1. The first combiner operation must be a binary operation with the /// iteration-carried value and the reduced value as operands. /// 2. The iteration-carried value and combiner operations must be side /// effect-free, have single result and a single use. /// 3. Combiner operations must be immediately nested in the region op /// performing the reduction. /// 4. Reduction def-use chain must end in a terminator op that yields the /// next iteration/output values in the same order as the iteration-carried /// values in `iterCarriedArgs`. /// 5. `iterCarriedArgs` must contain all the iteration-carried/output values /// of the region op performing the reduction. /// /// This utility is generic enough to detect reductions involving multiple /// combiner operations (disabled for now) across multiple dialects, including /// Linalg, Affine and SCF. For the sake of genericity, it does not return /// specific enum values for the combiner operations since its goal is also /// matching reductions without pre-defined semantics in core MLIR. It's up to /// each client to make sense out of the list of combiner operations. It's also /// up to each client to check for additional invariants on the expected /// reductions not covered by this generic matching. Value mlir::matchReduction(ArrayRef<BlockArgument> iterCarriedArgs, unsigned redPos, SmallVectorImpl<Operation *> &combinerOps) { … }