[Mlir-commits] [mlir] 87e05eb - Revert "Remove use of tuple for multiresult type storage"
Jacques Pienaar
llvmlistbot at llvm.org
Mon Mar 1 10:39:55 PST 2021
Author: Jacques Pienaar
Date: 2021-03-01T10:39:41-08:00
New Revision: 87e05eb03b1b58b9c1184d688868ab153d53000d
URL: https://github.com/llvm/llvm-project/commit/87e05eb03b1b58b9c1184d688868ab153d53000d
DIFF: https://github.com/llvm/llvm-project/commit/87e05eb03b1b58b9c1184d688868ab153d53000d.diff
LOG: Revert "Remove use of tuple for multiresult type storage"
This reverts commit 08f0764ff551c5aa2486c40871453e1ff40fb679.
Added:
Modified:
mlir/include/mlir/IR/Operation.h
mlir/lib/IR/Operation.cpp
mlir/lib/IR/Value.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h
index 5cc1639b240db..63a94d971da71 100644
--- a/mlir/include/mlir/IR/Operation.h
+++ b/mlir/include/mlir/IR/Operation.h
@@ -27,7 +27,7 @@ namespace mlir {
/// 'Block' class.
class alignas(8) Operation final
: public llvm::ilist_node_with_parent<Operation, Block>,
- private llvm::TrailingObjects<Operation, BlockOperand, Region, Type,
+ private llvm::TrailingObjects<Operation, BlockOperand, Region,
detail::OperandStorage> {
public:
/// Create a new Operation with the specific fields.
@@ -651,7 +651,7 @@ class alignas(8) Operation final
/// Returns a pointer to the use list for the given trailing result.
detail::TrailingOpResult *getTrailingResult(unsigned resultNumber) {
- // Trailing results are stored in reverse order after (before in memory) the
+ // Trailing results are stored in reverse order after(before in memory) the
// inline results.
return reinterpret_cast<detail::TrailingOpResult *>(
getInlineResult(OpResult::getMaxInlineResults() - 1)) -
@@ -695,18 +695,11 @@ class alignas(8) Operation final
/// states recorded here:
/// - 0 results : The type below is null.
/// - 1 result : The single result type is held here.
- /// - N results : The type here is empty and instead the result types are held
- /// in trailing storage.
+ /// - N results : The type here is a tuple holding the result types.
+ /// Note: We steal a bit for 'hasSingleResult' from somewhere else so that we
+ /// can use 'resultType` in an ArrayRef<Type>.
bool hasSingleResult : 1;
-
- /// Union representing either the Type of a single result operation (if
- /// hasSingleResult) or the number of result types for multi-result.
- union {
- // Type, set if single result Operation.
- Type type = nullptr;
- // Size, set if not a single result Operation.
- unsigned size;
- } resultTypeOrSize;
+ Type resultType;
/// This holds the name of the operation.
OperationName name;
@@ -727,15 +720,12 @@ class alignas(8) Operation final
friend class llvm::ilist_node_with_parent<Operation, Block>;
// This stuff is used by the TrailingObjects template.
- friend llvm::TrailingObjects<Operation, BlockOperand, Region, Type,
+ friend llvm::TrailingObjects<Operation, BlockOperand, Region,
detail::OperandStorage>;
size_t numTrailingObjects(OverloadToken<BlockOperand>) const {
return numSuccs;
}
size_t numTrailingObjects(OverloadToken<Region>) const { return numRegions; }
- size_t numTrailingObjects(OverloadToken<Type>) const {
- return hasSingleResult ? 0 : resultTypeOrSize.size;
- }
};
inline raw_ostream &operator<<(raw_ostream &os, Operation &op) {
diff --git a/mlir/lib/IR/Operation.cpp b/mlir/lib/IR/Operation.cpp
index b074a675f2ff1..b1f2ad66efdb4 100644
--- a/mlir/lib/IR/Operation.cpp
+++ b/mlir/lib/IR/Operation.cpp
@@ -123,11 +123,8 @@ Operation *Operation::create(Location location, OperationName name,
// into account the size of the operation, its trailing objects, and its
// prefixed objects.
size_t byteSize =
- totalSizeToAlloc<BlockOperand, Region, Type, detail::OperandStorage>(
- numSuccessors, numRegions,
- // Result type storage only needed if there is not 0 or 1 results.
- resultTypes.size() == 1 ? 0 : resultTypes.size(),
- needsOperandStorage ? 1 : 0) +
+ totalSizeToAlloc<BlockOperand, Region, detail::OperandStorage>(
+ numSuccessors, numRegions, needsOperandStorage ? 1 : 0) +
detail::OperandStorage::additionalAllocSize(numOperands);
size_t prefixByteSize = llvm::alignTo(
Operation::prefixAllocSize(numTrailingResults, numInlineResults),
@@ -175,18 +172,13 @@ Operation::Operation(Location location, OperationName name,
assert(attributes && "unexpected null attribute dictionary");
assert(llvm::all_of(resultTypes, [](Type t) { return t; }) &&
"unexpected null result type");
- if (resultTypes.empty()) {
- resultTypeOrSize.size = 0;
- } else {
- // If there is a single result it is stored in-place, otherwise use trailing
- // type storage.
+ if (!resultTypes.empty()) {
+ // If there is a single result it is stored in-place, otherwise use a tuple.
hasSingleResult = resultTypes.size() == 1;
- if (hasSingleResult) {
- resultTypeOrSize.type = resultTypes.front();
- } else {
- resultTypeOrSize.size = resultTypes.size();
- llvm::copy(resultTypes, getTrailingObjects<Type>());
- }
+ if (hasSingleResult)
+ resultType = resultTypes.front();
+ else
+ resultType = TupleType::get(location->getContext(), resultTypes);
}
}
@@ -553,15 +545,17 @@ void Operation::dropAllDefinedValueUses() {
/// Return the number of results held by this operation.
unsigned Operation::getNumResults() {
- if (hasSingleResult)
- return 1;
- return resultTypeOrSize.size;
+ if (!resultType)
+ return 0;
+ return hasSingleResult ? 1 : resultType.cast<TupleType>().size();
}
auto Operation::getResultTypes() -> result_type_range {
+ if (!resultType)
+ return llvm::None;
if (hasSingleResult)
- return resultTypeOrSize.type;
- return ArrayRef<Type>(getTrailingObjects<Type>(), resultTypeOrSize.size);
+ return resultType;
+ return resultType.cast<TupleType>().getTypes();
}
void Operation::setSuccessor(Block *block, unsigned index) {
diff --git a/mlir/lib/IR/Value.cpp b/mlir/lib/IR/Value.cpp
index c6d3e58573437..fd7e5b5d64e5f 100644
--- a/mlir/lib/IR/Value.cpp
+++ b/mlir/lib/IR/Value.cpp
@@ -39,21 +39,31 @@ Type Value::getType() const {
OpResult result = cast<OpResult>();
Operation *owner = result.getOwner();
if (owner->hasSingleResult)
- return owner->resultTypeOrSize.type;
- return owner->getResultTypes()[result.getResultNumber()];
+ return owner->resultType;
+ return owner->resultType.cast<TupleType>().getType(result.getResultNumber());
}
/// Mutate the type of this Value to be of the specified type.
void Value::setType(Type newType) {
if (BlockArgument arg = dyn_cast<BlockArgument>())
return arg.setType(newType);
-
OpResult result = cast<OpResult>();
+
+ // If the owner has a single result, simply update it directly.
Operation *owner = result.getOwner();
- if (owner->hasSingleResult)
- owner->resultTypeOrSize.type = newType;
- else
- owner->getTrailingObjects<Type>()[result.getResultNumber()] = newType;
+ if (owner->hasSingleResult) {
+ owner->resultType = newType;
+ return;
+ }
+ unsigned resultNo = result.getResultNumber();
+
+ // Otherwise, rebuild the tuple if the new type is
diff erent from the current.
+ auto curTypes = owner->resultType.cast<TupleType>().getTypes();
+ if (curTypes[resultNo] == newType)
+ return;
+ auto newTypes = llvm::to_vector<4>(curTypes);
+ newTypes[resultNo] = newType;
+ owner->resultType = TupleType::get(newType.getContext(), newTypes);
}
/// If this value is the result of an Operation, return the operation that
More information about the Mlir-commits
mailing list