115 lines
4.9 KiB
C++
115 lines
4.9 KiB
C++
//===-- Mem2RegInterfaces.h - Mem2Reg interfaces ----------------*- 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_INTERFACES_MEMORYSLOTINTERFACES_H
|
|
#define MLIR_INTERFACES_MEMORYSLOTINTERFACES_H
|
|
|
|
#include "mlir/IR/Dominance.h"
|
|
#include "mlir/IR/OpDefinition.h"
|
|
#include "mlir/IR/PatternMatch.h"
|
|
|
|
#include "llvm/ADT/DenseMap.h"
|
|
|
|
namespace mlir {
|
|
|
|
/// Represents a slot in memory. This is generated by an allocating operation
|
|
/// (for example alloca).
|
|
struct MemorySlot {
|
|
/// Pointer to the memory slot, used by operations to refer to it.
|
|
Value ptr;
|
|
/// Type of the value contained in the slot.
|
|
Type elemType;
|
|
};
|
|
|
|
/// Memory slot attached with information about its destructuring procedure.
|
|
struct DestructurableMemorySlot : public MemorySlot {
|
|
/// Maps an index within the memory slot to the corresponding subelement type.
|
|
DenseMap<Attribute, Type> subelementTypes;
|
|
};
|
|
|
|
/// Returned by operation promotion logic requesting the deletion of an
|
|
/// operation.
|
|
enum class DeletionKind {
|
|
/// Keep the operation after promotion.
|
|
Keep,
|
|
/// Delete the operation after promotion.
|
|
Delete,
|
|
};
|
|
|
|
} // namespace mlir
|
|
|
|
#include "mlir/Interfaces/MemorySlotOpInterfaces.h.inc"
|
|
#include "mlir/Interfaces/MemorySlotTypeInterfaces.h.inc"
|
|
|
|
namespace mlir {
|
|
|
|
/// An entry in a `PromotableAliasMap`: the memory slot defined by an aliaser
|
|
/// operation and its source operand.
|
|
struct PromotableSlotAliasInfo {
|
|
/// The slot defined by the aliaser (its `ptr` is the map key).
|
|
MemorySlot slot;
|
|
/// The aliaser operand whose value is the parent slot's pointer.
|
|
OpOperand *aliasedSlotPointerOperand;
|
|
};
|
|
|
|
/// Maps an alias slot pointer (a result of a `PromotableAliaserInterface` op)
|
|
/// reachable from a root slot to its `PromotableSlotAliasInfo`.
|
|
using PromotableAliasMap =
|
|
llvm::SmallDenseMap<Value, PromotableSlotAliasInfo, 4>;
|
|
|
|
/// Populates `aliasMap` with alias entries produced by `aliaser` for operands
|
|
/// that already alias `rootSlot`. This should be called during a forward slice
|
|
/// traversal from `rootSlot.ptr` to ensure topological ordering.
|
|
void populatePromotableAliasMap(PromotableAliaserInterface aliaser,
|
|
const MemorySlot &rootSlot,
|
|
PromotableAliasMap &aliasMap);
|
|
|
|
/// Returns a `MemorySlot` for the operand of `op` that aliases `rootSlot.ptr`
|
|
/// (either the root itself or a known entry in `aliasMap`), providing the
|
|
/// alias's element type. Returns `nullopt` if no operand of `op` reaches
|
|
/// `rootSlot`. If `op` reaches `rootSlot` through multiple distinct aliases
|
|
/// (e.g., a memcpy between two aliases of the same root), the result is one
|
|
/// of them; use `referencesAtMostOneAliasOfSlot` to rule this out.
|
|
std::optional<MemorySlot> getOpAliasSlot(Operation *op,
|
|
const MemorySlot &rootSlot,
|
|
const PromotableAliasMap &aliasMap);
|
|
|
|
/// Returns true if `op`'s operands reach `rootSlot` through at most one
|
|
/// distinct alias pointer (the root itself or a single `aliasMap` entry).
|
|
/// Multiple operands referencing the same alias are allowed. This is used to
|
|
/// guard `PromotableMemOpInterface` calls, which assume a single slot per
|
|
/// operation.
|
|
bool referencesAtMostOneAliasOfSlot(Operation *op, const MemorySlot &rootSlot,
|
|
const PromotableAliasMap &aliasMap);
|
|
|
|
/// Walks the alias chain from `rootSlot` down to `aliasSlot`. Calls
|
|
/// `projectSlotValueToAliasValue` at each step to convert `slotValue`
|
|
/// (initially the root slot's value) to `aliasSlot`'s value. Returns a null
|
|
/// value if any projection fails.
|
|
Value convertSlotValueToAliasValue(Value slotValue, const MemorySlot &aliasSlot,
|
|
const MemorySlot &rootSlot,
|
|
const PromotableAliasMap &aliasMap,
|
|
OpBuilder &builder);
|
|
|
|
/// Walks the alias chain from `aliasSlot` back up to `rootSlot`. Calls
|
|
/// `projectAliasValueToSlotValue` at each step to convert `aliasValue`
|
|
/// (initially `aliasSlot`'s value) to the root slot's value.
|
|
/// `rootReachingDef` is the current value of the root slot; it is projected
|
|
/// down to each intermediate slot to provide the reaching definition required
|
|
/// by partial sub-aliases.
|
|
Value convertAliasValueToSlotValue(Value aliasValue,
|
|
const MemorySlot &aliasSlot,
|
|
Value rootReachingDef,
|
|
const MemorySlot &rootSlot,
|
|
const PromotableAliasMap &aliasMap,
|
|
OpBuilder &builder);
|
|
|
|
} // namespace mlir
|
|
|
|
#endif // MLIR_INTERFACES_MEMORYSLOTINTERFACES_H
|