Skip to content

Commit

Permalink
ReImplement the Value classes as value-typed objects wrapping an inte…
Browse files Browse the repository at this point in the history
…rnal pointer storage.

This will enable future commits to reimplement the internal implementation of OpResult without needing to change all of the existing users. This is part of a chain of commits optimizing the size of operation results.

PiperOrigin-RevId: 286919966
  • Loading branch information
River707 authored and tensorflower-gardener committed Dec 23, 2019
1 parent 56222a0 commit f603a50
Show file tree
Hide file tree
Showing 30 changed files with 370 additions and 160 deletions.
3 changes: 2 additions & 1 deletion mlir/bindings/python/pybind.cpp
Expand Up @@ -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) {
Expand Down
7 changes: 2 additions & 5 deletions mlir/include/mlir/Analysis/AffineAnalysis.h
Expand Up @@ -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"

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Analysis/Liveness.h
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Analysis/LoopAnalysis.h
Expand Up @@ -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
Expand Down
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Conversion/LoopsToGPU/LoopsToGPU.h
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/Dialect/VectorOps/Utils.h
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions mlir/include/mlir/EDSC/Builders.h
Expand Up @@ -329,6 +329,7 @@ class ValueHandle : public CapturableHandle {

/// 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.
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/IR/Block.h
Expand Up @@ -63,7 +63,7 @@ class Block : public IRObjectWithUseList,
//===--------------------------------------------------------------------===//

// This is the list of arguments to the block.
using BlockArgListType = ArrayRef<BlockArgumentPtr>;
using BlockArgListType = MutableArrayRef<BlockArgumentPtr>;

BlockArgListType getArguments() { return arguments; }

Expand Down
38 changes: 21 additions & 17 deletions mlir/include/mlir/IR/BlockAndValueMapping.h
Expand Up @@ -28,38 +28,38 @@ class BlockAndValueMapping {
/// 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
/// does not exist then return nullptr.
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;
}
Expand All @@ -69,14 +69,18 @@ class BlockAndValueMapping {

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
Expand Down
16 changes: 6 additions & 10 deletions mlir/include/mlir/IR/OpImplementation.h
Expand Up @@ -142,17 +142,14 @@ class OpAsmPrinter {

// 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;
Expand All @@ -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 &&
Expand Down
2 changes: 1 addition & 1 deletion mlir/include/mlir/IR/Operation.h
Expand Up @@ -246,7 +246,7 @@ class Operation final

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;
Expand Down
44 changes: 21 additions & 23 deletions mlir/include/mlir/IR/OperationSupport.h
Expand Up @@ -525,8 +525,8 @@ class OpPrintingFlags {
/// 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;
Expand All @@ -536,8 +536,7 @@ class ValueTypeIterator final

/// 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) {}
};

//===----------------------------------------------------------------------===//
Expand All @@ -546,7 +545,7 @@ class ValueTypeIterator final
/// 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);
Expand All @@ -561,7 +560,7 @@ class OperandRange final
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();
}

Expand All @@ -574,8 +573,8 @@ class OperandRange final

/// 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);
Expand All @@ -586,12 +585,12 @@ class ResultRange final

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`.
Expand All @@ -608,25 +607,24 @@ class ResultRange final
/// 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);

Expand All @@ -637,12 +635,12 @@ class ValueRange final
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;
Expand Down
1 change: 0 additions & 1 deletion mlir/include/mlir/IR/TypeUtilities.h
Expand Up @@ -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.
Expand Down
17 changes: 17 additions & 0 deletions mlir/include/mlir/IR/UseDefLists.h
Expand Up @@ -21,6 +21,7 @@ namespace mlir {

class IROperand;
class Operation;
class Value;
template <typename OperandType> class ValueUseIterator;
template <typename OperandType> class ValueUserIterator;

Expand Down Expand Up @@ -167,6 +168,22 @@ class IROperand {
}
};

/// 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.
Expand Down

0 comments on commit f603a50

Please sign in to comment.