MLIR 23.0.0git
MemorySlotInterfaces.cpp
Go to the documentation of this file.
1//===-- MemorySlotInterfaces.cpp - MemorySlot interfaces --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "llvm/ADT/SmallVector.h"
12
13#include "mlir/Interfaces/MemorySlotOpInterfaces.cpp.inc"
14#include "mlir/Interfaces/MemorySlotTypeInterfaces.cpp.inc"
15
16using namespace mlir;
17
18/// Returns the slot describing `aliasPtr`: `rootSlot` if it is the root,
19/// the entry in `aliasMap` if it's a known alias, or `nullopt` otherwise.
20static std::optional<MemorySlot>
21getParentSlot(Value aliasPtr, const MemorySlot &rootSlot,
22 const PromotableAliasMap &aliasMap) {
23 if (aliasPtr == rootSlot.ptr)
24 return rootSlot;
25 auto it = aliasMap.find(aliasPtr);
26 if (it == aliasMap.end())
27 return std::nullopt;
28 return it->second.slot;
29}
30
31void mlir::populatePromotableAliasMap(PromotableAliaserInterface aliaser,
32 const MemorySlot &rootSlot,
33 PromotableAliasMap &aliasMap) {
34 for (OpOperand &operand : aliaser->getOpOperands()) {
35 std::optional<MemorySlot> parentSlot =
36 getParentSlot(operand.get(), rootSlot, aliasMap);
37 if (!parentSlot)
38 continue;
40 aliaser.getPromotableSlotAliases(operand, *parentSlot, newSlots);
41 for (const MemorySlot &alias : newSlots)
42 aliasMap.try_emplace(alias.ptr, PromotableSlotAliasInfo{alias, &operand});
43 }
44}
45
46std::optional<MemorySlot>
48 const PromotableAliasMap &aliasMap) {
49 for (Value operand : op->getOperands())
50 if (std::optional<MemorySlot> slot =
51 getParentSlot(operand, rootSlot, aliasMap))
52 return slot;
53 return std::nullopt;
54}
55
57 const MemorySlot &rootSlot,
58 const PromotableAliasMap &aliasMap) {
59 Value uniqueAliasPtr;
60 for (Value operand : op->getOperands()) {
61 std::optional<MemorySlot> slot = getParentSlot(operand, rootSlot, aliasMap);
62 if (!slot)
63 continue;
64 if (uniqueAliasPtr && uniqueAliasPtr != slot->ptr)
65 return false;
66 uniqueAliasPtr = slot->ptr;
67 }
68 return true;
69}
70
71namespace {
72/// A step in an alias chain, from leaf to root. `parentSlot` is one step
73/// closer to the root; `aliasSlot` is the slot exposed at this step.
74struct ChainStep {
75 PromotableAliaserInterface aliaser;
76 OpOperand *aliasedSlotPointerOperand;
77 MemorySlot parentSlot;
78 MemorySlot aliasSlot;
79};
80} // namespace
81
82/// Walks from `aliasSlot` back to `rootSlot` via `aliasMap`. Returns the
83/// leaf-to-root chain, or `nullopt` if `aliasSlot` is not a known alias.
84static std::optional<SmallVector<ChainStep>>
85buildAliasChain(const MemorySlot &aliasSlot, const MemorySlot &rootSlot,
86 const PromotableAliasMap &aliasMap) {
88 Value current = aliasSlot.ptr;
89 while (current != rootSlot.ptr) {
90 auto it = aliasMap.find(current);
91 if (it == aliasMap.end())
92 return std::nullopt;
93 OpOperand *operand = it->second.aliasedSlotPointerOperand;
94 auto aliaser = cast<PromotableAliaserInterface>(operand->getOwner());
95 std::optional<MemorySlot> parent =
96 getParentSlot(operand->get(), rootSlot, aliasMap);
97 if (!parent)
98 return std::nullopt;
99 chain.push_back(ChainStep{aliaser, operand, *parent, it->second.slot});
100 current = operand->get();
101 }
102 return chain;
103}
104
106 const MemorySlot &aliasSlot,
107 const MemorySlot &rootSlot,
108 const PromotableAliasMap &aliasMap,
109 OpBuilder &builder) {
110 std::optional<SmallVector<ChainStep>> chain =
111 buildAliasChain(aliasSlot, rootSlot, aliasMap);
112 if (!chain)
113 return {};
114 Value current = slotValue;
115 // Root-to-leaf walk: reverse the leaf-first chain.
116 for (ChainStep &step : llvm::reverse(*chain)) {
117 current = step.aliaser.projectSlotValueToAliasValue(
118 *step.aliasedSlotPointerOperand, step.parentSlot, step.aliasSlot,
119 current, builder);
120 if (!current)
121 return {};
122 }
123 return current;
124}
125
127 const MemorySlot &aliasSlot,
128 Value rootReachingDef,
129 const MemorySlot &rootSlot,
130 const PromotableAliasMap &aliasMap,
131 OpBuilder &builder) {
132 std::optional<SmallVector<ChainStep>> chainOpt =
133 buildAliasChain(aliasSlot, rootSlot, aliasMap);
134 if (!chainOpt)
135 return {};
136 SmallVector<ChainStep> &chain = *chainOpt;
137
138 // Project `rootReachingDef` down to each step's parent level so the
139 // per-step projector can use it (needed for partial sub-aliases; full
140 // aliases ignore it). The chain is leaf-first, so `chain.back()` is the
141 // root-most step (parent = rootSlot) and `chain.front()` is the leaf.
142 SmallVector<Value> perStepReachingDef(chain.size());
143 Value current = rootReachingDef;
144 for (int i = static_cast<int>(chain.size()) - 1; i >= 0; --i) {
145 perStepReachingDef[i] = current;
146 current = chain[i].aliaser.projectSlotValueToAliasValue(
147 *chain[i].aliasedSlotPointerOperand, chain[i].parentSlot,
148 chain[i].aliasSlot, current, builder);
149 if (!current)
150 return {};
151 }
152
153 // Walk leaf-to-root, combining `aliasValue` with the projected reaching
154 // definition at each step.
155 current = aliasValue;
156 for (size_t i = 0; i < chain.size(); ++i) {
157 current = chain[i].aliaser.projectAliasValueToSlotValue(
158 *chain[i].aliasedSlotPointerOperand, chain[i].parentSlot,
159 chain[i].aliasSlot, current, perStepReachingDef[i], builder);
160 if (!current)
161 return {};
162 }
163 return current;
164}
static std::optional< MemorySlot > getParentSlot(Value aliasPtr, const MemorySlot &rootSlot, const PromotableAliasMap &aliasMap)
Returns the slot describing aliasPtr: rootSlot if it is the root, the entry in aliasMap if it's a kno...
static std::optional< SmallVector< ChainStep > > buildAliasChain(const MemorySlot &aliasSlot, const MemorySlot &rootSlot, const PromotableAliasMap &aliasMap)
Walks from aliasSlot back to rootSlot via aliasMap.
IRValueT get() const
Return the current value being used by this operand.
This class helps build Operations.
Definition Builders.h:209
This class represents an operand of an operation.
Definition Value.h:254
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
operand_range getOperands()
Returns an iterator on the underlying Value's.
Definition Operation.h:403
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Operation * getOwner() const
Return the owner of this operand.
Definition UseDefLists.h:38
Include the generated interface declarations.
bool referencesAtMostOneAliasOfSlot(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 its...
Value convertSlotValueToAliasValue(Value slotValue, const MemorySlot &aliasSlot, const MemorySlot &rootSlot, const PromotableAliasMap &aliasMap, OpBuilder &builder)
Walks the alias chain from rootSlot down to aliasSlot.
void populatePromotableAliasMap(PromotableAliaserInterface aliaser, const MemorySlot &rootSlot, PromotableAliasMap &aliasMap)
Populates aliasMap with alias entries produced by aliaser for operands that already alias rootSlot.
Value convertAliasValueToSlotValue(Value aliasValue, const MemorySlot &aliasSlot, Value rootReachingDef, const MemorySlot &rootSlot, const PromotableAliasMap &aliasMap, OpBuilder &builder)
Walks the alias chain from aliasSlot back up to rootSlot.
llvm::SmallDenseMap< Value, PromotableSlotAliasInfo, 4 > PromotableAliasMap
Maps an alias slot pointer (a result of a PromotableAliaserInterface op) reachable from a root slot t...
std::optional< MemorySlot > getOpAliasSlot(Operation *op, const MemorySlot &rootSlot, const PromotableAliasMap &aliasMap)
Returns a MemorySlot for the operand of op that aliases rootSlot.ptr (either the root itself or a kno...
Represents a slot in memory.
Value ptr
Pointer to the memory slot, used by operations to refer to it.
An entry in a PromotableAliasMap: the memory slot defined by an aliaser operation and its source oper...