//===-- 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 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; /// 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 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