• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 BlockArgument;
24 class Operation;
25 class OpResult;
26 class Region;
27 class Value;
28 
29 namespace detail {
30 /// The internal implementation of a BlockArgument.
31 class BlockArgumentImpl;
32 } // end namespace detail
33 
34 /// This class represents an instance of an SSA value in the MLIR system,
35 /// representing a computable value that has a type and a set of users. An SSA
36 /// value is either a BlockArgument or the result of an operation. Note: This
37 /// class has value-type semantics and is just a simple wrapper around a
38 /// ValueImpl that is either owner by a block(in the case of a BlockArgument) or
39 /// an Operation(in the case of an OpResult).
40 class Value {
41 public:
42   /// The enumeration represents the various different kinds of values the
43   /// internal representation may take. We steal 2 bits to support a total of 4
44   /// possible values.
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, and the owner
48     /// pointer is the owning `Operation*`. Note: These are packed first to make
49     /// result number lookups more efficient.
50     OpResult0 = 0,
51     OpResult1 = 1,
52 
53     /// The next kind represents a 'trailing' operation result. This is for
54     /// results with numbers larger than we can represent inline. The owner here
55     /// is an `TrailingOpResult*` that points to a trailing storage on the
56     /// parent operation.
57     TrailingOpResult = 2,
58 
59     /// The last kind represents a block argument. The owner here is a
60     /// `BlockArgumentImpl*`.
61     BlockArgument = 3
62   };
63 
64   /// This value represents the 'owner' of the value and its kind. See the
65   /// 'Kind' enumeration above for a more detailed description of each kind of
66   /// owner.
67   struct ImplTypeTraits : public llvm::PointerLikeTypeTraits<void *> {
68     // We know that all pointers within the ImplType are aligned by 8-bytes,
69     // meaning that we can steal up to 3 bits for the different values.
70     static constexpr int NumLowBitsAvailable = 3;
71   };
72   using ImplType = llvm::PointerIntPair<void *, 2, Kind, ImplTypeTraits>;
73 
74 public:
Value(std::nullptr_t)75   constexpr Value(std::nullptr_t) : ownerAndKind() {}
ownerAndKind(ownerAndKind)76   Value(ImplType ownerAndKind = {}) : ownerAndKind(ownerAndKind) {}
77   Value(const Value &) = default;
78   Value &operator=(const Value &) = default;
79 
isa()80   template <typename U> bool isa() const {
81     assert(*this && "isa<> used on a null type.");
82     return U::classof(*this);
83   }
84 
85   template <typename First, typename Second, typename... Rest>
isa()86   bool isa() const {
87     return isa<First>() || isa<Second, Rest...>();
88   }
89 
dyn_cast()90   template <typename U> U dyn_cast() const {
91     return isa<U>() ? U(ownerAndKind) : U(nullptr);
92   }
dyn_cast_or_null()93   template <typename U> U dyn_cast_or_null() const {
94     return (*this && isa<U>()) ? U(ownerAndKind) : U(nullptr);
95   }
cast()96   template <typename U> U cast() const {
97     assert(isa<U>());
98     return U(ownerAndKind);
99   }
100 
101   explicit operator bool() const { return ownerAndKind.getPointer(); }
102   bool operator==(const Value &other) const {
103     return ownerAndKind == other.ownerAndKind;
104   }
105   bool operator!=(const Value &other) const { return !(*this == other); }
106 
107   /// Return the type of this value.
108   Type getType() const;
109 
110   /// Utility to get the associated MLIRContext that this value is defined in.
getContext()111   MLIRContext *getContext() const { return getType().getContext(); }
112 
113   /// Mutate the type of this Value to be of the specified type.
114   ///
115   /// Note that this is an extremely dangerous operation which can create
116   /// completely invalid IR very easily.  It is strongly recommended that you
117   /// recreate IR objects with the right types instead of mutating them in
118   /// place.
119   void setType(Type newType);
120 
121   /// If this value is the result of an operation, return the operation that
122   /// defines it.
123   Operation *getDefiningOp() const;
124 
125   /// If this value is the result of an operation of type OpTy, return the
126   /// operation that defines it.
127   template <typename OpTy>
getDefiningOp()128   OpTy getDefiningOp() const {
129     return llvm::dyn_cast_or_null<OpTy>(getDefiningOp());
130   }
131 
132   /// If this value is the result of an operation, use it as a location,
133   /// otherwise return an unknown location.
134   Location getLoc() const;
135 
136   /// Return the Region in which this Value is defined.
137   Region *getParentRegion();
138 
139   /// Return the Block in which this Value is defined.
140   Block *getParentBlock();
141 
142   //===--------------------------------------------------------------------===//
143   // UseLists
144   //===--------------------------------------------------------------------===//
145 
146   /// Provide the use list that is attached to this value.
147   IRObjectWithUseList<OpOperand> *getUseList() const;
148 
149   /// Drop all uses of this object from their respective owners.
150   void dropAllUses() const;
151 
152   /// Replace all uses of 'this' value with the new value, updating anything in
153   /// the IR that uses 'this' to use the other value instead.  When this returns
154   /// there are zero uses of 'this'.
155   void replaceAllUsesWith(Value newValue) const;
156 
157   /// Replace all uses of 'this' value with 'newValue', updating anything in the
158   /// IR that uses 'this' to use the other value instead except if the user is
159   /// listed in 'exceptions' .
160   void
161   replaceAllUsesExcept(Value newValue,
162                        const SmallPtrSetImpl<Operation *> &exceptions) const;
163 
164   /// Replace all uses of 'this' value with 'newValue' if the given callback
165   /// returns true.
166   void replaceUsesWithIf(Value newValue,
167                          function_ref<bool(OpOperand &)> shouldReplace);
168 
169   /// Returns true if the value is used outside of the given block.
170   bool isUsedOutsideOfBlock(Block *block);
171 
172   //===--------------------------------------------------------------------===//
173   // Uses
174 
175   /// This class implements an iterator over the uses of a value.
176   using use_iterator = ValueUseIterator<OpOperand>;
177   using use_range = iterator_range<use_iterator>;
178 
179   use_iterator use_begin() const;
use_end()180   use_iterator use_end() const { return use_iterator(); }
181 
182   /// Returns a range of all uses, which is useful for iterating over all uses.
getUses()183   use_range getUses() const { return {use_begin(), use_end()}; }
184 
185   /// Returns true if this value has exactly one use.
186   bool hasOneUse() const;
187 
188   /// Returns true if this value has no uses.
189   bool use_empty() const;
190 
191   //===--------------------------------------------------------------------===//
192   // Users
193 
194   using user_iterator = ValueUserIterator<use_iterator, OpOperand>;
195   using user_range = iterator_range<user_iterator>;
196 
user_begin()197   user_iterator user_begin() const { return use_begin(); }
user_end()198   user_iterator user_end() const { return use_end(); }
getUsers()199   user_range getUsers() const { return {user_begin(), user_end()}; }
200 
201   //===--------------------------------------------------------------------===//
202   // Utilities
203 
204   /// Returns the kind of this value.
getKind()205   Kind getKind() const { return ownerAndKind.getInt(); }
206 
207   void print(raw_ostream &os);
208   void print(raw_ostream &os, AsmState &state);
209   void dump();
210 
211   /// Print this value as if it were an operand.
212   void printAsOperand(raw_ostream &os, AsmState &state);
213 
214   /// Methods for supporting PointerLikeTypeTraits.
getAsOpaquePointer()215   void *getAsOpaquePointer() const { return ownerAndKind.getOpaqueValue(); }
getFromOpaquePointer(const void * pointer)216   static Value getFromOpaquePointer(const void *pointer) {
217     Value value;
218     value.ownerAndKind.setFromOpaqueValue(const_cast<void *>(pointer));
219     return value;
220   }
221 
222   friend ::llvm::hash_code hash_value(Value arg);
223 
224 protected:
225   /// Returns true if the given operation result can be packed inline.
canPackResultInline(unsigned resultNo)226   static bool canPackResultInline(unsigned resultNo) {
227     return resultNo < static_cast<unsigned>(Kind::TrailingOpResult);
228   }
229 
230   /// Construct a value.
231   Value(detail::BlockArgumentImpl *impl);
232   Value(Operation *op, unsigned resultNo);
233 
234   /// This value represents the 'owner' of the value and its kind. See the
235   /// 'Kind' enumeration above for a more detailed description of each kind of
236   /// owner.
237   ImplType ownerAndKind;
238 };
239 
240 inline raw_ostream &operator<<(raw_ostream &os, Value value) {
241   value.print(os);
242   return os;
243 }
244 
245 //===----------------------------------------------------------------------===//
246 // BlockArgument
247 //===----------------------------------------------------------------------===//
248 
249 namespace detail {
250 /// The internal implementation of a BlockArgument.
251 class BlockArgumentImpl : public IRObjectWithUseList<OpOperand> {
BlockArgumentImpl(Type type,Block * owner)252   BlockArgumentImpl(Type type, Block *owner) : type(type), owner(owner) {}
253 
254   /// The type of this argument.
255   Type type;
256 
257   /// The owner of this argument.
258   Block *owner;
259 
260   /// Allow access to owner and constructor.
261   friend BlockArgument;
262 };
263 } // end namespace detail
264 
265 /// Block arguments are values.
266 class BlockArgument : public Value {
267 public:
268   using Value::Value;
269 
classof(Value value)270   static bool classof(Value value) {
271     return value.getKind() == Kind::BlockArgument;
272   }
273 
274   /// Returns the block that owns this argument.
getOwner()275   Block *getOwner() const { return getImpl()->owner; }
276 
277   /// Return the type of this value.
getType()278   Type getType() const { return getImpl()->type; }
279 
280   /// Set the type of this value.
setType(Type newType)281   void setType(Type newType) { getImpl()->type = newType; }
282 
283   /// Returns the number of this argument.
284   unsigned getArgNumber() const;
285 
286 private:
287   /// Allocate a new argument with the given type and owner.
create(Type type,Block * owner)288   static BlockArgument create(Type type, Block *owner) {
289     return new detail::BlockArgumentImpl(type, owner);
290   }
291 
292   /// Destroy and deallocate this argument.
destroy()293   void destroy() { delete getImpl(); }
294 
295   /// Get a raw pointer to the internal implementation.
getImpl()296   detail::BlockArgumentImpl *getImpl() const {
297     return reinterpret_cast<detail::BlockArgumentImpl *>(
298         ownerAndKind.getPointer());
299   }
300 
301   /// Allow access to `create` and `destroy`.
302   friend Block;
303 
304   /// Allow access to 'getImpl'.
305   friend Value;
306 };
307 
308 //===----------------------------------------------------------------------===//
309 // OpResult
310 //===----------------------------------------------------------------------===//
311 
312 /// This is a value defined by a result of an operation.
313 class OpResult : public Value {
314 public:
315   using Value::Value;
316 
classof(Value value)317   static bool classof(Value value) {
318     return value.getKind() != Kind::BlockArgument;
319   }
320 
321   /// Returns the operation that owns this result.
322   Operation *getOwner() const;
323 
324   /// Returns the number of this result.
325   unsigned getResultNumber() const;
326 
327   /// Returns the maximum number of results that can be stored inline.
getMaxInlineResults()328   static unsigned getMaxInlineResults() {
329     return static_cast<unsigned>(Kind::TrailingOpResult);
330   }
331 
332 private:
333   /// Given a number of operation results, returns the number that need to be
334   /// stored inline.
335   static unsigned getNumInline(unsigned numResults);
336 
337   /// Given a number of operation results, returns the number that need to be
338   /// stored as trailing.
339   static unsigned getNumTrailing(unsigned numResults);
340 
341   /// Allow access to constructor.
342   friend Operation;
343 };
344 
345 /// Make Value hashable.
hash_value(Value arg)346 inline ::llvm::hash_code hash_value(Value arg) {
347   return ::llvm::hash_value(arg.ownerAndKind.getOpaqueValue());
348 }
349 
350 } // namespace mlir
351 
352 namespace llvm {
353 
354 template <> struct DenseMapInfo<mlir::Value> {
355   static mlir::Value getEmptyKey() {
356     auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
357     return mlir::Value::getFromOpaquePointer(pointer);
358   }
359   static mlir::Value getTombstoneKey() {
360     auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
361     return mlir::Value::getFromOpaquePointer(pointer);
362   }
363   static unsigned getHashValue(mlir::Value val) {
364     return mlir::hash_value(val);
365   }
366   static bool isEqual(mlir::Value lhs, mlir::Value rhs) { return lhs == rhs; }
367 };
368 
369 /// Allow stealing the low bits of a value.
370 template <> struct PointerLikeTypeTraits<mlir::Value> {
371 public:
372   static inline void *getAsVoidPointer(mlir::Value I) {
373     return const_cast<void *>(I.getAsOpaquePointer());
374   }
375   static inline mlir::Value getFromVoidPointer(void *P) {
376     return mlir::Value::getFromOpaquePointer(P);
377   }
378   enum {
379     NumLowBitsAvailable =
380         PointerLikeTypeTraits<mlir::Value::ImplType>::NumLowBitsAvailable
381   };
382 };
383 
384 template <> struct DenseMapInfo<mlir::BlockArgument> {
385   static mlir::BlockArgument getEmptyKey() {
386     auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
387     return mlir::BlockArgument(
388         mlir::Value::ImplType::getFromOpaqueValue(pointer));
389   }
390   static mlir::BlockArgument getTombstoneKey() {
391     auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
392     return mlir::BlockArgument(
393         mlir::Value::ImplType::getFromOpaqueValue(pointer));
394   }
395   static unsigned getHashValue(mlir::BlockArgument val) {
396     return mlir::hash_value(val);
397   }
398   static bool isEqual(mlir::BlockArgument LHS, mlir::BlockArgument RHS) {
399     return LHS == RHS;
400   }
401 };
402 
403 /// Allow stealing the low bits of a value.
404 template <> struct PointerLikeTypeTraits<mlir::BlockArgument> {
405 public:
406   static inline void *getAsVoidPointer(mlir::Value I) {
407     return const_cast<void *>(I.getAsOpaquePointer());
408   }
409   static inline mlir::BlockArgument getFromVoidPointer(void *P) {
410     return mlir::Value::getFromOpaquePointer(P).cast<mlir::BlockArgument>();
411   }
412   enum {
413     NumLowBitsAvailable =
414         PointerLikeTypeTraits<mlir::Value>::NumLowBitsAvailable
415   };
416 };
417 } // end namespace llvm
418 
419 #endif
420