llvm/mlir/include/mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h

//===- BufferDeallocationOpInterface.h --------------------------*- 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_DIALECT_BUFFERIZATION_IR_BUFFERDEALLOCATIONOPINTERFACE_H_
#define MLIR_DIALECT_BUFFERIZATION_IR_BUFFERDEALLOCATIONOPINTERFACE_H_

#include "mlir/Analysis/Liveness.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Support/LLVM.h"

namespace mlir {
namespace bufferization {

/// Compare two SSA values in a deterministic manner. Two block arguments are
/// ordered by argument number, block arguments are always less than operation
/// results, and operation results are ordered by the `isBeforeInBlock` order of
/// their defining operation.
struct ValueComparator {};

/// This class is used to track the ownership of values. The ownership can
/// either be not initialized yet ('Uninitialized' state), set to a unique SSA
/// value which indicates the ownership at runtime (or statically if it is a
/// constant value) ('Unique' state), or it cannot be represented in a single
/// SSA value ('Unknown' state). An artificial example of a case where ownership
/// cannot be represented in a single i1 SSA value could be the following:
/// `%0 = test.non_deterministic_select %arg0, %arg1 : i32`
/// Since the operation does not provide us a separate boolean indicator on
/// which of the two operands was selected, we would need to either insert an
/// alias check at runtime to determine if `%0` aliases with `%arg0` or `%arg1`,
/// or insert a `bufferization.clone` operation to get a fresh buffer which we
/// could assign ownership to.
///
/// The three states this class can represent form a lattice on a partial order:
/// forall X in SSA values. uninitialized < unique(X) < unknown
/// forall X, Y in SSA values.
///   unique(X) == unique(Y) iff X and Y always evaluate to the same value
///   unique(X) != unique(Y) otherwise
class Ownership {};

/// Options for BufferDeallocationOpInterface-based buffer deallocation.
struct DeallocationOptions {};

/// This class collects all the state that we need to perform the buffer
/// deallocation pass with associated helper functions such that we have easy
/// access to it in the BufferDeallocationOpInterface implementations and the
/// BufferDeallocation pass.
class DeallocationState {};

namespace deallocation_impl {
/// Insert a `bufferization.dealloc` operation right before `op` which has to be
/// a terminator without any successors. Note that it is not required to have
/// the ReturnLike trait attached. The MemRef values in the `operands` argument
/// will be added to the list of retained values and their updated ownership
/// values will be appended to the `updatedOperandOwnerships` list. `op` is not
/// modified in any way. Returns failure if at least one of the MemRefs to
/// deallocate does not have 'Unique' ownership (likely as a result of an
/// incorrect implementation of the `process` or
/// `materializeUniqueOwnershipForMemref` interface method) or the original
/// `op`.
FailureOr<Operation *>
insertDeallocOpForReturnLike(DeallocationState &state, Operation *op,
                             ValueRange operands,
                             SmallVectorImpl<Value> &updatedOperandOwnerships);
} // namespace deallocation_impl

} // namespace bufferization
} // namespace mlir

//===----------------------------------------------------------------------===//
// Buffer Deallocation Interface
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/Bufferization/IR/BufferDeallocationOpInterface.h.inc"

#endif // MLIR_DIALECT_BUFFERIZATION_IR_BUFFERDEALLOCATIONOPINTERFACE_H_