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