xref: /llvm-project-15.0.7/mlir/lib/IR/Value.cpp (revision d94af364)
1 //===- Value.cpp - MLIR Value Classes -------------------------------------===//
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 
9 #include "mlir/IR/Value.h"
10 #include "mlir/IR/Block.h"
11 #include "mlir/IR/Operation.h"
12 #include "mlir/IR/StandardTypes.h"
13 #include "llvm/ADT/SmallPtrSet.h"
14 using namespace mlir;
15 
16 /// Construct a value.
17 Value::Value(detail::BlockArgumentImpl *impl)
18     : ownerAndKind(impl, Kind::BlockArgument) {}
19 Value::Value(Operation *op, unsigned resultNo) {
20   assert(op->getNumResults() > resultNo && "invalid result number");
21   if (LLVM_LIKELY(canPackResultInline(resultNo))) {
22     ownerAndKind = {op, static_cast<Kind>(resultNo)};
23     return;
24   }
25 
26   // If we can't pack the result directly, we need to represent this as a
27   // trailing result.
28   unsigned trailingResultNo =
29       resultNo - static_cast<unsigned>(Kind::TrailingOpResult);
30   ownerAndKind = {op->getTrailingResult(trailingResultNo),
31                   Kind::TrailingOpResult};
32 }
33 
34 /// Return the type of this value.
35 Type Value::getType() const {
36   if (BlockArgument arg = dyn_cast<BlockArgument>())
37     return arg.getType();
38 
39   // If this is an operation result, query the parent operation.
40   OpResult result = cast<OpResult>();
41   Operation *owner = result.getOwner();
42   if (owner->hasSingleResult)
43     return owner->resultType;
44   return owner->resultType.cast<TupleType>().getType(result.getResultNumber());
45 }
46 
47 /// Mutate the type of this Value to be of the specified type.
48 void Value::setType(Type newType) {
49   if (BlockArgument arg = dyn_cast<BlockArgument>())
50     return arg.setType(newType);
51   OpResult result = cast<OpResult>();
52 
53   // If the owner has a single result, simply update it directly.
54   Operation *owner = result.getOwner();
55   if (owner->hasSingleResult) {
56     owner->resultType = newType;
57     return;
58   }
59   unsigned resultNo = result.getResultNumber();
60 
61   // Otherwise, rebuild the tuple if the new type is different from the current.
62   auto curTypes = owner->resultType.cast<TupleType>().getTypes();
63   if (curTypes[resultNo] == newType)
64     return;
65   auto newTypes = llvm::to_vector<4>(curTypes);
66   newTypes[resultNo] = newType;
67   owner->resultType = TupleType::get(newTypes, newType.getContext());
68 }
69 
70 /// If this value is the result of an Operation, return the operation that
71 /// defines it.
72 Operation *Value::getDefiningOp() const {
73   if (auto result = dyn_cast<OpResult>())
74     return result.getOwner();
75   return nullptr;
76 }
77 
78 Location Value::getLoc() const {
79   if (auto *op = getDefiningOp())
80     return op->getLoc();
81   return UnknownLoc::get(getContext());
82 }
83 
84 /// Return the Region in which this Value is defined.
85 Region *Value::getParentRegion() {
86   if (auto *op = getDefiningOp())
87     return op->getParentRegion();
88   return cast<BlockArgument>().getOwner()->getParent();
89 }
90 
91 //===----------------------------------------------------------------------===//
92 // Value::UseLists
93 //===----------------------------------------------------------------------===//
94 
95 /// Provide the use list that is attached to this value.
96 IRObjectWithUseList<OpOperand> *Value::getUseList() const {
97   if (BlockArgument arg = dyn_cast<BlockArgument>())
98     return arg.getImpl();
99   return cast<OpResult>().getOwner();
100 }
101 
102 /// Drop all uses of this object from their respective owners.
103 void Value::dropAllUses() const {
104   if (BlockArgument arg = dyn_cast<BlockArgument>())
105     return arg.getImpl()->dropAllUses();
106   Operation *owner = cast<OpResult>().getOwner();
107   if (owner->hasSingleResult)
108     return owner->dropAllUses();
109   return owner->dropAllUses(*this);
110 }
111 
112 /// Replace all uses of 'this' value with the new value, updating anything in
113 /// the IR that uses 'this' to use the other value instead.  When this returns
114 /// there are zero uses of 'this'.
115 void Value::replaceAllUsesWith(Value newValue) const {
116   if (BlockArgument arg = dyn_cast<BlockArgument>())
117     return arg.getImpl()->replaceAllUsesWith(newValue);
118   Operation *owner = cast<OpResult>().getOwner();
119   IRMultiObjectWithUseList<OpOperand> *useList = owner;
120   if (owner->hasSingleResult)
121     return useList->replaceAllUsesWith(newValue);
122   useList->replaceAllUsesWith(*this, newValue);
123 }
124 
125 /// Replace all uses of 'this' value with the new value, updating anything in
126 /// the IR that uses 'this' to use the other value instead except if the user is
127 /// listed in 'exceptions' .
128 void Value::replaceAllUsesExcept(
129     Value newValue, const SmallPtrSetImpl<Operation *> &exceptions) const {
130   for (auto &use : llvm::make_early_inc_range(getUses())) {
131     if (exceptions.count(use.getOwner()) == 0)
132       use.set(newValue);
133   }
134 }
135 
136 //===--------------------------------------------------------------------===//
137 // Uses
138 
139 auto Value::use_begin() const -> use_iterator {
140   if (BlockArgument arg = dyn_cast<BlockArgument>())
141     return arg.getImpl()->use_begin();
142   Operation *owner = cast<OpResult>().getOwner();
143   return owner->hasSingleResult ? use_iterator(owner->use_begin())
144                                 : owner->use_begin(*this);
145 }
146 
147 /// Returns true if this value has exactly one use.
148 bool Value::hasOneUse() const {
149   if (BlockArgument arg = dyn_cast<BlockArgument>())
150     return arg.getImpl()->hasOneUse();
151   Operation *owner = cast<OpResult>().getOwner();
152   return owner->hasSingleResult ? owner->hasOneUse() : owner->hasOneUse(*this);
153 }
154 
155 /// Returns true if this value has no uses.
156 bool Value::use_empty() const {
157   if (BlockArgument arg = dyn_cast<BlockArgument>())
158     return arg.getImpl()->use_empty();
159   Operation *owner = cast<OpResult>().getOwner();
160   return owner->hasSingleResult ? owner->use_empty() : owner->use_empty(*this);
161 }
162 
163 //===----------------------------------------------------------------------===//
164 // OpResult
165 //===----------------------------------------------------------------------===//
166 
167 /// Returns the operation that owns this result.
168 Operation *OpResult::getOwner() const {
169   // If the result is in-place, the `owner` is the operation.
170   if (LLVM_LIKELY(getKind() != Kind::TrailingOpResult))
171     return reinterpret_cast<Operation *>(ownerAndKind.getPointer());
172 
173   // Otherwise, we need to do some arithmetic to get the operation pointer.
174   // Move the trailing owner to the start of the array.
175   auto *trailingIt =
176       static_cast<detail::TrailingOpResult *>(ownerAndKind.getPointer());
177   trailingIt -= trailingIt->trailingResultNumber;
178 
179   // This point is the first trailing object after the operation. So all we need
180   // to do here is adjust for the operation size.
181   return reinterpret_cast<Operation *>(trailingIt) - 1;
182 }
183 
184 /// Return the result number of this result.
185 unsigned OpResult::getResultNumber() const {
186   // If the result is in-place, we can use the kind directly.
187   if (LLVM_LIKELY(getKind() != Kind::TrailingOpResult))
188     return static_cast<unsigned>(ownerAndKind.getInt());
189   // Otherwise, we add the number of inline results to the trailing owner.
190   auto *trailingIt =
191       static_cast<detail::TrailingOpResult *>(ownerAndKind.getPointer());
192   unsigned trailingNumber = trailingIt->trailingResultNumber;
193   return trailingNumber + static_cast<unsigned>(Kind::TrailingOpResult);
194 }
195 
196 /// Given a number of operation results, returns the number that need to be
197 /// stored as trailing.
198 unsigned OpResult::getNumTrailing(unsigned numResults) {
199   // If we can pack all of the results, there is no need for additional storage.
200   if (numResults <= static_cast<unsigned>(Kind::TrailingOpResult))
201     return 0;
202   return numResults - static_cast<unsigned>(Kind::TrailingOpResult);
203 }
204 
205 //===----------------------------------------------------------------------===//
206 // BlockOperand
207 //===----------------------------------------------------------------------===//
208 
209 /// Provide the use list that is attached to the given block.
210 IRObjectWithUseList<BlockOperand> *BlockOperand::getUseList(Block *value) {
211   return value;
212 }
213 
214 /// Return which operand this is in the operand list.
215 unsigned BlockOperand::getOperandNumber() {
216   return this - &getOwner()->getBlockOperands()[0];
217 }
218 
219 //===----------------------------------------------------------------------===//
220 // OpOperand
221 //===----------------------------------------------------------------------===//
222 
223 /// Provide the use list that is attached to the given value.
224 IRObjectWithUseList<OpOperand> *OpOperand::getUseList(Value value) {
225   return value.getUseList();
226 }
227 
228 /// Return the current value being used by this operand.
229 Value OpOperand::get() const {
230   return IROperand<OpOperand, detail::OpaqueValue>::get();
231 }
232 
233 /// Set the operand to the given value.
234 void OpOperand::set(Value value) {
235   IROperand<OpOperand, detail::OpaqueValue>::set(value);
236 }
237 
238 /// Return which operand this is in the operand list.
239 unsigned OpOperand::getOperandNumber() {
240   return this - &getOwner()->getOpOperands()[0];
241 }
242 
243 //===----------------------------------------------------------------------===//
244 // detail::OpaqueValue
245 //===----------------------------------------------------------------------===//
246 
247 /// Implicit conversion from 'Value'.
248 detail::OpaqueValue::OpaqueValue(Value value)
249     : impl(value.getAsOpaquePointer()) {}
250 
251 /// Implicit conversion back to 'Value'.
252 detail::OpaqueValue::operator Value() const {
253   return Value::getFromOpaquePointer(impl);
254 }
255