1//===- Value.h - Base of the SSA Value hierarchy ----------------*- C++ -*-===//
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// This file defines generic Value type and manipulation utilities.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef MLIR_IR_VALUE_H
14#define MLIR_IR_VALUE_H
15
16#include "mlir/IR/Types.h"
17#include "mlir/IR/UseDefLists.h"
18#include "mlir/Support/LLVM.h"
19#include "llvm/Support/PointerLikeTypeTraits.h"
20
21namespace mlir {
22class AsmState;
23class Block;
24class BlockArgument;
25class Operation;
26class OpOperand;
27class OpPrintingFlags;
28class OpResult;
29class Region;
30class Value;
31
32//===----------------------------------------------------------------------===//
33// Value
34//===----------------------------------------------------------------------===//
35
36namespace detail {
37
38/// The base class for all derived Value classes. It contains all of the
39/// components that are shared across Value classes.
40class alignas(8) ValueImpl : public IRObjectWithUseList<OpOperand> {
41public:
42 /// The enumeration represents the various different kinds of values the
43 /// internal representation may take. We use all of the bits from Type that we
44 /// can to store indices inline.
45 enum class Kind {
46 /// The first N kinds are all inline operation results. An inline operation
47 /// result means that the kind represents the result number. This removes
48 /// the need to store an additional index value. The derived class here is
49 /// an `OpResultImpl`.
50 InlineOpResult = 0,
51
52 /// The next kind represents a 'out-of-line' operation result. This is for
53 /// results with numbers larger than we can represent inline. The derived
54 /// class here is an `OpResultImpl`.
55 OutOfLineOpResult = 6,
56
57 /// The last kind represents a block argument. The derived class here is an
58 /// `BlockArgumentImpl`.
59 BlockArgument = 7
60 };
61
62 /// Return the type of this value.
63 Type getType() const { return typeAndKind.getPointer(); }
64
65 /// Set the type of this value.
66 void setType(Type type) { return typeAndKind.setPointer(type); }
67
68 /// Return the kind of this value.
69 Kind getKind() const { return typeAndKind.getInt(); }
70
71protected:
72 ValueImpl(Type type, Kind kind) : typeAndKind(type, kind) {}
73
74 /// Expose a few methods explicitly for the debugger to call for
75 /// visualization.
76#ifndef NDEBUG
77 LLVM_DUMP_METHOD Type debug_getType() const { return getType(); }
78 LLVM_DUMP_METHOD Kind debug_getKind() const { return getKind(); }
79
80#endif
81
82 /// The type of this result and the kind.
83 llvm::PointerIntPair<Type, 3, Kind> typeAndKind;
84};
85} // namespace detail
86
87/// This class represents an instance of an SSA value in the MLIR system,
88/// representing a computable value that has a type and a set of users. An SSA
89/// value is either a BlockArgument or the result of an operation. Note: This
90/// class has value-type semantics and is just a simple wrapper around a
91/// ValueImpl that is either owner by a block(in the case of a BlockArgument) or
92/// an Operation(in the case of an OpResult).
93/// As most IR constructs, this isn't const-correct, but we keep method
94/// consistent and as such method that immediately modify this Value aren't
95/// marked `const` (include modifying the Value use-list).
96class Value {
97public:
98 constexpr Value(detail::ValueImpl *impl = nullptr) : impl(impl) {}
99
100 template <typename U>
101 [[deprecated("Use isa<U>() instead")]]
102 bool isa() const {
103 return llvm::isa<U>(*this);
104 }
105
106 template <typename U>
107 [[deprecated("Use dyn_cast<U>() instead")]]
108 U dyn_cast() const {
109 return llvm::dyn_cast<U>(*this);
110 }
111
112 template <typename U>
113 [[deprecated("Use dyn_cast_or_null<U>() instead")]]
114 U dyn_cast_or_null() const {
115 return llvm::dyn_cast_or_null<U>(*this);
116 }
117
118 template <typename U>
119 [[deprecated("Use cast<U>() instead")]]
120 U cast() const {
121 return llvm::cast<U>(*this);
122 }
123
124 explicit operator bool() const { return impl; }
125 bool operator==(const Value &other) const { return impl == other.impl; }
126 bool operator!=(const Value &other) const { return !(*this == other); }
127
128 /// Return the type of this value.
129 Type getType() const { return impl->getType(); }
130
131 /// Utility to get the associated MLIRContext that this value is defined in.
132 MLIRContext *getContext() const { return getType().getContext(); }
133
134 /// Mutate the type of this Value to be of the specified type.
135 ///
136 /// Note that this is an extremely dangerous operation which can create
137 /// completely invalid IR very easily. It is strongly recommended that you
138 /// recreate IR objects with the right types instead of mutating them in
139 /// place.
140 void setType(Type newType) { impl->setType(newType); }
141
142 /// If this value is the result of an operation, return the operation that
143 /// defines it.
144 Operation *getDefiningOp() const;
145
146 /// If this value is the result of an operation of type OpTy, return the
147 /// operation that defines it.
148 template <typename OpTy>
149 OpTy getDefiningOp() const {
150 return llvm::dyn_cast_or_null<OpTy>(getDefiningOp());
151 }
152
153 /// Return the location of this value.
154 Location getLoc() const;
155 void setLoc(Location loc);
156
157 /// Return the Region in which this Value is defined.
158 Region *getParentRegion();
159
160 /// Return the Block in which this Value is defined.
161 Block *getParentBlock();
162
163 //===--------------------------------------------------------------------===//
164 // UseLists
165 //===--------------------------------------------------------------------===//
166
167 /// Drop all uses of this object from their respective owners.
168 void dropAllUses() { return impl->dropAllUses(); }
169
170 /// Replace all uses of 'this' value with the new value, updating anything in
171 /// the IR that uses 'this' to use the other value instead. When this returns
172 /// there are zero uses of 'this'.
173 void replaceAllUsesWith(Value newValue) {
174 impl->replaceAllUsesWith(newValue);
175 }
176
177 /// Replace all uses of 'this' value with 'newValue', updating anything in the
178 /// IR that uses 'this' to use the other value instead except if the user is
179 /// listed in 'exceptions' .
180 void replaceAllUsesExcept(Value newValue,
181 const SmallPtrSetImpl<Operation *> &exceptions);
182
183 /// Replace all uses of 'this' value with 'newValue', updating anything in the
184 /// IR that uses 'this' to use the other value instead except if the user is
185 /// 'exceptedUser'.
186 void replaceAllUsesExcept(Value newValue, Operation *exceptedUser);
187
188 /// Replace all uses of 'this' value with 'newValue' if the given callback
189 /// returns true.
190 void replaceUsesWithIf(Value newValue,
191 function_ref<bool(OpOperand &)> shouldReplace);
192
193 /// Returns true if the value is used outside of the given block.
194 bool isUsedOutsideOfBlock(Block *block) const;
195
196 /// Shuffle the use list order according to the provided indices. It is
197 /// responsibility of the caller to make sure that the indices map the current
198 /// use-list chain to another valid use-list chain.
199 void shuffleUseList(ArrayRef<unsigned> indices);
200
201 //===--------------------------------------------------------------------===//
202 // Uses
203
204 /// This class implements an iterator over the uses of a value.
205 using use_iterator = ValueUseIterator<OpOperand>;
206 using use_range = iterator_range<use_iterator>;
207
208 use_iterator use_begin() const { return impl->use_begin(); }
209 use_iterator use_end() const { return use_iterator(); }
210
211 /// Returns a range of all uses, which is useful for iterating over all uses.
212 use_range getUses() const { return {use_begin(), use_end()}; }
213
214 /// Returns true if this value has exactly one use.
215 bool hasOneUse() const { return impl->hasOneUse(); }
216
217 /// Returns true if this value has no uses.
218 bool use_empty() const { return impl->use_empty(); }
219
220 //===--------------------------------------------------------------------===//
221 // Users
222
223 using user_iterator = ValueUserIterator<use_iterator, OpOperand>;
224 using user_range = iterator_range<user_iterator>;
225
226 user_iterator user_begin() const { return use_begin(); }
227 user_iterator user_end() const { return use_end(); }
228 user_range getUsers() const { return {user_begin(), user_end()}; }
229
230 //===--------------------------------------------------------------------===//
231 // Utilities
232
233 void print(raw_ostream &os) const;
234 void print(raw_ostream &os, const OpPrintingFlags &flags) const;
235 void print(raw_ostream &os, AsmState &state) const;
236 void dump() const;
237
238 /// Print this value as if it were an operand.
239 void printAsOperand(raw_ostream &os, AsmState &state) const;
240 void printAsOperand(raw_ostream &os, const OpPrintingFlags &flags) const;
241
242 /// Methods for supporting PointerLikeTypeTraits.
243 void *getAsOpaquePointer() const { return impl; }
244 static Value getFromOpaquePointer(const void *pointer) {
245 return reinterpret_cast<detail::ValueImpl *>(const_cast<void *>(pointer));
246 }
247 detail::ValueImpl *getImpl() const { return impl; }
248
249 friend ::llvm::hash_code hash_value(Value arg);
250
251protected:
252 /// A pointer to the internal implementation of the value.
253 detail::ValueImpl *impl;
254};
255
256inline raw_ostream &operator<<(raw_ostream &os, Value value) {
257 value.print(os);
258 return os;
259}
260
261//===----------------------------------------------------------------------===//
262// OpOperand
263//===----------------------------------------------------------------------===//
264
265/// This class represents an operand of an operation. Instances of this class
266/// contain a reference to a specific `Value`.
267class OpOperand : public IROperand<OpOperand, Value> {
268public:
269 /// Provide the use list that is attached to the given value.
270 static IRObjectWithUseList<OpOperand> *getUseList(Value value) {
271 return value.getImpl();
272 }
273
274 /// Return which operand this is in the OpOperand list of the Operation.
275 unsigned getOperandNumber();
276
277 /// Set the current value being used by this operand.
278 void assign(Value value) { set(value); }
279
280private:
281 /// Keep the constructor private and accessible to the OperandStorage class
282 /// only to avoid hard-to-debug typo/programming mistakes.
283 friend class OperandStorage;
284 using IROperand<OpOperand, Value>::IROperand;
285};
286
287//===----------------------------------------------------------------------===//
288// BlockArgument
289//===----------------------------------------------------------------------===//
290
291namespace detail {
292/// The internal implementation of a BlockArgument.
293class BlockArgumentImpl : public ValueImpl {
294public:
295 static bool classof(const ValueImpl *value) {
296 return value->getKind() == ValueImpl::Kind::BlockArgument;
297 }
298
299private:
300 BlockArgumentImpl(Type type, Block *owner, int64_t index, Location loc)
301 : ValueImpl(type, Kind::BlockArgument), owner(owner), index(index),
302 loc(loc) {}
303
304 /// The owner of this argument.
305 Block *owner;
306
307 /// The position in the argument list.
308 int64_t index;
309
310 /// The source location of this argument.
311 Location loc;
312
313 /// Allow access to owner and constructor.
314 friend BlockArgument;
315};
316} // namespace detail
317
318/// This class represents an argument of a Block.
319class BlockArgument : public Value {
320public:
321 using Value::Value;
322
323 static bool classof(Value value) {
324 return llvm::isa<detail::BlockArgumentImpl>(Val: value.getImpl());
325 }
326
327 /// Returns the block that owns this argument.
328 Block *getOwner() const { return getImpl()->owner; }
329
330 /// Returns the number of this argument.
331 unsigned getArgNumber() const { return getImpl()->index; }
332
333 /// Return the location for this argument.
334 Location getLoc() const { return getImpl()->loc; }
335 void setLoc(Location loc) { getImpl()->loc = loc; }
336
337private:
338 /// Allocate a new argument with the given type and owner.
339 static BlockArgument create(Type type, Block *owner, int64_t index,
340 Location loc) {
341 return new detail::BlockArgumentImpl(type, owner, index, loc);
342 }
343
344 /// Destroy and deallocate this argument.
345 void destroy() { delete getImpl(); }
346
347 /// Get a raw pointer to the internal implementation.
348 detail::BlockArgumentImpl *getImpl() const {
349 return reinterpret_cast<detail::BlockArgumentImpl *>(impl);
350 }
351
352 /// Cache the position in the block argument list.
353 void setArgNumber(int64_t index) { getImpl()->index = index; }
354
355 /// Allow access to `create`, `destroy` and `setArgNumber`.
356 friend Block;
357
358 /// Allow access to 'getImpl'.
359 friend Value;
360};
361
362//===----------------------------------------------------------------------===//
363// OpResult
364//===----------------------------------------------------------------------===//
365
366namespace detail {
367/// This class provides the implementation for an operation result.
368class alignas(8) OpResultImpl : public ValueImpl {
369public:
370 using ValueImpl::ValueImpl;
371
372 static bool classof(const ValueImpl *value) {
373 return value->getKind() != ValueImpl::Kind::BlockArgument;
374 }
375
376 /// Returns the parent operation of this result.
377 Operation *getOwner() const;
378
379 /// Returns the result number of this op result.
380 unsigned getResultNumber() const;
381
382 /// Returns the next operation result at `offset` after this result. This
383 /// method is useful when indexing the result storage of an operation, given
384 /// that there is more than one kind of operation result (with the different
385 /// kinds having different sizes) and that operations are stored in reverse
386 /// order.
387 OpResultImpl *getNextResultAtOffset(intptr_t offset);
388
389 /// Returns the maximum number of results that can be stored inline.
390 static unsigned getMaxInlineResults() {
391 return static_cast<unsigned>(Kind::OutOfLineOpResult);
392 }
393};
394
395/// This class provides the implementation for an operation result whose index
396/// can be represented "inline" in the underlying ValueImpl.
397struct InlineOpResult : public OpResultImpl {
398public:
399 InlineOpResult(Type type, unsigned resultNo)
400 : OpResultImpl(type, static_cast<ValueImpl::Kind>(resultNo)) {
401 assert(resultNo < getMaxInlineResults());
402 }
403
404 /// Return the result number of this op result.
405 unsigned getResultNumber() const { return static_cast<unsigned>(getKind()); }
406
407 static bool classof(const OpResultImpl *value) {
408 return value->getKind() != ValueImpl::Kind::OutOfLineOpResult;
409 }
410};
411
412/// This class provides the implementation for an operation result whose index
413/// cannot be represented "inline", and thus requires an additional index field.
414class OutOfLineOpResult : public OpResultImpl {
415public:
416 OutOfLineOpResult(Type type, uint64_t outOfLineIndex)
417 : OpResultImpl(type, Kind::OutOfLineOpResult),
418 outOfLineIndex(outOfLineIndex) {}
419
420 static bool classof(const OpResultImpl *value) {
421 return value->getKind() == ValueImpl::Kind::OutOfLineOpResult;
422 }
423
424 /// Return the result number of this op result.
425 unsigned getResultNumber() const {
426 return outOfLineIndex + getMaxInlineResults();
427 }
428
429 /// The trailing result number, or the offset from the beginning of the
430 /// `OutOfLineOpResult` array.
431 uint64_t outOfLineIndex;
432};
433
434/// Return the result number of this op result.
435inline unsigned OpResultImpl::getResultNumber() const {
436 if (const auto *outOfLineResult = dyn_cast<OutOfLineOpResult>(Val: this))
437 return outOfLineResult->getResultNumber();
438 return cast<InlineOpResult>(Val: this)->getResultNumber();
439}
440
441/// TypedValue is a Value with a statically know type.
442/// TypedValue can be null/empty
443template <typename Ty>
444struct TypedValue : Value {
445 using Value::Value;
446
447 static bool classof(Value value) { return llvm::isa<Ty>(value.getType()); }
448
449 /// Return the known Type
450 Ty getType() const { return llvm::cast<Ty>(Value::getType()); }
451 void setType(Ty ty) { Value::setType(ty); }
452};
453
454} // namespace detail
455
456/// This is a value defined by a result of an operation.
457class OpResult : public Value {
458public:
459 using Value::Value;
460
461 static bool classof(Value value) {
462 return llvm::isa<detail::OpResultImpl>(Val: value.getImpl());
463 }
464
465 /// Returns the operation that owns this result.
466 Operation *getOwner() const { return getImpl()->getOwner(); }
467
468 /// Returns the number of this result.
469 unsigned getResultNumber() const { return getImpl()->getResultNumber(); }
470
471private:
472 /// Get a raw pointer to the internal implementation.
473 detail::OpResultImpl *getImpl() const {
474 return reinterpret_cast<detail::OpResultImpl *>(impl);
475 }
476
477 /// Given a number of operation results, returns the number that need to be
478 /// stored inline.
479 static unsigned getNumInline(unsigned numResults);
480
481 /// Given a number of operation results, returns the number that need to be
482 /// stored as trailing.
483 static unsigned getNumTrailing(unsigned numResults);
484
485 /// Allow access to constructor.
486 friend Operation;
487};
488
489/// Make Value hashable.
490inline ::llvm::hash_code hash_value(Value arg) {
491 return ::llvm::hash_value(ptr: arg.getImpl());
492}
493
494template <typename Ty, typename Value = mlir::Value>
495/// If Ty is mlir::Type this will select `Value` instead of having a wrapper
496/// around it. This helps resolve ambiguous conversion issues.
497using TypedValue = std::conditional_t<std::is_same_v<Ty, mlir::Type>,
498 mlir::Value, detail::TypedValue<Ty>>;
499
500} // namespace mlir
501
502namespace llvm {
503
504template <>
505struct DenseMapInfo<mlir::Value> {
506 static mlir::Value getEmptyKey() {
507 void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
508 return mlir::Value::getFromOpaquePointer(pointer);
509 }
510 static mlir::Value getTombstoneKey() {
511 void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
512 return mlir::Value::getFromOpaquePointer(pointer);
513 }
514 static unsigned getHashValue(mlir::Value val) {
515 return mlir::hash_value(arg: val);
516 }
517 static bool isEqual(mlir::Value lhs, mlir::Value rhs) { return lhs == rhs; }
518};
519template <>
520struct DenseMapInfo<mlir::BlockArgument> : public DenseMapInfo<mlir::Value> {
521 static mlir::BlockArgument getEmptyKey() {
522 void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
523 return reinterpret_cast<mlir::detail::BlockArgumentImpl *>(pointer);
524 }
525 static mlir::BlockArgument getTombstoneKey() {
526 void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
527 return reinterpret_cast<mlir::detail::BlockArgumentImpl *>(pointer);
528 }
529};
530template <>
531struct DenseMapInfo<mlir::OpResult> : public DenseMapInfo<mlir::Value> {
532 static mlir::OpResult getEmptyKey() {
533 void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
534 return reinterpret_cast<mlir::detail::OpResultImpl *>(pointer);
535 }
536 static mlir::OpResult getTombstoneKey() {
537 void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
538 return reinterpret_cast<mlir::detail::OpResultImpl *>(pointer);
539 }
540};
541template <typename T>
542struct DenseMapInfo<mlir::detail::TypedValue<T>>
543 : public DenseMapInfo<mlir::Value> {
544 static mlir::detail::TypedValue<T> getEmptyKey() {
545 void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
546 return reinterpret_cast<mlir::detail::ValueImpl *>(pointer);
547 }
548 static mlir::detail::TypedValue<T> getTombstoneKey() {
549 void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
550 return reinterpret_cast<mlir::detail::ValueImpl *>(pointer);
551 }
552};
553
554/// Allow stealing the low bits of a value.
555template <>
556struct PointerLikeTypeTraits<mlir::Value> {
557public:
558 static inline void *getAsVoidPointer(mlir::Value value) {
559 return const_cast<void *>(value.getAsOpaquePointer());
560 }
561 static inline mlir::Value getFromVoidPointer(void *pointer) {
562 return mlir::Value::getFromOpaquePointer(pointer);
563 }
564 enum {
565 NumLowBitsAvailable =
566 PointerLikeTypeTraits<mlir::detail::ValueImpl *>::NumLowBitsAvailable
567 };
568};
569template <>
570struct PointerLikeTypeTraits<mlir::BlockArgument>
571 : public PointerLikeTypeTraits<mlir::Value> {
572public:
573 static inline mlir::BlockArgument getFromVoidPointer(void *pointer) {
574 return reinterpret_cast<mlir::detail::BlockArgumentImpl *>(pointer);
575 }
576};
577template <>
578struct PointerLikeTypeTraits<mlir::OpResult>
579 : public PointerLikeTypeTraits<mlir::Value> {
580public:
581 static inline mlir::OpResult getFromVoidPointer(void *pointer) {
582 return reinterpret_cast<mlir::detail::OpResultImpl *>(pointer);
583 }
584};
585template <typename T>
586struct PointerLikeTypeTraits<mlir::detail::TypedValue<T>>
587 : public PointerLikeTypeTraits<mlir::Value> {
588public:
589 static inline mlir::detail::TypedValue<T> getFromVoidPointer(void *pointer) {
590 return reinterpret_cast<mlir::detail::ValueImpl *>(pointer);
591 }
592};
593
594/// Add support for llvm style casts. We provide a cast between To and From if
595/// From is mlir::Value or derives from it.
596template <typename To, typename From>
597struct CastInfo<
598 To, From,
599 std::enable_if_t<std::is_same_v<mlir::Value, std::remove_const_t<From>> ||
600 std::is_base_of_v<mlir::Value, From>>>
601 : NullableValueCastFailed<To>,
602 DefaultDoCastIfPossible<To, From, CastInfo<To, From>> {
603 /// Arguments are taken as mlir::Value here and not as `From`, because
604 /// when casting from an intermediate type of the hierarchy to one of its
605 /// children, the val.getKind() inside T::classof will use the static
606 /// getKind() of the parent instead of the non-static ValueImpl::getKind()
607 /// that returns the dynamic type. This means that T::classof would end up
608 /// comparing the static Kind of the children to the static Kind of its
609 /// parent, making it impossible to downcast from the parent to the child.
610 static inline bool isPossible(mlir::Value ty) {
611 /// Return a constant true instead of a dynamic true when casting to self or
612 /// up the hierarchy.
613 if constexpr (std::is_base_of_v<To, From>) {
614 return true;
615 } else {
616 return To::classof(ty);
617 }
618 }
619 static inline To doCast(mlir::Value value) { return To(value.getImpl()); }
620};
621
622} // namespace llvm
623
624#endif
625

source code of mlir/include/mlir/IR/Value.h