Revert "Remove use of tuple for multiresult type storage"

This reverts commit 08f0764ff5.
This commit is contained in:
Jacques Pienaar 2021-03-01 10:39:41 -08:00
parent 283db5f083
commit 87e05eb03b
3 changed files with 39 additions and 45 deletions

View File

@ -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 @@ private:
/// 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 @@ private:
/// 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 @@ private:
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) {

View File

@ -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) {

View File

@ -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 different 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