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