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