My Project
Value.h
Go to the documentation of this file.
1 //===- Value.h - Base of the SSA Value hierarchy ----------------*- C++ -*-===//
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 // 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 
20 namespace mlir {
21 class BlockArgument;
22 class Operation;
23 class OpResult;
24 class Region;
25 class Value;
26 
27 namespace detail {
29 class BlockArgumentImpl;
30 } // end namespace detail
31 
38 class Value {
39 public:
43  enum class Kind {
48  OpResult0 = 0,
49  OpResult1 = 1,
50 
55  TrailingOpResult = 2,
56 
59  BlockArgument = 3
60  };
61 
65  struct ImplTypeTraits : public llvm::PointerLikeTypeTraits<void *> {
66  // We know that all pointers within the ImplType are aligned by 8-bytes,
67  // meaning that we can steal up to 3 bits for the different values.
68  enum { NumLowBitsAvailable = 3 };
69  };
70  using ImplType = llvm::PointerIntPair<void *, 2, Kind, ImplTypeTraits>;
71 
72 public:
73  Value(std::nullptr_t) : ownerAndKind() {}
74  Value(ImplType ownerAndKind = {}) : ownerAndKind(ownerAndKind) {}
75  Value(const Value &) = default;
76  Value &operator=(const Value &) = default;
77 
78  template <typename U> bool isa() const {
79  assert(*this && "isa<> used on a null type.");
80  return U::classof(*this);
81  }
82  template <typename U> U dyn_cast() const {
83  return isa<U>() ? U(ownerAndKind) : U(nullptr);
84  }
85  template <typename U> U dyn_cast_or_null() const {
86  return (*this && isa<U>()) ? U(ownerAndKind) : U(nullptr);
87  }
88  template <typename U> U cast() const {
89  assert(isa<U>());
90  return U(ownerAndKind);
91  }
92 
96  Value operator*() const { return *this; }
97  Value *operator->() const { return const_cast<Value *>(this); }
98 
99  operator bool() const { return ownerAndKind.getPointer(); }
100  bool operator==(const Value &other) const {
101  return ownerAndKind == other.ownerAndKind;
102  }
103  bool operator!=(const Value &other) const { return !(*this == other); }
104 
106  Type getType() const;
107 
109  MLIRContext *getContext() const { return getType().getContext(); }
110 
117  void setType(Type newType);
118 
121  Operation *getDefiningOp() const;
122 
125  Location getLoc();
126 
128  Region *getParentRegion();
129 
130  //===--------------------------------------------------------------------===//
131  // UseLists
132  //===--------------------------------------------------------------------===//
133 
135  IRObjectWithUseList<OpOperand> *getUseList() const;
136 
138  void dropAllUses() const;
139 
143  void replaceAllUsesWith(Value newValue) const;
144 
145  //===--------------------------------------------------------------------===//
146  // Uses
147 
151 
152  use_iterator use_begin() const;
153  use_iterator use_end() const { return use_iterator(); }
154 
156  use_range getUses() const { return {use_begin(), use_end()}; }
157 
159  bool hasOneUse() const;
160 
162  bool use_empty() const;
163 
164  //===--------------------------------------------------------------------===//
165  // Users
166 
169 
170  user_iterator user_begin() const { return use_begin(); }
171  user_iterator user_end() const { return use_end(); }
172  user_range getUsers() const { return {user_begin(), user_end()}; }
173 
174  //===--------------------------------------------------------------------===//
175  // Utilities
176 
178  Kind getKind() const { return ownerAndKind.getInt(); }
179 
180  void print(raw_ostream &os);
181  void dump();
182 
184  void *getAsOpaquePointer() const { return ownerAndKind.getOpaqueValue(); }
185  static Value getFromOpaquePointer(const void *pointer) {
186  Value value;
187  value.ownerAndKind.setFromOpaqueValue(const_cast<void *>(pointer));
188  return value;
189  }
190 
191  friend ::llvm::hash_code hash_value(Value arg);
192 
193 protected:
195  static bool canPackResultInline(unsigned resultNo) {
196  return resultNo < static_cast<unsigned>(Kind::TrailingOpResult);
197  }
198 
201  Value(Operation *op, unsigned resultNo);
202 
207 };
208 
209 inline raw_ostream &operator<<(raw_ostream &os, Value value) {
210  value.print(os);
211  return os;
212 }
213 
214 //===----------------------------------------------------------------------===//
215 // BlockArgument
216 //===----------------------------------------------------------------------===//
217 
218 namespace detail {
220 class BlockArgumentImpl : public IRObjectWithUseList<OpOperand> {
221  BlockArgumentImpl(Type type, Block *owner) : type(type), owner(owner) {}
222 
224  Type type;
225 
227  Block *owner;
228 
230  friend BlockArgument;
231 };
232 } // end namespace detail
233 
235 class BlockArgument : public Value {
236 public:
237  using Value::Value;
238 
242  BlockArgument *operator->() { return this; }
243 
244  static bool classof(Value value) {
245  return value.getKind() == Kind::BlockArgument;
246  }
247 
249  Block *getOwner() const { return getImpl()->owner; }
250 
252  Type getType() const { return getImpl()->type; }
253 
255  void setType(Type newType) { getImpl()->type = newType; }
256 
258  unsigned getArgNumber() const;
259 
260 private:
262  static BlockArgument create(Type type, Block *owner) {
263  return new detail::BlockArgumentImpl(type, owner);
264  }
265 
267  void destroy() { delete getImpl(); }
268 
270  detail::BlockArgumentImpl *getImpl() const {
271  return reinterpret_cast<detail::BlockArgumentImpl *>(
272  ownerAndKind.getPointer());
273  }
274 
276  friend Block;
277 
279  friend Value;
280 };
281 
282 //===----------------------------------------------------------------------===//
283 // OpResult
284 //===----------------------------------------------------------------------===//
285 
287 class OpResult : public Value {
288 public:
289  using Value::Value;
290 
294  OpResult operator*() { return *this; }
295  OpResult *operator->() { return this; }
296 
297  static bool classof(Value value) {
298  return value.getKind() != Kind::BlockArgument;
299  }
300 
302  Operation *getOwner() const;
303 
305  unsigned getResultNumber() const;
306 
307 private:
310  static unsigned getNumTrailing(unsigned numResults);
311 
313  friend Operation;
314 };
315 
317 inline ::llvm::hash_code hash_value(Value arg) {
318  return ::llvm::hash_value(arg.ownerAndKind.getOpaqueValue());
319 }
320 
321 } // namespace mlir
322 
323 namespace llvm {
324 
325 template <> struct DenseMapInfo<mlir::Value> {
328  return mlir::Value::getFromOpaquePointer(pointer);
329  }
332  return mlir::Value::getFromOpaquePointer(pointer);
333  }
334  static unsigned getHashValue(mlir::Value val) {
335  return mlir::hash_value(val);
336  }
337  static bool isEqual(mlir::Value lhs, mlir::Value rhs) { return lhs == rhs; }
338 };
339 
341 template <> struct PointerLikeTypeTraits<mlir::Value> {
342 public:
343  static inline void *getAsVoidPointer(mlir::Value I) {
344  return const_cast<void *>(I.getAsOpaquePointer());
345  }
346  static inline mlir::Value getFromVoidPointer(void *P) {
348  }
349  enum {
350  NumLowBitsAvailable =
351  PointerLikeTypeTraits<mlir::Value::ImplType>::NumLowBitsAvailable
352  };
353 };
354 
355 template <> struct DenseMapInfo<mlir::BlockArgument> {
358  return mlir::BlockArgument(
359  mlir::Value::ImplType::getFromOpaqueValue(pointer));
360  }
363  return mlir::BlockArgument(
364  mlir::Value::ImplType::getFromOpaqueValue(pointer));
365  }
366  static unsigned getHashValue(mlir::BlockArgument val) {
367  return mlir::hash_value(val);
368  }
370  return LHS == RHS;
371  }
372 };
373 
375 template <> struct PointerLikeTypeTraits<mlir::BlockArgument> {
376 public:
377  static inline void *getAsVoidPointer(mlir::Value I) {
378  return const_cast<void *>(I.getAsOpaquePointer());
379  }
380  static inline mlir::BlockArgument getFromVoidPointer(void *P) {
382  }
383  enum {
384  NumLowBitsAvailable =
385  PointerLikeTypeTraits<mlir::Value>::NumLowBitsAvailable
386  };
387 };
388 } // end namespace llvm
389 
390 #endif
Kind getKind() const
Returns the kind of this value.
Definition: Value.h:178
Definition: InferTypeOpInterface.cpp:20
Definition: Region.h:23
Definition: PassRegistry.cpp:413
static bool classof(Value value)
Definition: Value.h:244
Definition: Operation.h:27
The internal implementation of a BlockArgument.
Definition: Value.h:220
This is a value defined by a result of an operation.
Definition: Value.h:287
Type getType() const
Return the type of this value.
Definition: Value.h:252
Block represents an ordered list of Operations.
Definition: Block.h:21
Definition: LLVM.h:45
OpResult operator*()
Definition: Value.h:294
OpResult * operator->()
Definition: Value.h:295
An iterator over all users of a ValueBase.
Definition: UseDefLists.h:27
static mlir::Value getTombstoneKey()
Definition: Value.h:330
static bool isEqual(mlir::Value lhs, mlir::Value rhs)
Definition: Value.h:337
user_range getUsers() const
Definition: Value.h:172
bool operator!=(const Value &other) const
Definition: Value.h:103
void * getAsOpaquePointer() const
Methods for supporting PointerLikeTypeTraits.
Definition: Value.h:184
Definition: Location.h:52
Value operator*() const
Definition: Value.h:96
Block * getOwner() const
Returns the block that owns this argument.
Definition: Value.h:249
static Value getFromOpaquePointer(const void *pointer)
Definition: Value.h:185
void print(raw_ostream &os)
Definition: AsmPrinter.cpp:2109
static unsigned getHashValue(mlir::BlockArgument val)
Definition: Value.h:366
static unsigned getHashValue(mlir::Value val)
Definition: Value.h:334
Definition: Value.h:65
U dyn_cast() const
Definition: Value.h:82
user_iterator user_begin() const
Definition: Value.h:170
static void * getAsVoidPointer(mlir::Value I)
Definition: Value.h:343
static mlir::BlockArgument getEmptyKey()
Definition: Value.h:356
void setType(Type newType)
Set the type of this value.
Definition: Value.h:255
static bool isEqual(mlir::BlockArgument LHS, mlir::BlockArgument RHS)
Definition: Value.h:369
static bool canPackResultInline(unsigned resultNo)
Returns true if the given operation result can be packed inline.
Definition: Value.h:195
bool operator==(const Value &other) const
Definition: Value.h:100
ImplType ownerAndKind
Definition: Value.h:206
Block arguments are values.
Definition: Value.h:235
static void * getAsVoidPointer(mlir::Value I)
Definition: Value.h:377
Definition: Types.h:84
use_iterator use_end() const
Definition: Value.h:153
BlockArgument * operator->()
Definition: Value.h:242
user_iterator user_end() const
Definition: Value.h:171
MLIRContext * getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Types.cpp:27
Definition: Value.h:38
inline ::llvm::hash_code hash_value(AffineExpr arg)
Make AffineExpr hashable.
Definition: AffineExpr.h:201
bool isa() const
Definition: Value.h:78
inline ::llvm::hash_code hash_value(Value arg)
Make Value hashable.
Definition: Value.h:317
Definition: LLVM.h:50
llvm::PointerIntPair< void *, 2, Kind, ImplTypeTraits > ImplType
Definition: Value.h:70
Value(std::nullptr_t)
Definition: Value.h:73
U dyn_cast_or_null() const
Definition: Value.h:85
Definition: MLIRContext.h:34
void print(OpAsmPrinter &p, AffineIfOp op)
Definition: AffineOps.cpp:1671
static bool classof(Value value)
Definition: Value.h:297
Value(ImplType ownerAndKind={})
Definition: Value.h:74
Definition: UseDefLists.h:26
U cast() const
Definition: Value.h:88
static mlir::BlockArgument getTombstoneKey()
Definition: Value.h:361
raw_ostream & operator<<(raw_ostream &os, SubViewOp::Range &range)
Definition: Ops.cpp:2759
Kind
Definition: Value.h:43
static mlir::Value getFromVoidPointer(void *P)
Definition: Value.h:346
Value * operator->() const
Definition: Value.h:97
use_range getUses() const
Returns a range of all uses, which is useful for iterating over all uses.
Definition: Value.h:156
static mlir::BlockArgument getFromVoidPointer(void *P)
Definition: Value.h:380
MLIRContext * getContext() const
Utility to get the associated MLIRContext that this value is defined in.
Definition: Value.h:109
static mlir::Value getEmptyKey()
Definition: Value.h:326