summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mlir/bindings/python/pybind.cpp3
-rw-r--r--mlir/include/mlir/Analysis/AffineAnalysis.h7
-rw-r--r--mlir/include/mlir/Analysis/Liveness.h2
-rw-r--r--mlir/include/mlir/Analysis/LoopAnalysis.h2
-rw-r--r--mlir/include/mlir/Conversion/AffineToStandard/AffineToStandard.h2
-rw-r--r--mlir/include/mlir/Conversion/LoopsToGPU/LoopsToGPU.h2
-rw-r--r--mlir/include/mlir/Dialect/VectorOps/Utils.h2
-rw-r--r--mlir/include/mlir/EDSC/Builders.h1
-rw-r--r--mlir/include/mlir/IR/Block.h2
-rw-r--r--mlir/include/mlir/IR/BlockAndValueMapping.h38
-rw-r--r--mlir/include/mlir/IR/OpImplementation.h16
-rw-r--r--mlir/include/mlir/IR/Operation.h2
-rw-r--r--mlir/include/mlir/IR/OperationSupport.h44
-rw-r--r--mlir/include/mlir/IR/TypeUtilities.h1
-rw-r--r--mlir/include/mlir/IR/UseDefLists.h17
-rw-r--r--mlir/include/mlir/IR/Value.h297
-rw-r--r--mlir/lib/Analysis/AffineStructures.cpp4
-rw-r--r--mlir/lib/Analysis/Dominance.cpp2
-rw-r--r--mlir/lib/Analysis/Liveness.cpp4
-rw-r--r--mlir/lib/Analysis/SliceAnalysis.cpp2
-rw-r--r--mlir/lib/Dialect/AffineOps/AffineOps.cpp6
-rw-r--r--mlir/lib/Dialect/Linalg/Analysis/DependenceAnalysis.cpp4
-rw-r--r--mlir/lib/Dialect/LoopOps/LoopOps.cpp2
-rw-r--r--mlir/lib/Dialect/SPIRV/Serialization/Serializer.cpp2
-rw-r--r--mlir/lib/IR/AsmPrinter.cpp6
-rw-r--r--mlir/lib/IR/Block.cpp11
-rw-r--r--mlir/lib/IR/Operation.cpp26
-rw-r--r--mlir/lib/IR/OperationSupport.cpp15
-rw-r--r--mlir/lib/IR/TypeUtilities.cpp4
-rw-r--r--mlir/lib/IR/Value.cpp4
30 files changed, 370 insertions, 160 deletions
diff --git a/mlir/bindings/python/pybind.cpp b/mlir/bindings/python/pybind.cpp
index 10445edaf12..caff9af59ac 100644
--- a/mlir/bindings/python/pybind.cpp
+++ b/mlir/bindings/python/pybind.cpp
@@ -87,7 +87,8 @@ struct PythonValueHandle {
operator ValueHandle &() { return value; }
std::string str() const {
- return std::to_string(reinterpret_cast<intptr_t>(value.getValue()));
+ return std::to_string(
+ reinterpret_cast<intptr_t>(value.getValue().getAsOpaquePointer()));
}
PythonValueHandle call(const std::vector<PythonValueHandle> &args) {
diff --git a/mlir/include/mlir/Analysis/AffineAnalysis.h b/mlir/include/mlir/Analysis/AffineAnalysis.h
index 5d9422883c1..6029a9ccdaa 100644
--- a/mlir/include/mlir/Analysis/AffineAnalysis.h
+++ b/mlir/include/mlir/Analysis/AffineAnalysis.h
@@ -15,9 +15,7 @@
#ifndef MLIR_ANALYSIS_AFFINE_ANALYSIS_H
#define MLIR_ANALYSIS_AFFINE_ANALYSIS_H
-#include "mlir/Support/LLVM.h"
-#include "mlir/Support/LogicalResult.h"
-#include "llvm/ADT/ArrayRef.h"
+#include "mlir/IR/Value.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
@@ -28,10 +26,9 @@ class AffineForOp;
class AffineValueMap;
class FlatAffineConstraints;
class Operation;
-class Value;
// TODO(riverriddle) Remove this after Value is value-typed.
-using ValuePtr = Value *;
+using ValuePtr = Value;
/// Returns in `affineApplyOps`, the sequence of those AffineApplyOp
/// Operations that are reachable via a search starting from `operands` and
diff --git a/mlir/include/mlir/Analysis/Liveness.h b/mlir/include/mlir/Analysis/Liveness.h
index 791c164c7d2..cbd2e63fd3e 100644
--- a/mlir/include/mlir/Analysis/Liveness.h
+++ b/mlir/include/mlir/Analysis/Liveness.h
@@ -33,7 +33,7 @@ class Region;
class Value;
// TODO(riverriddle) Remove this after Value is value-typed.
-using ValuePtr = Value *;
+using ValuePtr = Value;
/// Represents an analysis for computing liveness information from a
/// given top-level operation. The analysis iterates over all associated
diff --git a/mlir/include/mlir/Analysis/LoopAnalysis.h b/mlir/include/mlir/Analysis/LoopAnalysis.h
index 66f0033bf2f..75d7b98e20f 100644
--- a/mlir/include/mlir/Analysis/LoopAnalysis.h
+++ b/mlir/include/mlir/Analysis/LoopAnalysis.h
@@ -28,7 +28,7 @@ class Operation;
class Value;
// TODO(riverriddle) Remove this after Value is value-typed.
-using ValuePtr = Value *;
+using ValuePtr = Value;
/// Returns the trip count of the loop as an affine map with its corresponding
/// operands if the latter is expressible as an affine expression, and nullptr
diff --git a/mlir/include/mlir/Conversion/AffineToStandard/AffineToStandard.h b/mlir/include/mlir/Conversion/AffineToStandard/AffineToStandard.h
index 8e873bfb1c3..c8298760bad 100644
--- a/mlir/include/mlir/Conversion/AffineToStandard/AffineToStandard.h
+++ b/mlir/include/mlir/Conversion/AffineToStandard/AffineToStandard.h
@@ -22,7 +22,7 @@ class RewritePattern;
class Value;
// TODO(riverriddle) Remove this after Value is value-typed.
-using ValuePtr = Value *;
+using ValuePtr = Value;
// Owning list of rewriting patterns.
class OwningRewritePatternList;
diff --git a/mlir/include/mlir/Conversion/LoopsToGPU/LoopsToGPU.h b/mlir/include/mlir/Conversion/LoopsToGPU/LoopsToGPU.h
index 5f3ea87f3cc..b7423a58f2a 100644
--- a/mlir/include/mlir/Conversion/LoopsToGPU/LoopsToGPU.h
+++ b/mlir/include/mlir/Conversion/LoopsToGPU/LoopsToGPU.h
@@ -16,7 +16,7 @@ struct LogicalResult;
class Value;
// TODO(riverriddle) Remove this after Value is value-typed.
-using ValuePtr = Value *;
+using ValuePtr = Value;
namespace loop {
class ForOp;
diff --git a/mlir/include/mlir/Dialect/VectorOps/Utils.h b/mlir/include/mlir/Dialect/VectorOps/Utils.h
index b4d8ad65e60..04bd8b50fb6 100644
--- a/mlir/include/mlir/Dialect/VectorOps/Utils.h
+++ b/mlir/include/mlir/Dialect/VectorOps/Utils.h
@@ -26,7 +26,7 @@ class Value;
class VectorType;
// TODO(riverriddle) Remove this after Value is value-typed.
-using ValuePtr = Value *;
+using ValuePtr = Value;
/// Computes and returns the multi-dimensional ratio of `superShape` to
/// `subShape`. This is calculated by performing a traversal from minor to major
diff --git a/mlir/include/mlir/EDSC/Builders.h b/mlir/include/mlir/EDSC/Builders.h
index 6607f267057..f9629a8d99e 100644
--- a/mlir/include/mlir/EDSC/Builders.h
+++ b/mlir/include/mlir/EDSC/Builders.h
@@ -329,6 +329,7 @@ public:
/// Implicit conversion useful for automatic conversion to Container<Value>.
operator ValuePtr() const { return getValue(); }
+ operator bool() const { return hasValue(); }
/// Generic mlir::Op create. This is the key to being extensible to the whole
/// of MLIR without duplicating the type system or the op definitions.
diff --git a/mlir/include/mlir/IR/Block.h b/mlir/include/mlir/IR/Block.h
index b5189b48a85..33feea7bcbb 100644
--- a/mlir/include/mlir/IR/Block.h
+++ b/mlir/include/mlir/IR/Block.h
@@ -63,7 +63,7 @@ public:
//===--------------------------------------------------------------------===//
// This is the list of arguments to the block.
- using BlockArgListType = ArrayRef<BlockArgumentPtr>;
+ using BlockArgListType = MutableArrayRef<BlockArgumentPtr>;
BlockArgListType getArguments() { return arguments; }
diff --git a/mlir/include/mlir/IR/BlockAndValueMapping.h b/mlir/include/mlir/IR/BlockAndValueMapping.h
index 82173c34368..b7ad36072bd 100644
--- a/mlir/include/mlir/IR/BlockAndValueMapping.h
+++ b/mlir/include/mlir/IR/BlockAndValueMapping.h
@@ -28,14 +28,18 @@ public:
/// Inserts a new mapping for 'from' to 'to'. If there is an existing mapping,
/// it is overwritten.
void map(Block *from, Block *to) { valueMap[from] = to; }
- void map(ValuePtr from, ValuePtr to) { valueMap[from] = to; }
+ void map(Value from, Value to) {
+ valueMap[from.getAsOpaquePointer()] = to.getAsOpaquePointer();
+ }
/// Erases a mapping for 'from'.
- void erase(IRObjectWithUseList *from) { valueMap.erase(from); }
+ void erase(Block *from) { valueMap.erase(from); }
+ void erase(Value from) { valueMap.erase(from.getAsOpaquePointer()); }
/// Checks to see if a mapping for 'from' exists.
- bool contains(IRObjectWithUseList *from) const {
- return valueMap.count(from);
+ bool contains(Block *from) const { return valueMap.count(from); }
+ bool contains(Value from) const {
+ return valueMap.count(from.getAsOpaquePointer());
}
/// Lookup a mapped value within the map. If a mapping for the provided value
@@ -43,23 +47,19 @@ public:
Block *lookupOrNull(Block *from) const {
return lookupOrValue(from, (Block *)nullptr);
}
- ValuePtr lookupOrNull(ValuePtr from) const {
- return lookupOrValue(from, (ValuePtr) nullptr);
- }
+ Value lookupOrNull(Value from) const { return lookupOrValue(from, Value()); }
/// Lookup a mapped value within the map. If a mapping for the provided value
/// does not exist then return the provided value.
Block *lookupOrDefault(Block *from) const {
return lookupOrValue(from, from);
}
- ValuePtr lookupOrDefault(ValuePtr from) const {
- return lookupOrValue(from, from);
- }
+ Value lookupOrDefault(Value from) const { return lookupOrValue(from, from); }
/// Lookup a mapped value within the map. This asserts the provided value
/// exists within the map.
- template <typename T> T *lookup(T *from) const {
- auto *result = lookupOrNull(from);
+ template <typename T> T lookup(T from) const {
+ auto result = lookupOrNull(from);
assert(result && "expected 'from' to be contained within the map");
return result;
}
@@ -69,14 +69,18 @@ public:
private:
/// Utility lookupOrValue that looks up an existing key or returns the
- /// provided value. This function assumes that if a mapping does exist, then
- /// it is of 'T' type.
- template <typename T> T *lookupOrValue(T *from, T *value) const {
+ /// provided value.
+ Block *lookupOrValue(Block *from, Block *value) const {
auto it = valueMap.find(from);
- return it != valueMap.end() ? static_cast<T *>(it->second) : value;
+ return it != valueMap.end() ? reinterpret_cast<Block *>(it->second) : value;
+ }
+ Value lookupOrValue(Value from, Value value) const {
+ auto it = valueMap.find(from.getAsOpaquePointer());
+ return it != valueMap.end() ? Value::getFromOpaquePointer(it->second)
+ : value;
}
- DenseMap<IRObjectWithUseList *, IRObjectWithUseList *> valueMap;
+ DenseMap<void *, void *> valueMap;
};
} // end namespace mlir
diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index e58a5b07038..8e2aed29500 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -142,17 +142,14 @@ private:
// Make the implementations convenient to use.
inline OpAsmPrinter &operator<<(OpAsmPrinter &p, ValueRef value) {
- p.printOperand(&value);
+ p.printOperand(value);
return p;
}
-inline OpAsmPrinter &operator<<(OpAsmPrinter &p, ValuePtr value) {
- return p << *value;
-}
-template <typename T, typename std::enable_if<
- std::is_convertible<T &, ValueRange>::value &&
- !std::is_convertible<T &, ValuePtr>::value,
- T>::type * = nullptr>
+template <typename T,
+ typename std::enable_if<std::is_convertible<T &, ValueRange>::value &&
+ !std::is_convertible<T &, Value &>::value,
+ T>::type * = nullptr>
inline OpAsmPrinter &operator<<(OpAsmPrinter &p, const T &values) {
p.printOperands(values);
return p;
@@ -172,8 +169,7 @@ inline OpAsmPrinter &operator<<(OpAsmPrinter &p, Attribute attr) {
// even if it isn't exactly one of them. For example, we want to print
// FunctionType with the Type version above, not have it match this.
template <typename T, typename std::enable_if<
- !std::is_convertible<T &, ValueRef>::value &&
- !std::is_convertible<T &, ValuePtr>::value &&
+ !std::is_convertible<T &, Value &>::value &&
!std::is_convertible<T &, Type &>::value &&
!std::is_convertible<T &, Attribute &>::value &&
!std::is_convertible<T &, ValueRange>::value &&
diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h
index 9ab900c8761..29227613468 100644
--- a/mlir/include/mlir/IR/Operation.h
+++ b/mlir/include/mlir/IR/Operation.h
@@ -246,7 +246,7 @@ public:
unsigned getNumResults() { return numResults; }
- ValuePtr getResult(unsigned idx) { return &getOpResult(idx); }
+ ValuePtr getResult(unsigned idx) { return getOpResult(idx); }
/// Support result iteration.
using result_range = ResultRange;
diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index 14681663372..ef2ff44ef6e 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -525,8 +525,8 @@ private:
/// This class implements iteration on the types of a given range of values.
template <typename ValueIteratorT>
class ValueTypeIterator final
- : public llvm::mapped_iterator<ValueIteratorT, Type (*)(ValuePtr)> {
- static Type unwrap(ValuePtr value) { return value->getType(); }
+ : public llvm::mapped_iterator<ValueIteratorT, Type (*)(Value)> {
+ static Type unwrap(Value value) { return value.getType(); }
public:
using reference = Type;
@@ -536,8 +536,7 @@ public:
/// Initializes the type iterator to the specified value iterator.
ValueTypeIterator(ValueIteratorT it)
- : llvm::mapped_iterator<ValueIteratorT, Type (*)(ValuePtr)>(it, &unwrap) {
- }
+ : llvm::mapped_iterator<ValueIteratorT, Type (*)(Value)>(it, &unwrap) {}
};
//===----------------------------------------------------------------------===//
@@ -546,7 +545,7 @@ public:
/// This class implements the operand iterators for the Operation class.
class OperandRange final
: public detail::indexed_accessor_range_base<OperandRange, OpOperand *,
- ValuePtr, ValuePtr, ValuePtr> {
+ Value, Value, Value> {
public:
using RangeBaseT::RangeBaseT;
OperandRange(Operation *op);
@@ -561,7 +560,7 @@ private:
return object + index;
}
/// See `detail::indexed_accessor_range_base` for details.
- static ValuePtr dereference_iterator(OpOperand *object, ptrdiff_t index) {
+ static Value dereference_iterator(OpOperand *object, ptrdiff_t index) {
return object[index].get();
}
@@ -574,8 +573,8 @@ private:
/// This class implements the result iterators for the Operation class.
class ResultRange final
- : public detail::indexed_accessor_range_base<ResultRange, OpResultPtr,
- ValuePtr, ValuePtr, ValuePtr> {
+ : public detail::indexed_accessor_range_base<ResultRange, OpResult *, Value,
+ Value, Value> {
public:
using RangeBaseT::RangeBaseT;
ResultRange(Operation *op);
@@ -586,12 +585,12 @@ public:
private:
/// See `detail::indexed_accessor_range_base` for details.
- static OpResultPtr offset_base(OpResultPtr object, ptrdiff_t index) {
+ static OpResult *offset_base(OpResult *object, ptrdiff_t index) {
return object + index;
}
/// See `detail::indexed_accessor_range_base` for details.
- static ValuePtr dereference_iterator(OpResultPtr object, ptrdiff_t index) {
- return &object[index];
+ static Value dereference_iterator(OpResult *object, ptrdiff_t index) {
+ return object[index];
}
/// Allow access to `offset_base` and `dereference_iterator`.
@@ -608,25 +607,24 @@ private:
/// parameter.
class ValueRange final
: public detail::indexed_accessor_range_base<
- ValueRange, PointerUnion<ValuePtr const *, OpOperand *, OpResultPtr>,
- ValuePtr, ValuePtr, ValuePtr> {
+ ValueRange, PointerUnion<const Value *, OpOperand *, OpResult *>,
+ Value, Value, Value> {
public:
using RangeBaseT::RangeBaseT;
template <typename Arg,
typename = typename std::enable_if_t<
- std::is_constructible<ArrayRef<ValuePtr>, Arg>::value &&
- !std::is_convertible<Arg, ValuePtr>::value>>
- ValueRange(Arg &&arg)
- : ValueRange(ArrayRef<ValuePtr>(std::forward<Arg>(arg))) {}
- ValueRange(ValuePtr const &value) : ValueRange(&value, /*count=*/1) {}
- ValueRange(const std::initializer_list<ValuePtr> &values)
- : ValueRange(ArrayRef<ValuePtr>(values)) {}
+ std::is_constructible<ArrayRef<Value>, Arg>::value &&
+ !std::is_convertible<Arg, Value>::value>>
+ ValueRange(Arg &&arg) : ValueRange(ArrayRef<Value>(std::forward<Arg>(arg))) {}
+ ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {}
+ ValueRange(const std::initializer_list<Value> &values)
+ : ValueRange(ArrayRef<Value>(values)) {}
ValueRange(iterator_range<OperandRange::iterator> values)
: ValueRange(OperandRange(values)) {}
ValueRange(iterator_range<ResultRange::iterator> values)
: ValueRange(ResultRange(values)) {}
- ValueRange(ArrayRef<ValuePtr> values = llvm::None);
+ ValueRange(ArrayRef<Value> values = llvm::None);
ValueRange(OperandRange values);
ValueRange(ResultRange values);
@@ -637,12 +635,12 @@ public:
private:
/// The type representing the owner of this range. This is either a list of
/// values, operands, or results.
- using OwnerT = PointerUnion<ValuePtr const *, OpOperand *, OpResultPtr>;
+ using OwnerT = PointerUnion<const Value *, OpOperand *, OpResult *>;
/// See `detail::indexed_accessor_range_base` for details.
static OwnerT offset_base(const OwnerT &owner, ptrdiff_t index);
/// See `detail::indexed_accessor_range_base` for details.
- static ValuePtr dereference_iterator(const OwnerT &owner, ptrdiff_t index);
+ static Value dereference_iterator(const OwnerT &owner, ptrdiff_t index);
/// Allow access to `offset_base` and `dereference_iterator`.
friend RangeBaseT;
diff --git a/mlir/include/mlir/IR/TypeUtilities.h b/mlir/include/mlir/IR/TypeUtilities.h
index b4713226559..fd9d317ed35 100644
--- a/mlir/include/mlir/IR/TypeUtilities.h
+++ b/mlir/include/mlir/IR/TypeUtilities.h
@@ -33,7 +33,6 @@ Type getElementTypeOrSelf(Type type);
/// Return the element type or return the type itself.
Type getElementTypeOrSelf(Attribute attr);
Type getElementTypeOrSelf(ValuePtr val);
-Type getElementTypeOrSelf(ValueRef val);
/// Get the types within a nested Tuple. A helper for the class method that
/// handles storage concerns, which is tricky to do in tablegen.
diff --git a/mlir/include/mlir/IR/UseDefLists.h b/mlir/include/mlir/IR/UseDefLists.h
index 898d0da2b28..05720ed39af 100644
--- a/mlir/include/mlir/IR/UseDefLists.h
+++ b/mlir/include/mlir/IR/UseDefLists.h
@@ -21,6 +21,7 @@ namespace mlir {
class IROperand;
class Operation;
+class Value;
template <typename OperandType> class ValueUseIterator;
template <typename OperandType> class ValueUserIterator;
@@ -167,6 +168,22 @@ private:
}
};
+/// A reference to a value, suitable for use as an operand of an operation.
+class OpOperand : public IROperand {
+public:
+ OpOperand(Operation *owner) : IROperand(owner) {}
+ OpOperand(Operation *owner, Value value);
+
+ /// Return the current value being used by this operand.
+ Value get();
+
+ /// Set the current value being used by this operand.
+ void set(Value newValue);
+
+ /// Return which operand this is in the operand list of the User.
+ unsigned getOperandNumber();
+};
+
/// A reference to a value, suitable for use as an operand of an operation,
/// operation, etc. IRValueTy is the root type to use for values this tracks,
/// and SSAUserTy is the type that will contain operands.
diff --git a/mlir/include/mlir/IR/Value.h b/mlir/include/mlir/IR/Value.h
index 030e6fa58b1..26703a25306 100644
--- a/mlir/include/mlir/IR/Value.h
+++ b/mlir/include/mlir/IR/Value.h
@@ -25,40 +25,101 @@ class OpResult;
class Region;
class Value;
-/// Using directives that simplify the transition of Value to being value typed.
-using BlockArgumentPtr = BlockArgument *;
-using OpResultPtr = OpResult *;
-using ValueRef = Value &;
-using ValuePtr = Value *;
+namespace detail {
+/// The internal implementation of a Value.
+class ValueImpl : public IRObjectWithUseList {
+protected:
+ /// This enumerates all of the SSA value kinds.
+ enum class Kind {
+ BlockArgument,
+ OpResult,
+ };
+
+ ValueImpl(Kind kind, Type type) : typeAndKind(type, kind) {}
+
+private:
+ /// The type of the value and its kind.
+ llvm::PointerIntPair<Type, 1, Kind> typeAndKind;
+
+ /// Allow access to 'typeAndKind'.
+ friend Value;
+};
-/// Operands contain a Value.
-using OpOperand = IROperandImpl<Value>;
+/// The internal implementation of a BlockArgument.
+class BlockArgumentImpl : public ValueImpl {
+ BlockArgumentImpl(Type type, Block *owner)
+ : ValueImpl(Kind::BlockArgument, type), owner(owner) {}
-/// This is the common base class for all SSA values in the MLIR system,
-/// representing a computable value that has a type and a set of users.
+ /// The owner of this argument.
+ Block *owner;
+
+ /// Allow access to owner and constructor.
+ friend BlockArgument;
+};
+
+class OpResultImpl : public ValueImpl {
+ OpResultImpl(Type type, Operation *owner)
+ : ValueImpl(Kind::OpResult, type), owner(owner) {}
+
+ /// The owner of this result.
+ Operation *owner;
+
+ /// Allow access to owner and the constructor.
+ friend OpResult;
+};
+} // end namespace detail
+
+/// This class represents an instance of an SSA value in the MLIR system,
+/// representing a computable value that has a type and a set of users. An SSA
+/// value is either a BlockArgument or the result of an operation. Note: This
+/// class has value-type semantics and is just a simple wrapper around a
+/// ValueImpl that is either owner by a block(in the case of a BlockArgument) or
+/// an Operation(in the case of an OpResult).
///
-class Value : public IRObjectWithUseList {
+class Value {
public:
/// This enumerates all of the SSA value kinds in the MLIR system.
enum class Kind {
- BlockArgument, // block argument
- OpResult, // operation result
+ BlockArgument,
+ OpResult,
};
+ Value(std::nullptr_t) : impl(nullptr) {}
+ Value(detail::ValueImpl *impl = nullptr) : impl(impl) {}
+ Value(const Value &) = default;
+ Value &operator=(const Value &) = default;
~Value() {}
- template <typename U> bool isa() const { return U::classof(this); }
- template <typename U> U *dyn_cast() const {
- return isa<U>() ? (U *)this : nullptr;
+ template <typename U> bool isa() const {
+ assert(impl && "isa<> used on a null type.");
+ return U::classof(*this);
+ }
+ template <typename U> U dyn_cast() const {
+ return isa<U>() ? U(impl) : U(nullptr);
}
- template <typename U> U *cast() const {
+ template <typename U> U dyn_cast_or_null() const {
+ return (impl && isa<U>()) ? U(impl) : U(nullptr);
+ }
+ template <typename U> U cast() const {
assert(isa<U>());
- return (U *)this;
+ return U(impl);
}
- Kind getKind() const { return typeAndKind.getInt(); }
+ /// Temporary methods to enable transition of Value to being used as a
+ /// value-type.
+ /// TODO(riverriddle) Remove these when all usages have been removed.
+ Value operator*() const { return *this; }
+ Value *operator->() const { return (Value *)this; }
+
+ operator bool() const { return impl; }
+ bool operator==(const Value &other) const { return impl == other.impl; }
+ bool operator!=(const Value &other) const { return !(*this == other); }
- Type getType() const { return typeAndKind.getPointer(); }
+ /// Return the kind of this value.
+ Kind getKind() const { return (Kind)impl->typeAndKind.getInt(); }
+
+ /// Return the type of this value.
+ Type getType() const { return impl->typeAndKind.getPointer(); }
/// Utility to get the associated MLIRContext that this value is defined in.
MLIRContext *getContext() const { return getType().getContext(); }
@@ -69,18 +130,18 @@ public:
/// completely invalid IR very easily. It is strongly recommended that you
/// recreate IR objects with the right types instead of mutating them in
/// place.
- void setType(Type newType) { typeAndKind.setPointer(newType); }
+ void setType(Type newType) { impl->typeAndKind.setPointer(newType); }
/// Replace all uses of 'this' value with the new value, updating anything in
/// the IR that uses 'this' to use the other value instead. When this returns
/// there are zero uses of 'this'.
- void replaceAllUsesWith(ValuePtr newValue) {
- IRObjectWithUseList::replaceAllUsesWith(newValue);
+ void replaceAllUsesWith(Value newValue) const {
+ impl->replaceAllUsesWith(newValue.impl);
}
/// If this value is the result of an operation, return the operation that
/// defines it.
- Operation *getDefiningOp();
+ Operation *getDefiningOp() const;
/// If this value is the result of an operation, use it as a location,
/// otherwise return an unknown location.
@@ -98,24 +159,51 @@ public:
/// Returns a range of all uses, which is useful for iterating over all uses.
inline use_range getUses();
+ using user_iterator = ValueUserIterator<IROperand>;
+ using user_range = iterator_range<user_iterator>;
+
+ user_iterator user_begin() const { return impl->user_begin(); }
+ user_iterator user_end() const { return impl->user_end(); }
+
+ /// Returns a range of all users.
+ user_range getUsers() const { return impl->getUsers(); }
+
+ /// Returns true if this value has no uses.
+ bool use_empty() const { return impl->use_empty(); }
+
+ /// Returns true if this value has exactly one use.
+ bool hasOneUse() const { return impl->hasOneUse(); }
+
+ /// Drop all uses of this object from their respective owners.
+ void dropAllUses() const { impl->dropAllUses(); }
+
void print(raw_ostream &os);
void dump();
+ /// Methods for supporting PointerLikeTypeTraits.
+ void *getAsOpaquePointer() const { return static_cast<void *>(impl); }
+ static Value getFromOpaquePointer(const void *pointer) {
+ return reinterpret_cast<detail::ValueImpl *>(const_cast<void *>(pointer));
+ }
+
+ friend ::llvm::hash_code hash_value(Value arg);
+
protected:
- Value(Kind kind, Type type) : typeAndKind(type, kind) {}
+ /// The internal implementation of this value.
+ mutable detail::ValueImpl *impl;
-private:
- llvm::PointerIntPair<Type, 1, Kind> typeAndKind;
+ /// Allow access to 'impl'.
+ friend OpOperand;
};
-inline raw_ostream &operator<<(raw_ostream &os, ValueRef value) {
+inline raw_ostream &operator<<(raw_ostream &os, Value value) {
value.print(os);
return os;
}
// Utility functions for iterating through Value uses.
inline auto Value::use_begin() -> use_iterator {
- return use_iterator((OpOperand *)getFirstUse());
+ return use_iterator((OpOperand *)impl->getFirstUse());
}
inline auto Value::use_end() -> use_iterator { return use_iterator(nullptr); }
@@ -127,47 +215,154 @@ inline auto Value::getUses() -> iterator_range<use_iterator> {
/// Block arguments are values.
class BlockArgument : public Value {
public:
- static bool classof(const Value *value) {
- return const_cast<Value *>(value)->getKind() == Kind::BlockArgument;
+ using Value::Value;
+
+ /// Temporary methods to enable transition of Value to being used as a
+ /// value-type.
+ /// TODO(riverriddle) Remove this when all usages have been removed.
+ BlockArgument *operator->() { return this; }
+
+ static bool classof(Value value) {
+ return value.getKind() == Kind::BlockArgument;
}
- Block *getOwner() { return owner; }
+ /// Returns the block that owns this argument.
+ Block *getOwner() const { return getImpl()->owner; }
/// Returns the number of this argument.
- unsigned getArgNumber();
+ unsigned getArgNumber() const;
private:
- friend class Block; // For access to private constructor.
- BlockArgument(Type type, Block *owner)
- : Value(Value::Kind::BlockArgument, type), owner(owner) {}
-
- /// The owner of this operand.
- /// TODO: can encode this more efficiently to avoid the space hit of this
- /// through bitpacking shenanigans.
- Block *const owner;
+ /// Allocate a new argument with the given type and owner.
+ static BlockArgument create(Type type, Block *owner) {
+ return new detail::BlockArgumentImpl(type, owner);
+ }
+
+ /// Destroy and deallocate this argument.
+ void destroy() { delete getImpl(); }
+
+ /// Get a raw pointer to the internal implementation.
+ detail::BlockArgumentImpl *getImpl() const {
+ return reinterpret_cast<detail::BlockArgumentImpl *>(impl);
+ }
+
+ /// Allow access to `create` and `destroy`.
+ friend Block;
};
/// This is a value defined by a result of an operation.
class OpResult : public Value {
public:
- OpResult(Type type, Operation *owner)
- : Value(Value::Kind::OpResult, type), owner(owner) {}
+ using Value::Value;
- static bool classof(const Value *value) {
- return const_cast<Value *>(value)->getKind() == Kind::OpResult;
- }
+ /// Temporary methods to enable transition of Value to being used as a
+ /// value-type.
+ /// TODO(riverriddle) Remove these when all usages have been removed.
+ OpResult *operator*() { return this; }
+ OpResult *operator->() { return this; }
+
+ static bool classof(Value value) { return value.getKind() == Kind::OpResult; }
- Operation *getOwner() { return owner; }
+ /// Returns the operation that owns this result.
+ Operation *getOwner() const { return getImpl()->owner; }
/// Returns the number of this result.
- unsigned getResultNumber();
+ unsigned getResultNumber() const;
private:
- /// The owner of this operand.
- /// TODO: can encode this more efficiently to avoid the space hit of this
- /// through bitpacking shenanigans.
- Operation *const owner;
+ /// Allocate a new result with the given type and owner.
+ static OpResult create(Type type, Operation *owner) {
+ return new detail::OpResultImpl(type, owner);
+ }
+
+ /// Destroy and deallocate this result.
+ void destroy() { delete getImpl(); }
+
+ /// Get a raw pointer to the internal implementation.
+ detail::OpResultImpl *getImpl() const {
+ return reinterpret_cast<detail::OpResultImpl *>(impl);
+ }
+
+ /// Allow access to `create` and `destroy`.
+ friend Operation;
};
+
+/// Make Value hashable.
+inline ::llvm::hash_code hash_value(Value arg) {
+ return ::llvm::hash_value(arg.impl);
+}
+
+/// Using directives that simplify the transition of Value to being value typed.
+using BlockArgumentPtr = BlockArgument;
+using OpResultPtr = OpResult;
+using ValueRef = Value;
+using ValuePtr = Value;
+
} // namespace mlir
+namespace llvm {
+
+template <> struct DenseMapInfo<mlir::Value> {
+ static mlir::Value getEmptyKey() {
+ auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
+ return mlir::Value(static_cast<mlir::detail::ValueImpl *>(pointer));
+ }
+ static mlir::Value getTombstoneKey() {
+ auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
+ return mlir::Value(static_cast<mlir::detail::ValueImpl *>(pointer));
+ }
+ static unsigned getHashValue(mlir::Value val) {
+ return mlir::hash_value(val);
+ }
+ static bool isEqual(mlir::Value LHS, mlir::Value RHS) { return LHS == RHS; }
+};
+
+/// Allow stealing the low bits of a value.
+template <> struct PointerLikeTypeTraits<mlir::Value> {
+public:
+ static inline void *getAsVoidPointer(mlir::Value I) {
+ return const_cast<void *>(I.getAsOpaquePointer());
+ }
+ static inline mlir::Value getFromVoidPointer(void *P) {
+ return mlir::Value::getFromOpaquePointer(P);
+ }
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<mlir::detail::ValueImpl *>::NumLowBitsAvailable
+ };
+};
+
+template <> struct DenseMapInfo<mlir::BlockArgument> {
+ static mlir::BlockArgument getEmptyKey() {
+ auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
+ return mlir::BlockArgument(static_cast<mlir::detail::ValueImpl *>(pointer));
+ }
+ static mlir::BlockArgument getTombstoneKey() {
+ auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
+ return mlir::BlockArgument(static_cast<mlir::detail::ValueImpl *>(pointer));
+ }
+ static unsigned getHashValue(mlir::BlockArgument val) {
+ return mlir::hash_value(val);
+ }
+ static bool isEqual(mlir::BlockArgument LHS, mlir::BlockArgument RHS) {
+ return LHS == RHS;
+ }
+};
+
+/// Allow stealing the low bits of a value.
+template <> struct PointerLikeTypeTraits<mlir::BlockArgument> {
+public:
+ static inline void *getAsVoidPointer(mlir::Value I) {
+ return const_cast<void *>(I.getAsOpaquePointer());
+ }
+ static inline mlir::BlockArgument getFromVoidPointer(void *P) {
+ return mlir::Value::getFromOpaquePointer(P).cast<mlir::BlockArgument>();
+ }
+ enum {
+ NumLowBitsAvailable =
+ PointerLikeTypeTraits<mlir::detail::ValueImpl *>::NumLowBitsAvailable
+ };
+};
+} // end namespace llvm
+
#endif
diff --git a/mlir/lib/Analysis/AffineStructures.cpp b/mlir/lib/Analysis/AffineStructures.cpp
index 7ab547483cd..ce96a19751f 100644
--- a/mlir/lib/Analysis/AffineStructures.cpp
+++ b/mlir/lib/Analysis/AffineStructures.cpp
@@ -1965,7 +1965,7 @@ void FlatAffineConstraints::addLocalFloorDiv(ArrayRef<int64_t> dividend,
bool FlatAffineConstraints::findId(ValueRef id, unsigned *pos) const {
unsigned i = 0;
for (const auto &mayBeId : ids) {
- if (mayBeId.hasValue() && mayBeId.getValue() == &id) {
+ if (mayBeId.hasValue() && mayBeId.getValue() == id) {
*pos = i;
return true;
}
@@ -1976,7 +1976,7 @@ bool FlatAffineConstraints::findId(ValueRef id, unsigned *pos) const {
bool FlatAffineConstraints::containsId(ValueRef id) const {
return llvm::any_of(ids, [&](const Optional<ValuePtr> &mayBeId) {
- return mayBeId.hasValue() && mayBeId.getValue() == &id;
+ return mayBeId.hasValue() && mayBeId.getValue() == id;
});
}
diff --git a/mlir/lib/Analysis/Dominance.cpp b/mlir/lib/Analysis/Dominance.cpp
index 060a505593a..ea1501e8998 100644
--- a/mlir/lib/Analysis/Dominance.cpp
+++ b/mlir/lib/Analysis/Dominance.cpp
@@ -129,7 +129,7 @@ bool DominanceInfo::properlyDominates(ValuePtr a, Operation *b) {
// block arguments properly dominate all operations in their own block, so
// we use a dominates check here, not a properlyDominates check.
- return dominates(cast<BlockArgument>(a)->getOwner(), b->getBlock());
+ return dominates(a.cast<BlockArgument>()->getOwner(), b->getBlock());
}
DominanceInfoNode *DominanceInfo::getNode(Block *a) {
diff --git a/mlir/lib/Analysis/Liveness.cpp b/mlir/lib/Analysis/Liveness.cpp
index bef0b9fa385..9b7b806c558 100644
--- a/mlir/lib/Analysis/Liveness.cpp
+++ b/mlir/lib/Analysis/Liveness.cpp
@@ -174,7 +174,7 @@ Liveness::OperationListT Liveness::resolveLiveness(ValuePtr value) const {
if (Operation *defOp = value->getDefiningOp())
currentBlock = defOp->getBlock();
else
- currentBlock = cast<BlockArgument>(value)->getOwner();
+ currentBlock = value.cast<BlockArgument>()->getOwner();
toProcess.push_back(currentBlock);
visited.insert(currentBlock);
@@ -272,7 +272,7 @@ void Liveness::print(raw_ostream &os) const {
if (Operation *defOp = value->getDefiningOp())
os << "val_" << defOp->getName();
else {
- auto blockArg = cast<BlockArgument>(value);
+ auto blockArg = value.cast<BlockArgument>();
os << "arg" << blockArg->getArgNumber() << "@"
<< blockIds[blockArg->getOwner()];
}
diff --git a/mlir/lib/Analysis/SliceAnalysis.cpp b/mlir/lib/Analysis/SliceAnalysis.cpp
index befe3d39759..89ee613b370 100644
--- a/mlir/lib/Analysis/SliceAnalysis.cpp
+++ b/mlir/lib/Analysis/SliceAnalysis.cpp
@@ -96,7 +96,7 @@ static void getBackwardSliceImpl(Operation *op,
for (auto en : llvm::enumerate(op->getOperands())) {
auto operand = en.value();
- if (auto blockArg = dyn_cast<BlockArgument>(operand)) {
+ if (auto blockArg = operand.dyn_cast<BlockArgument>()) {
if (auto affIv = getForInductionVarOwner(operand)) {
auto *affOp = affIv.getOperation();
if (backwardSlice->count(affOp) == 0)
diff --git a/mlir/lib/Dialect/AffineOps/AffineOps.cpp b/mlir/lib/Dialect/AffineOps/AffineOps.cpp
index bfe72101e85..d80f9865ccb 100644
--- a/mlir/lib/Dialect/AffineOps/AffineOps.cpp
+++ b/mlir/lib/Dialect/AffineOps/AffineOps.cpp
@@ -107,7 +107,7 @@ static bool isFunctionRegion(Region *region) {
/// function. A value of index type defined at the top level is always a valid
/// symbol.
bool mlir::isTopLevelValue(ValuePtr value) {
- if (auto arg = dyn_cast<BlockArgument>(value))
+ if (auto arg = value.dyn_cast<BlockArgument>())
return isFunctionRegion(arg->getOwner()->getParent());
return isFunctionRegion(value->getDefiningOp()->getParentRegion());
}
@@ -134,7 +134,7 @@ bool mlir::isValidDim(ValuePtr value) {
return false;
}
// This value has to be a block argument for a FuncOp or an affine.for.
- auto *parentOp = cast<BlockArgument>(value)->getOwner()->getParentOp();
+ auto *parentOp = value.cast<BlockArgument>()->getOwner()->getParentOp();
return isa<FuncOp>(parentOp) || isa<AffineForOp>(parentOp);
}
@@ -1571,7 +1571,7 @@ bool mlir::isForInductionVar(ValuePtr val) {
/// Returns the loop parent of an induction variable. If the provided value is
/// not an induction variable, then return nullptr.
AffineForOp mlir::getForInductionVarOwner(ValuePtr val) {
- auto ivArg = dyn_cast<BlockArgument>(val);
+ auto ivArg = val.dyn_cast<BlockArgument>();
if (!ivArg || !ivArg->getOwner())
return AffineForOp();
auto *containingInst = ivArg->getOwner()->getParent()->getParentOp();
diff --git a/mlir/lib/Dialect/Linalg/Analysis/DependenceAnalysis.cpp b/mlir/lib/Dialect/Linalg/Analysis/DependenceAnalysis.cpp
index 5fbbdea60c2..be90b1ce5a6 100644
--- a/mlir/lib/Dialect/Linalg/Analysis/DependenceAnalysis.cpp
+++ b/mlir/lib/Dialect/Linalg/Analysis/DependenceAnalysis.cpp
@@ -41,7 +41,7 @@ static StringRef toStringRef(LinalgDependenceGraph::DependenceType dt) {
}
ValuePtr Aliases::find(ValuePtr v) {
- if (isa<BlockArgument>(v))
+ if (v.isa<BlockArgument>())
return v;
auto it = aliases.find(v);
@@ -51,7 +51,7 @@ ValuePtr Aliases::find(ValuePtr v) {
}
while (true) {
- if (isa<BlockArgument>(v))
+ if (v.isa<BlockArgument>())
return v;
if (auto alloc = dyn_cast_or_null<AllocOp>(v->getDefiningOp())) {
if (isStrided(alloc.getType()))
diff --git a/mlir/lib/Dialect/LoopOps/LoopOps.cpp b/mlir/lib/Dialect/LoopOps/LoopOps.cpp
index d3040c1bbb2..8e19eba911a 100644
--- a/mlir/lib/Dialect/LoopOps/LoopOps.cpp
+++ b/mlir/lib/Dialect/LoopOps/LoopOps.cpp
@@ -136,7 +136,7 @@ LogicalResult ForOp::moveOutOfLoop(ArrayRef<Operation *> ops) {
}
ForOp mlir::loop::getForInductionVarOwner(ValuePtr val) {
- auto ivArg = dyn_cast<BlockArgument>(val);
+ auto ivArg = val.dyn_cast<BlockArgument>();
if (!ivArg)
return ForOp();
assert(ivArg->getOwner() && "unlinked block argument");
diff --git a/mlir/lib/Dialect/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Dialect/SPIRV/Serialization/Serializer.cpp
index 7ff471dfda5..424c2e0427e 100644
--- a/mlir/lib/Dialect/SPIRV/Serialization/Serializer.cpp
+++ b/mlir/lib/Dialect/SPIRV/Serialization/Serializer.cpp
@@ -509,7 +509,7 @@ void Serializer::printValueIDMap(raw_ostream &os) {
<< "id = " << valueIDPair.second << ' ';
if (auto *op = val->getDefiningOp()) {
os << "from op '" << op->getName() << "'";
- } else if (auto arg = dyn_cast<BlockArgument>(val)) {
+ } else if (auto arg = val.dyn_cast<BlockArgument>()) {
Block *block = arg->getOwner();
os << "from argument of block " << block << ' ';
os << " in op '" << block->getParentOp()->getName() << "'";
diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index a574f87c530..4eeb5e4e95c 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -1612,7 +1612,7 @@ void OperationPrinter::numberValuesInRegion(Region &region) {
void OperationPrinter::numberValuesInBlock(Block &block) {
auto setArgNameFn = [&](ValuePtr arg, StringRef name) {
assert(!valueIDs.count(arg) && "arg numbered multiple times");
- assert(cast<BlockArgument>(arg)->getOwner() == &block &&
+ assert(arg.cast<BlockArgument>()->getOwner() == &block &&
"arg not defined in 'block'");
setValueName(arg, name);
};
@@ -1658,7 +1658,7 @@ void OperationPrinter::numberValuesInOp(Operation &op) {
setValueName(result, name);
// Record the result number for groups not anchored at 0.
- if (int resultNo = cast<OpResult>(result)->getResultNumber())
+ if (int resultNo = result.cast<OpResult>()->getResultNumber())
resultGroups.push_back(resultNo);
};
@@ -1831,7 +1831,7 @@ void OperationPrinter::printValueIDImpl(ValuePtr value, bool printResultNo,
// If this is a reference to the result of a multi-result operation or
// operation, print out the # identifier and make sure to map our lookup
// to the first result of the operation.
- if (OpResultPtr result = dyn_cast<OpResult>(value))
+ if (OpResultPtr result = value.dyn_cast<OpResult>())
getResultIDAndNumber(result, lookupValue, resultNo);
auto it = valueIDs.find(lookupValue);
diff --git a/mlir/lib/IR/Block.cpp b/mlir/lib/IR/Block.cpp
index b168a8facd2..3abbe1027ce 100644
--- a/mlir/lib/IR/Block.cpp
+++ b/mlir/lib/IR/Block.cpp
@@ -16,10 +16,10 @@ using namespace mlir;
//===----------------------------------------------------------------------===//
/// Returns the number of this argument.
-unsigned BlockArgument::getArgNumber() {
+unsigned BlockArgument::getArgNumber() const {
// Arguments are not stored in place, so we have to find it within the list.
auto argList = getOwner()->getArguments();
- return std::distance(argList.begin(), llvm::find(argList, this));
+ return std::distance(argList.begin(), llvm::find(argList, *this));
}
//===----------------------------------------------------------------------===//
@@ -29,7 +29,8 @@ unsigned BlockArgument::getArgNumber() {
Block::~Block() {
assert(!verifyOpOrder() && "Expected valid operation ordering.");
clear();
- llvm::DeleteContainerPointers(arguments);
+ for (BlockArgument arg : arguments)
+ arg.destroy();
}
Region *Block::getParent() const { return parentValidOpOrderPair.getPointer(); }
@@ -143,7 +144,7 @@ void Block::recomputeOpOrder() {
//===----------------------------------------------------------------------===//
BlockArgumentPtr Block::addArgument(Type type) {
- auto *arg = new BlockArgument(type, this);
+ BlockArgument arg = BlockArgument::create(type, this);
arguments.push_back(arg);
return arg;
}
@@ -163,7 +164,7 @@ void Block::eraseArgument(unsigned index, bool updatePredTerms) {
assert(index < arguments.size());
// Delete the argument.
- delete arguments[index];
+ arguments[index].destroy();
arguments.erase(arguments.begin() + index);
// If we aren't updating predecessors, there is nothing left to do.
diff --git a/mlir/lib/IR/Operation.cpp b/mlir/lib/IR/Operation.cpp
index 1dc7cb4bafd..77288b228aa 100644
--- a/mlir/lib/IR/Operation.cpp
+++ b/mlir/lib/IR/Operation.cpp
@@ -68,23 +68,29 @@ OperationName OperationName::getFromOpaquePointer(void *pointer) {
//===----------------------------------------------------------------------===//
/// Return the result number of this result.
-unsigned OpResult::getResultNumber() {
- // Results are always stored consecutively, so use pointer subtraction to
- // figure out what number this is.
- return this - &getOwner()->getOpResults()[0];
+unsigned OpResult::getResultNumber() const {
+ // Results are not stored in place, so we have to find it within the list.
+ auto resList = getOwner()->getOpResults();
+ return std::distance(resList.begin(), llvm::find(resList, *this));
}
//===----------------------------------------------------------------------===//
// OpOperand
//===----------------------------------------------------------------------===//
-// TODO: This namespace is only required because of a bug in GCC<7.0.
-namespace mlir {
+OpOperand::OpOperand(Operation *owner, Value value)
+ : IROperand(owner, value.impl) {}
+
+/// Return the current value being used by this operand.
+Value OpOperand::get() { return (detail::ValueImpl *)IROperand::get(); }
+
+/// Set the current value being used by this operand.
+void OpOperand::set(Value newValue) { IROperand::set(newValue.impl); }
+
/// Return which operand this is in the operand list.
-template <> unsigned OpOperand::getOperandNumber() {
+unsigned OpOperand::getOperandNumber() {
return this - &getOwner()->getOpOperands()[0];
}
-} // end namespace mlir
//===----------------------------------------------------------------------===//
// BlockOperand
@@ -179,7 +185,7 @@ Operation *Operation::create(Location location, OperationName name,
auto instResults = op->getOpResults();
for (unsigned i = 0, e = resultTypes.size(); i != e; ++i)
- new (&instResults[i]) OpResult(resultTypes[i], op);
+ new (&instResults[i]) OpResult(OpResult::create(resultTypes[i], op));
auto opOperands = op->getOpOperands();
@@ -256,7 +262,7 @@ Operation::~Operation() {
getOperandStorage().~OperandStorage();
for (auto &result : getOpResults())
- result.~OpResult();
+ result.destroy();
// Explicitly run the destructors for the successors.
for (auto &successor : getBlockOperands())
diff --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index 1c68686a0cb..5dfd3b02cc6 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -155,7 +155,7 @@ ResultRange::ResultRange(Operation *op)
//===----------------------------------------------------------------------===//
// ValueRange
-ValueRange::ValueRange(ArrayRef<ValuePtr> values)
+ValueRange::ValueRange(ArrayRef<Value> values)
: ValueRange(values.data(), values.size()) {}
ValueRange::ValueRange(OperandRange values)
: ValueRange(values.begin().getBase(), values.size()) {}
@@ -167,19 +167,18 @@ ValueRange::OwnerT ValueRange::offset_base(const OwnerT &owner,
ptrdiff_t index) {
if (OpOperand *operand = owner.dyn_cast<OpOperand *>())
return operand + index;
- if (OpResultPtr result = owner.dyn_cast<OpResultPtr>())
+ if (OpResult *result = owner.dyn_cast<OpResult *>())
return result + index;
- return owner.get<ValuePtr const *>() + index;
+ return owner.get<const Value *>() + index;
}
/// See `detail::indexed_accessor_range_base` for details.
-ValuePtr ValueRange::dereference_iterator(const OwnerT &owner,
- ptrdiff_t index) {
+Value ValueRange::dereference_iterator(const OwnerT &owner, ptrdiff_t index) {
// Operands access the held value via 'get'.
if (OpOperand *operand = owner.dyn_cast<OpOperand *>())
return operand[index].get();
// An OpResult is a value, so we can return it directly.
- if (OpResultPtr result = owner.dyn_cast<OpResultPtr>())
- return &result[index];
+ if (OpResult *result = owner.dyn_cast<OpResult *>())
+ return result[index];
// Otherwise, this is a raw value array so just index directly.
- return owner.get<ValuePtr const *>()[index];
+ return owner.get<const Value *>()[index];
}
diff --git a/mlir/lib/IR/TypeUtilities.cpp b/mlir/lib/IR/TypeUtilities.cpp
index 8bc67e46fdc..1fa13a85c51 100644
--- a/mlir/lib/IR/TypeUtilities.cpp
+++ b/mlir/lib/IR/TypeUtilities.cpp
@@ -28,10 +28,6 @@ Type mlir::getElementTypeOrSelf(ValuePtr val) {
return getElementTypeOrSelf(val->getType());
}
-Type mlir::getElementTypeOrSelf(ValueRef val) {
- return getElementTypeOrSelf(val.getType());
-}
-
Type mlir::getElementTypeOrSelf(Attribute attr) {
return getElementTypeOrSelf(attr.getType());
}
diff --git a/mlir/lib/IR/Value.cpp b/mlir/lib/IR/Value.cpp
index d723eec8b29..ffb9601f1c9 100644
--- a/mlir/lib/IR/Value.cpp
+++ b/mlir/lib/IR/Value.cpp
@@ -13,8 +13,8 @@ using namespace mlir;
/// If this value is the result of an Operation, return the operation that
/// defines it.
-Operation *Value::getDefiningOp() {
- if (auto *result = dyn_cast<OpResult>())
+Operation *Value::getDefiningOp() const {
+ if (auto result = dyn_cast<OpResult>())
return result->getOwner();
return nullptr;
}
OpenPOWER on IntegriCloud