//======- BufferViewFlowAnalysis.cpp - Buffer alias analysis -*- 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
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/Bufferization/Transforms/BufferViewFlowAnalysis.h"

#include "mlir/Dialect/Bufferization/IR/BufferViewFlowOpInterface.h"
#include "mlir/Interfaces/CallInterfaces.h"
#include "mlir/Interfaces/ControlFlowInterfaces.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "mlir/Interfaces/ViewLikeInterface.h"
#include "llvm/ADT/SetOperations.h"

using namespace mlir;
using namespace mlir::bufferization;

//===----------------------------------------------------------------------===//
// BufferViewFlowAnalysis
//===----------------------------------------------------------------------===//

/// Constructs a new alias analysis using the op provided.
BufferViewFlowAnalysis::BufferViewFlowAnalysis(Operation *op) { build(op); }

static BufferViewFlowAnalysis::ValueSetT
resolveValues(const BufferViewFlowAnalysis::ValueMapT &map, Value value) {
  BufferViewFlowAnalysis::ValueSetT result;
  SmallVector<Value, 8> queue;
  queue.push_back(value);
  while (!queue.empty()) {
    Value currentValue = queue.pop_back_val();
    if (result.insert(currentValue).second) {
      auto it = map.find(currentValue);
      if (it != map.end()) {
        for (Value aliasValue : it->second)
          queue.push_back(aliasValue);
      }
    }
  }
  return result;
}

/// Find all immediate and indirect dependent buffers this value could
/// potentially have. Note that the resulting set will also contain the value
/// provided as it is a dependent alias of itself.
BufferViewFlowAnalysis::ValueSetT
BufferViewFlowAnalysis::resolve(Value rootValue) const {
  return resolveValues(dependencies, rootValue);
}

BufferViewFlowAnalysis::ValueSetT
BufferViewFlowAnalysis::resolveReverse(Value rootValue) const {
  return resolveValues(reverseDependencies, rootValue);
}

/// Removes the given values from all alias sets.
void BufferViewFlowAnalysis::remove(const SetVector<Value> &aliasValues) {
  for (auto &entry : dependencies)
    llvm::set_subtract(entry.second, aliasValues);
}

void BufferViewFlowAnalysis::rename(Value from, Value to) {
  dependencies[to] = dependencies[from];
  dependencies.erase(from);

  for (auto &[_, value] : dependencies) {
    if (value.contains(from)) {
      value.insert(to);
      value.erase(from);
    }
  }
}

/// This function constructs a mapping from values to its immediate
/// dependencies. It iterates over all blocks, gets their predecessors,
/// determines the values that will be passed to the corresponding block
/// arguments and inserts them into the underlying map. Furthermore, it wires
/// successor regions and branch-like return operations from nested regions.
void BufferViewFlowAnalysis::build(Operation *op) {
  // Registers all dependencies of the given values.
  auto registerDependencies = [&](ValueRange values, ValueRange dependencies) {
    for (auto [value, dep] : llvm::zip_equal(values, dependencies)) {
      this->dependencies[value].insert(dep);
      this->reverseDependencies[dep].insert(value);
    }
  };

  // Mark all buffer results and buffer region entry block arguments of the
  // given op as terminals.
  auto populateTerminalValues = [&](Operation *op) {
    for (Value v : op->getResults())
      if (isa<BaseMemRefType>(v.getType()))
        this->terminals.insert(v);
    for (Region &r : op->getRegions())
      for (BlockArgument v : r.getArguments())
        if (isa<BaseMemRefType>(v.getType()))
          this->terminals.insert(v);
  };

  op->walk([&](Operation *op) {
    // Query BufferViewFlowOpInterface. If the op does not implement that
    // interface, try to infer the dependencies from other interfaces that the
    // op may implement.
    if (auto bufferViewFlowOp = dyn_cast<BufferViewFlowOpInterface>(op)) {
      bufferViewFlowOp.populateDependencies(registerDependencies);
      for (Value v : op->getResults())
        if (isa<BaseMemRefType>(v.getType()) &&
            bufferViewFlowOp.mayBeTerminalBuffer(v))
          this->terminals.insert(v);
      for (Region &r : op->getRegions())
        for (BlockArgument v : r.getArguments())
          if (isa<BaseMemRefType>(v.getType()) &&
              bufferViewFlowOp.mayBeTerminalBuffer(v))
            this->terminals.insert(v);
      return WalkResult::advance();
    }

    // Add additional dependencies created by view changes to the alias list.
    if (auto viewInterface = dyn_cast<ViewLikeOpInterface>(op)) {
      registerDependencies(viewInterface.getViewSource(),
                           viewInterface.getViewDest());
      return WalkResult::advance();
    }

    if (auto branchInterface = dyn_cast<BranchOpInterface>(op)) {
      // Query all branch interfaces to link block argument dependencies.
      Block *parentBlock = branchInterface->getBlock();
      for (auto it = parentBlock->succ_begin(), e = parentBlock->succ_end();
           it != e; ++it) {
        // Query the branch op interface to get the successor operands.
        auto successorOperands =
            branchInterface.getSuccessorOperands(it.getIndex());
        // Build the actual mapping of values to their immediate dependencies.
        registerDependencies(successorOperands.getForwardedOperands(),
                             (*it)->getArguments().drop_front(
                                 successorOperands.getProducedOperandCount()));
      }
      return WalkResult::advance();
    }

    if (auto regionInterface = dyn_cast<RegionBranchOpInterface>(op)) {
      // Wire the successor operands with the successor inputs.
      DenseMap<OpOperand *, SmallVector<Value>> mapping;
      regionInterface.getSuccessorOperandInputMapping(mapping);
      for (const auto &[operand, inputs] : mapping)
        for (Value input : inputs)
          registerDependencies({operand->get()}, {input});
      return WalkResult::advance();
    }

    // Region terminators are handled together with RegionBranchOpInterface.
    if (isa<RegionBranchTerminatorOpInterface>(op))
      return WalkResult::advance();

    if (isa<CallOpInterface>(op)) {
      // This is an intra-function analysis. We have no information about other
      // functions. Conservatively assume that each operand may alias with each
      // result. Also mark the results are terminals because the function could
      // return newly allocated buffers.
      populateTerminalValues(op);
      for (Value operand : op->getOperands())
        for (Value result : op->getResults())
          registerDependencies({operand}, {result});
      return WalkResult::advance();
    }

    // We have no information about unknown ops.
    populateTerminalValues(op);

    return WalkResult::advance();
  });
}

bool BufferViewFlowAnalysis::mayBeTerminalBuffer(Value value) const {
  assert(isa<BaseMemRefType>(value.getType()) && "expected memref");
  return terminals.contains(value);
}

//===----------------------------------------------------------------------===//
// BufferOriginAnalysis
//===----------------------------------------------------------------------===//

/// Return "true" if the given value is the result of a memory allocation.
static bool hasAllocateSideEffect(Value v) {
  Operation *op = v.getDefiningOp();
  if (!op)
    return false;
  return hasEffect<MemoryEffects::Allocate>(op, v);
}

/// Return "true" if the given value is a function block argument.
static bool isFunctionArgument(Value v) {
  auto bbArg = dyn_cast<BlockArgument>(v);
  if (!bbArg)
    return false;
  Block *b = bbArg.getOwner();
  auto funcOp = dyn_cast<FunctionOpInterface>(b->getParentOp());
  if (!funcOp)
    return false;
  return bbArg.getOwner() == &funcOp.getFunctionBody().front();
}

/// Given a memref value, return the "base" value by skipping over all
/// ViewLikeOpInterface ops (if any) in the reverse use-def chain.
static Value getViewBase(Value value) {
  while (auto viewLikeOp = value.getDefiningOp<ViewLikeOpInterface>()) {
    if (value != viewLikeOp.getViewDest()) {
      break;
    }
    value = viewLikeOp.getViewSource();
  }
  return value;
}

BufferOriginAnalysis::BufferOriginAnalysis(Operation *op) : analysis(op) {}

std::optional<bool> BufferOriginAnalysis::isSameAllocation(Value v1, Value v2) {
  assert(isa<BaseMemRefType>(v1.getType()) && "expected buffer");
  assert(isa<BaseMemRefType>(v2.getType()) && "expected buffer");

  // Skip over all view-like ops.
  v1 = getViewBase(v1);
  v2 = getViewBase(v2);

  // Fast path: If both buffers are the same SSA value, we can be sure that
  // they originate from the same allocation.
  if (v1 == v2)
    return true;

  // Compute the SSA values from which the buffers `v1` and `v2` originate.
  SmallPtrSet<Value, 16> origin1 = analysis.resolveReverse(v1);
  SmallPtrSet<Value, 16> origin2 = analysis.resolveReverse(v2);

  // Originating buffers are "terminal" if they could not be traced back any
  // further by the `BufferViewFlowAnalysis`. Examples of terminal buffers:
  // - function block arguments
  // - values defined by allocation ops such as "memref.alloc"
  // - values defined by ops that are unknown to the buffer view flow analysis
  // - values that are marked as "terminal" in the `BufferViewFlowOpInterface`
  SmallPtrSet<Value, 16> terminal1, terminal2;

  // While gathering terminal buffers, keep track of whether all terminal
  // buffers are newly allocated buffer or function entry arguments.
  bool allAllocs1 = true, allAllocs2 = true;
  bool allAllocsOrFuncEntryArgs1 = true, allAllocsOrFuncEntryArgs2 = true;

  // Helper function that gathers terminal buffers among `origin`.
  auto gatherTerminalBuffers = [this](const SmallPtrSet<Value, 16> &origin,
                                      SmallPtrSet<Value, 16> &terminal,
                                      bool &allAllocs,
                                      bool &allAllocsOrFuncEntryArgs) {
    for (Value v : origin) {
      if (isa<BaseMemRefType>(v.getType()) && analysis.mayBeTerminalBuffer(v)) {
        terminal.insert(v);
        allAllocs &= hasAllocateSideEffect(v);
        allAllocsOrFuncEntryArgs &=
            isFunctionArgument(v) || hasAllocateSideEffect(v);
      }
    }
    assert(!terminal.empty() && "expected non-empty terminal set");
  };

  // Gather terminal buffers for `v1` and `v2`.
  gatherTerminalBuffers(origin1, terminal1, allAllocs1,
                        allAllocsOrFuncEntryArgs1);
  gatherTerminalBuffers(origin2, terminal2, allAllocs2,
                        allAllocsOrFuncEntryArgs2);

  // If both `v1` and `v2` have a single matching terminal buffer, they are
  // guaranteed to originate from the same buffer allocation.
  if (llvm::hasSingleElement(terminal1) && llvm::hasSingleElement(terminal2) &&
      *terminal1.begin() == *terminal2.begin())
    return true;

  // At least one of the two values has multiple terminals.

  // Check if there is overlap between the terminal buffers of `v1` and `v2`.
  bool distinctTerminalSets = true;
  for (Value v : terminal1)
    distinctTerminalSets &= !terminal2.contains(v);
  // If there is overlap between the terminal buffers of `v1` and `v2`, we
  // cannot make an accurate decision without further analysis.
  if (!distinctTerminalSets)
    return std::nullopt;

  // If `v1` originates from only allocs, and `v2` is guaranteed to originate
  // from different allocations (that is guaranteed if `v2` originates from
  // only distinct allocs or function entry arguments), we can be sure that
  // `v1` and `v2` originate from different allocations. The same argument can
  // be made when swapping `v1` and `v2`.
  bool isolatedAlloc1 = allAllocs1 && (allAllocs2 || allAllocsOrFuncEntryArgs2);
  bool isolatedAlloc2 = (allAllocs1 || allAllocsOrFuncEntryArgs1) && allAllocs2;
  if (isolatedAlloc1 || isolatedAlloc2)
    return false;

  // Otherwise: We do not know whether `v1` and `v2` originate from the same
  // allocation or not.
  // TODO: Function arguments are currently handled conservatively. We assume
  // that they could be the same allocation.
  // TODO: Terminals other than allocations and function arguments are
  // currently handled conservatively. We assume that they could be the same
  // allocation. E.g., we currently return "nullopt" for values that originate
  // from different "memref.get_global" ops (with different symbols).
  return std::nullopt;
}
