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 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 Operation *owner = cast<OpResult>().getOwner(); 106 if (owner->hasSingleResult) 107 return owner->dropAllUses(); 108 return owner->dropAllUses(*this); 109 } 110 111 /// Replace all uses of 'this' value with the new value, updating anything in 112 /// the IR that uses 'this' to use the other value instead. When this returns 113 /// there are zero uses of 'this'. 114 void Value::replaceAllUsesWith(Value newValue) const { 115 if (BlockArgument arg = dyn_cast<BlockArgument>()) 116 return arg.getImpl()->replaceAllUsesWith(newValue); 117 Operation *owner = cast<OpResult>().getOwner(); 118 IRMultiObjectWithUseList<OpOperand> *useList = owner; 119 if (owner->hasSingleResult) 120 return useList->replaceAllUsesWith(newValue); 121 useList->replaceAllUsesWith(*this, newValue); 122 } 123 124 //===--------------------------------------------------------------------===// 125 // Uses 126 127 auto Value::use_begin() const -> use_iterator { 128 if (BlockArgument arg = dyn_cast<BlockArgument>()) 129 return arg.getImpl()->use_begin(); 130 Operation *owner = cast<OpResult>().getOwner(); 131 return owner->hasSingleResult ? use_iterator(owner->use_begin()) 132 : owner->use_begin(*this); 133 } 134 135 /// Returns true if this value has exactly one use. 136 bool Value::hasOneUse() const { 137 if (BlockArgument arg = dyn_cast<BlockArgument>()) 138 return arg.getImpl()->hasOneUse(); 139 Operation *owner = cast<OpResult>().getOwner(); 140 return owner->hasSingleResult ? owner->hasOneUse() : owner->hasOneUse(*this); 141 } 142 143 /// Returns true if this value has no uses. 144 bool Value::use_empty() const { 145 if (BlockArgument arg = dyn_cast<BlockArgument>()) 146 return arg.getImpl()->use_empty(); 147 Operation *owner = cast<OpResult>().getOwner(); 148 return owner->hasSingleResult ? owner->use_empty() : owner->use_empty(*this); 149 } 150 151 //===----------------------------------------------------------------------===// 152 // OpResult 153 //===----------------------------------------------------------------------===// 154 155 /// Returns the operation that owns this result. 156 Operation *OpResult::getOwner() const { 157 // If the result is in-place, the `owner` is the operation. 158 if (LLVM_LIKELY(getKind() != Kind::TrailingOpResult)) 159 return reinterpret_cast<Operation *>(ownerAndKind.getPointer()); 160 161 // Otherwise, we need to do some arithmetic to get the operation pointer. 162 // Move the trailing owner to the start of the array. 163 auto *trailingIt = 164 static_cast<detail::TrailingOpResult *>(ownerAndKind.getPointer()); 165 trailingIt -= trailingIt->trailingResultNumber; 166 167 // This point is the first trailing object after the operation. So all we need 168 // to do here is adjust for the operation size. 169 return reinterpret_cast<Operation *>(trailingIt) - 1; 170 } 171 172 /// Return the result number of this result. 173 unsigned OpResult::getResultNumber() const { 174 // If the result is in-place, we can use the kind directly. 175 if (LLVM_LIKELY(getKind() != Kind::TrailingOpResult)) 176 return static_cast<unsigned>(ownerAndKind.getInt()); 177 // Otherwise, we add the number of inline results to the trailing owner. 178 auto *trailingIt = 179 static_cast<detail::TrailingOpResult *>(ownerAndKind.getPointer()); 180 unsigned trailingNumber = trailingIt->trailingResultNumber; 181 return trailingNumber + static_cast<unsigned>(Kind::TrailingOpResult); 182 } 183 184 /// Given a number of operation results, returns the number that need to be 185 /// stored as trailing. 186 unsigned OpResult::getNumTrailing(unsigned numResults) { 187 // If we can pack all of the results, there is no need for additional storage. 188 if (numResults <= static_cast<unsigned>(Kind::TrailingOpResult)) 189 return 0; 190 return numResults - static_cast<unsigned>(Kind::TrailingOpResult); 191 } 192 193 //===----------------------------------------------------------------------===// 194 // BlockOperand 195 //===----------------------------------------------------------------------===// 196 197 /// Provide the use list that is attached to the given block. 198 IRObjectWithUseList<BlockOperand> *BlockOperand::getUseList(Block *value) { 199 return value; 200 } 201 202 /// Return which operand this is in the operand list. 203 unsigned BlockOperand::getOperandNumber() { 204 return this - &getOwner()->getBlockOperands()[0]; 205 } 206 207 //===----------------------------------------------------------------------===// 208 // OpOperand 209 //===----------------------------------------------------------------------===// 210 211 /// Provide the use list that is attached to the given value. 212 IRObjectWithUseList<OpOperand> *OpOperand::getUseList(Value value) { 213 return value.getUseList(); 214 } 215 216 /// Return the current value being used by this operand. 217 Value OpOperand::get() const { 218 return IROperand<OpOperand, detail::OpaqueValue>::get(); 219 } 220 221 /// Set the operand to the given value. 222 void OpOperand::set(Value value) { 223 IROperand<OpOperand, detail::OpaqueValue>::set(value); 224 } 225 226 /// Return which operand this is in the operand list. 227 unsigned OpOperand::getOperandNumber() { 228 return this - &getOwner()->getOpOperands()[0]; 229 } 230 231 //===----------------------------------------------------------------------===// 232 // detail::OpaqueValue 233 //===----------------------------------------------------------------------===// 234 235 /// Implicit conversion from 'Value'. 236 detail::OpaqueValue::OpaqueValue(Value value) 237 : impl(value.getAsOpaquePointer()) {} 238 239 /// Implicit conversion back to 'Value'. 240 detail::OpaqueValue::operator Value() const { 241 return Value::getFromOpaquePointer(impl); 242 } 243