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 
21 namespace mlir {
22 class AsmState;
23 class Block;
24 class BlockArgument;
25 class Operation;
26 class OpOperand;
27 class OpPrintingFlags;
28 class OpResult;
29 class Region;
30 class Value;
31 
32 //===----------------------------------------------------------------------===//
33 // Value
34 //===----------------------------------------------------------------------===//
35 
36 namespace detail {
37 
38 /// The base class for all derived Value classes. It contains all of the
39 /// components that are shared across Value classes.
40 class alignas(8) ValueImpl : public IRObjectWithUseList<OpOperand> {
41 public:
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.
getType()63   Type getType() const { return typeAndKind.getPointer(); }
64 
65   /// Set the type of this value.
setType(Type type)66   void setType(Type type) { return typeAndKind.setPointer(type); }
67 
68   /// Return the kind of this value.
getKind()69   Kind getKind() const { return typeAndKind.getInt(); }
70 
71 protected:
ValueImpl(Type type,Kind kind)72   ValueImpl(Type type, Kind kind) : typeAndKind(type, kind) {}
73 
74   /// The type of this result and the kind.
75   llvm::PointerIntPair<Type, 3, Kind> typeAndKind;
76 };
77 } // namespace detail
78 
79 /// This class represents an instance of an SSA value in the MLIR system,
80 /// representing a computable value that has a type and a set of users. An SSA
81 /// value is either a BlockArgument or the result of an operation. Note: This
82 /// class has value-type semantics and is just a simple wrapper around a
83 /// ValueImpl that is either owner by a block(in the case of a BlockArgument) or
84 /// an Operation(in the case of an OpResult).
85 class Value {
86 public:
impl(impl)87   constexpr Value(detail::ValueImpl *impl = nullptr) : impl(impl) {}
88 
89   template <typename U>
isa()90   bool isa() const {
91     assert(*this && "isa<> used on a null type.");
92     return U::classof(*this);
93   }
94 
95   template <typename First, typename Second, typename... Rest>
isa()96   bool isa() const {
97     return isa<First>() || isa<Second, Rest...>();
98   }
99   template <typename U>
dyn_cast()100   U dyn_cast() const {
101     return isa<U>() ? U(impl) : U(nullptr);
102   }
103   template <typename U>
dyn_cast_or_null()104   U dyn_cast_or_null() const {
105     return (*this && isa<U>()) ? U(impl) : U(nullptr);
106   }
107   template <typename U>
cast()108   U cast() const {
109     assert(isa<U>());
110     return U(impl);
111   }
112 
113   explicit operator bool() const { return impl; }
114   bool operator==(const Value &other) const { return impl == other.impl; }
115   bool operator!=(const Value &other) const { return !(*this == other); }
116 
117   /// Return the type of this value.
getType()118   Type getType() const { return impl->getType(); }
119 
120   /// Utility to get the associated MLIRContext that this value is defined in.
getContext()121   MLIRContext *getContext() const { return getType().getContext(); }
122 
123   /// Mutate the type of this Value to be of the specified type.
124   ///
125   /// Note that this is an extremely dangerous operation which can create
126   /// completely invalid IR very easily.  It is strongly recommended that you
127   /// recreate IR objects with the right types instead of mutating them in
128   /// place.
setType(Type newType)129   void setType(Type newType) { impl->setType(newType); }
130 
131   /// If this value is the result of an operation, return the operation that
132   /// defines it.
133   Operation *getDefiningOp() const;
134 
135   /// If this value is the result of an operation of type OpTy, return the
136   /// operation that defines it.
137   template <typename OpTy>
getDefiningOp()138   OpTy getDefiningOp() const {
139     return llvm::dyn_cast_or_null<OpTy>(getDefiningOp());
140   }
141 
142   /// Return the location of this value.
143   Location getLoc() const;
144   void setLoc(Location loc);
145 
146   /// Return the Region in which this Value is defined.
147   Region *getParentRegion();
148 
149   /// Return the Block in which this Value is defined.
150   Block *getParentBlock();
151 
152   //===--------------------------------------------------------------------===//
153   // UseLists
154   //===--------------------------------------------------------------------===//
155 
156   /// Drop all uses of this object from their respective owners.
dropAllUses()157   void dropAllUses() const { return impl->dropAllUses(); }
158 
159   /// Replace all uses of 'this' value with the new value, updating anything in
160   /// the IR that uses 'this' to use the other value instead.  When this returns
161   /// there are zero uses of 'this'.
replaceAllUsesWith(Value newValue)162   void replaceAllUsesWith(Value newValue) const {
163     impl->replaceAllUsesWith(newValue);
164   }
165 
166   /// Replace all uses of 'this' value with 'newValue', updating anything in the
167   /// IR that uses 'this' to use the other value instead except if the user is
168   /// listed in 'exceptions' .
169   void
170   replaceAllUsesExcept(Value newValue,
171                        const SmallPtrSetImpl<Operation *> &exceptions) const;
172 
173   /// Replace all uses of 'this' value with 'newValue', updating anything in the
174   /// IR that uses 'this' to use the other value instead except if the user is
175   /// 'exceptedUser'.
176   void replaceAllUsesExcept(Value newValue, Operation *exceptedUser) const;
177 
178   /// Replace all uses of 'this' value with 'newValue' if the given callback
179   /// returns true.
180   void replaceUsesWithIf(Value newValue,
181                          function_ref<bool(OpOperand &)> shouldReplace);
182 
183   /// Returns true if the value is used outside of the given block.
184   bool isUsedOutsideOfBlock(Block *block);
185 
186   //===--------------------------------------------------------------------===//
187   // Uses
188 
189   /// This class implements an iterator over the uses of a value.
190   using use_iterator = ValueUseIterator<OpOperand>;
191   using use_range = iterator_range<use_iterator>;
192 
use_begin()193   use_iterator use_begin() const { return impl->use_begin(); }
use_end()194   use_iterator use_end() const { return use_iterator(); }
195 
196   /// Returns a range of all uses, which is useful for iterating over all uses.
getUses()197   use_range getUses() const { return {use_begin(), use_end()}; }
198 
199   /// Returns true if this value has exactly one use.
hasOneUse()200   bool hasOneUse() const { return impl->hasOneUse(); }
201 
202   /// Returns true if this value has no uses.
use_empty()203   bool use_empty() const { return impl->use_empty(); }
204 
205   //===--------------------------------------------------------------------===//
206   // Users
207 
208   using user_iterator = ValueUserIterator<use_iterator, OpOperand>;
209   using user_range = iterator_range<user_iterator>;
210 
user_begin()211   user_iterator user_begin() const { return use_begin(); }
user_end()212   user_iterator user_end() const { return use_end(); }
getUsers()213   user_range getUsers() const { return {user_begin(), user_end()}; }
214 
215   //===--------------------------------------------------------------------===//
216   // Utilities
217 
218   void print(raw_ostream &os);
219   void print(raw_ostream &os, const OpPrintingFlags &flags);
220   void print(raw_ostream &os, AsmState &state);
221   void dump();
222 
223   /// Print this value as if it were an operand.
224   void printAsOperand(raw_ostream &os, AsmState &state);
225 
226   /// Methods for supporting PointerLikeTypeTraits.
getAsOpaquePointer()227   void *getAsOpaquePointer() const { return impl; }
getFromOpaquePointer(const void * pointer)228   static Value getFromOpaquePointer(const void *pointer) {
229     return reinterpret_cast<detail::ValueImpl *>(const_cast<void *>(pointer));
230   }
getImpl()231   detail::ValueImpl *getImpl() const { return impl; }
232 
233   friend ::llvm::hash_code hash_value(Value arg);
234 
235 protected:
236   /// A pointer to the internal implementation of the value.
237   detail::ValueImpl *impl;
238 };
239 
240 inline raw_ostream &operator<<(raw_ostream &os, Value value) {
241   value.print(os);
242   return os;
243 }
244 
245 //===----------------------------------------------------------------------===//
246 // OpOperand
247 //===----------------------------------------------------------------------===//
248 
249 /// This class represents an operand of an operation. Instances of this class
250 /// contain a reference to a specific `Value`.
251 class OpOperand : public IROperand<OpOperand, Value> {
252 public:
253   /// Provide the use list that is attached to the given value.
getUseList(Value value)254   static IRObjectWithUseList<OpOperand> *getUseList(Value value) {
255     return value.getImpl();
256   }
257 
258   /// Return which operand this is in the OpOperand list of the Operation.
259   unsigned getOperandNumber();
260 
261 private:
262   /// Keep the constructor private and accessible to the OperandStorage class
263   /// only to avoid hard-to-debug typo/programming mistakes.
264   friend class OperandStorage;
265   using IROperand<OpOperand, Value>::IROperand;
266 };
267 
268 //===----------------------------------------------------------------------===//
269 // BlockArgument
270 //===----------------------------------------------------------------------===//
271 
272 namespace detail {
273 /// The internal implementation of a BlockArgument.
274 class BlockArgumentImpl : public ValueImpl {
275 public:
classof(const ValueImpl * value)276   static bool classof(const ValueImpl *value) {
277     return value->getKind() == ValueImpl::Kind::BlockArgument;
278   }
279 
280 private:
BlockArgumentImpl(Type type,Block * owner,int64_t index,Location loc)281   BlockArgumentImpl(Type type, Block *owner, int64_t index, Location loc)
282       : ValueImpl(type, Kind::BlockArgument), owner(owner), index(index),
283         loc(loc) {}
284 
285   /// The owner of this argument.
286   Block *owner;
287 
288   /// The position in the argument list.
289   int64_t index;
290 
291   /// The source location of this argument.
292   Location loc;
293 
294   /// Allow access to owner and constructor.
295   friend BlockArgument;
296 };
297 } // namespace detail
298 
299 /// This class represents an argument of a Block.
300 class BlockArgument : public Value {
301 public:
302   using Value::Value;
303 
classof(Value value)304   static bool classof(Value value) {
305     return llvm::isa<detail::BlockArgumentImpl>(value.getImpl());
306   }
307 
308   /// Returns the block that owns this argument.
getOwner()309   Block *getOwner() const { return getImpl()->owner; }
310 
311   /// Returns the number of this argument.
getArgNumber()312   unsigned getArgNumber() const { return getImpl()->index; }
313 
314   /// Return the location for this argument.
getLoc()315   Location getLoc() const { return getImpl()->loc; }
setLoc(Location loc)316   void setLoc(Location loc) { getImpl()->loc = loc; }
317 
318 private:
319   /// Allocate a new argument with the given type and owner.
create(Type type,Block * owner,int64_t index,Location loc)320   static BlockArgument create(Type type, Block *owner, int64_t index,
321                               Location loc) {
322     return new detail::BlockArgumentImpl(type, owner, index, loc);
323   }
324 
325   /// Destroy and deallocate this argument.
destroy()326   void destroy() { delete getImpl(); }
327 
328   /// Get a raw pointer to the internal implementation.
getImpl()329   detail::BlockArgumentImpl *getImpl() const {
330     return reinterpret_cast<detail::BlockArgumentImpl *>(impl);
331   }
332 
333   /// Cache the position in the block argument list.
setArgNumber(int64_t index)334   void setArgNumber(int64_t index) { getImpl()->index = index; }
335 
336   /// Allow access to `create`, `destroy` and `setArgNumber`.
337   friend Block;
338 
339   /// Allow access to 'getImpl'.
340   friend Value;
341 };
342 
343 //===----------------------------------------------------------------------===//
344 // OpResult
345 //===----------------------------------------------------------------------===//
346 
347 namespace detail {
348 /// This class provides the implementation for an operation result.
349 class alignas(8) OpResultImpl : public ValueImpl {
350 public:
351   using ValueImpl::ValueImpl;
352 
classof(const ValueImpl * value)353   static bool classof(const ValueImpl *value) {
354     return value->getKind() != ValueImpl::Kind::BlockArgument;
355   }
356 
357   /// Returns the parent operation of this result.
358   Operation *getOwner() const;
359 
360   /// Returns the result number of this op result.
361   unsigned getResultNumber() const;
362 
363   /// Returns the next operation result at `offset` after this result. This
364   /// method is useful when indexing the result storage of an operation, given
365   /// that there is more than one kind of operation result (with the different
366   /// kinds having different sizes) and that operations are stored in reverse
367   /// order.
368   OpResultImpl *getNextResultAtOffset(intptr_t offset);
369 
370   /// Returns the maximum number of results that can be stored inline.
getMaxInlineResults()371   static unsigned getMaxInlineResults() {
372     return static_cast<unsigned>(Kind::OutOfLineOpResult);
373   }
374 };
375 
376 /// This class provides the implementation for an operation result whose index
377 /// can be represented "inline" in the underlying ValueImpl.
378 struct InlineOpResult : public OpResultImpl {
379 public:
InlineOpResultInlineOpResult380   InlineOpResult(Type type, unsigned resultNo)
381       : OpResultImpl(type, static_cast<ValueImpl::Kind>(resultNo)) {
382     assert(resultNo < getMaxInlineResults());
383   }
384 
385   /// Return the result number of this op result.
getResultNumberInlineOpResult386   unsigned getResultNumber() const { return static_cast<unsigned>(getKind()); }
387 
classofInlineOpResult388   static bool classof(const OpResultImpl *value) {
389     return value->getKind() != ValueImpl::Kind::OutOfLineOpResult;
390   }
391 };
392 
393 /// This class provides the implementation for an operation result whose index
394 /// cannot be represented "inline", and thus requires an additional index field.
395 class OutOfLineOpResult : public OpResultImpl {
396 public:
OutOfLineOpResult(Type type,uint64_t outOfLineIndex)397   OutOfLineOpResult(Type type, uint64_t outOfLineIndex)
398       : OpResultImpl(type, Kind::OutOfLineOpResult),
399         outOfLineIndex(outOfLineIndex) {}
400 
classof(const OpResultImpl * value)401   static bool classof(const OpResultImpl *value) {
402     return value->getKind() == ValueImpl::Kind::OutOfLineOpResult;
403   }
404 
405   /// Return the result number of this op result.
getResultNumber()406   unsigned getResultNumber() const {
407     return outOfLineIndex + getMaxInlineResults();
408   }
409 
410   /// The trailing result number, or the offset from the beginning of the
411   /// `OutOfLineOpResult` array.
412   uint64_t outOfLineIndex;
413 };
414 
415 /// Return the result number of this op result.
getResultNumber()416 inline unsigned OpResultImpl::getResultNumber() const {
417   if (const auto *outOfLineResult = dyn_cast<OutOfLineOpResult>(this))
418     return outOfLineResult->getResultNumber();
419   return cast<InlineOpResult>(this)->getResultNumber();
420 }
421 
422 } // namespace detail
423 
424 /// This is a value defined by a result of an operation.
425 class OpResult : public Value {
426 public:
427   using Value::Value;
428 
classof(Value value)429   static bool classof(Value value) {
430     return llvm::isa<detail::OpResultImpl>(value.getImpl());
431   }
432 
433   /// Returns the operation that owns this result.
getOwner()434   Operation *getOwner() const { return getImpl()->getOwner(); }
435 
436   /// Returns the number of this result.
getResultNumber()437   unsigned getResultNumber() const { return getImpl()->getResultNumber(); }
438 
439 private:
440   /// Get a raw pointer to the internal implementation.
getImpl()441   detail::OpResultImpl *getImpl() const {
442     return reinterpret_cast<detail::OpResultImpl *>(impl);
443   }
444 
445   /// Given a number of operation results, returns the number that need to be
446   /// stored inline.
447   static unsigned getNumInline(unsigned numResults);
448 
449   /// Given a number of operation results, returns the number that need to be
450   /// stored as trailing.
451   static unsigned getNumTrailing(unsigned numResults);
452 
453   /// Allow access to constructor.
454   friend Operation;
455 };
456 
457 /// Make Value hashable.
hash_value(Value arg)458 inline ::llvm::hash_code hash_value(Value arg) {
459   return ::llvm::hash_value(arg.getImpl());
460 }
461 
462 } // namespace mlir
463 
464 namespace llvm {
465 
466 template <>
467 struct DenseMapInfo<mlir::Value> {
468   static mlir::Value getEmptyKey() {
469     void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
470     return mlir::Value::getFromOpaquePointer(pointer);
471   }
472   static mlir::Value getTombstoneKey() {
473     void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
474     return mlir::Value::getFromOpaquePointer(pointer);
475   }
476   static unsigned getHashValue(mlir::Value val) {
477     return mlir::hash_value(val);
478   }
479   static bool isEqual(mlir::Value lhs, mlir::Value rhs) { return lhs == rhs; }
480 };
481 template <>
482 struct DenseMapInfo<mlir::BlockArgument> : public DenseMapInfo<mlir::Value> {
483   static mlir::BlockArgument getEmptyKey() {
484     void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
485     return reinterpret_cast<mlir::detail::BlockArgumentImpl *>(pointer);
486   }
487   static mlir::BlockArgument getTombstoneKey() {
488     void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
489     return reinterpret_cast<mlir::detail::BlockArgumentImpl *>(pointer);
490   }
491 };
492 template <>
493 struct DenseMapInfo<mlir::OpResult> : public DenseMapInfo<mlir::Value> {
494   static mlir::OpResult getEmptyKey() {
495     void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
496     return reinterpret_cast<mlir::detail::OpResultImpl *>(pointer);
497   }
498   static mlir::OpResult getTombstoneKey() {
499     void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
500     return reinterpret_cast<mlir::detail::OpResultImpl *>(pointer);
501   }
502 };
503 
504 /// Allow stealing the low bits of a value.
505 template <>
506 struct PointerLikeTypeTraits<mlir::Value> {
507 public:
508   static inline void *getAsVoidPointer(mlir::Value value) {
509     return const_cast<void *>(value.getAsOpaquePointer());
510   }
511   static inline mlir::Value getFromVoidPointer(void *pointer) {
512     return mlir::Value::getFromOpaquePointer(pointer);
513   }
514   enum {
515     NumLowBitsAvailable =
516         PointerLikeTypeTraits<mlir::detail::ValueImpl *>::NumLowBitsAvailable
517   };
518 };
519 template <>
520 struct PointerLikeTypeTraits<mlir::BlockArgument>
521     : public PointerLikeTypeTraits<mlir::Value> {
522 public:
523   static inline mlir::BlockArgument getFromVoidPointer(void *pointer) {
524     return reinterpret_cast<mlir::detail::BlockArgumentImpl *>(pointer);
525   }
526 };
527 template <>
528 struct PointerLikeTypeTraits<mlir::OpResult>
529     : public PointerLikeTypeTraits<mlir::Value> {
530 public:
531   static inline mlir::OpResult getFromVoidPointer(void *pointer) {
532     return reinterpret_cast<mlir::detail::OpResultImpl *>(pointer);
533   }
534 };
535 
536 } // namespace llvm
537 
538 #endif
539