MLIR 24.0.0git
OpenACCUtilsType.cpp
Go to the documentation of this file.
1//===- OpenACCUtilsType.cpp - OpenACC Type Utilities ----------------------===//
2//
3// Part of the LLVM 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
15#include "mlir/IR/Builders.h"
16#include "mlir/IR/BuiltinOps.h"
19
20namespace mlir {
21namespace acc {
22
23static std::optional<TypeSizeAndAlignment>
24getTypeSizeAndAlignmentHelper(Type ty, ModuleOp module, const DataLayout &dl,
25 OpenACCSupport *support) {
26 if (support)
27 return support->getTypeSizeAndAlignment(ty, module);
28 return getTypeSizeAndAlignment(ty, module, dl);
29}
30
31std::optional<TypeSizeAndAlignment>
32getTypeSizeAndAlignment(Type ty, ModuleOp module, const DataLayout &dl,
33 OpenACCSupport *support, Value var) {
34 if (ty.isIntOrIndexOrFloat() ||
35 isa<ComplexType, VectorType, DataLayoutTypeInterface>(ty))
37 dl.getTypeSize(ty),
38 llvm::TypeSize::getFixed(dl.getTypeABIAlignment(ty))};
39
40 // Product of element size and static dimensions; no inter-element padding or
41 // array alignment rules are applied. This is acceptable as per API
42 // documentation.
43 if (auto memrefTy = dyn_cast<MemRefType>(ty)) {
44 if (!memrefTy.hasStaticShape())
45 return std::nullopt;
46 auto elemSizeAndAlignment = getTypeSizeAndAlignmentHelper(
47 memrefTy.getElementType(), module, dl, support);
48 if (!elemSizeAndAlignment)
49 return std::nullopt;
50 int64_t totalSize = elemSizeAndAlignment->first.getFixedValue();
51 int64_t alignment = elemSizeAndAlignment->second.getFixedValue();
52 for (int64_t dim : memrefTy.getShape())
53 totalSize *= dim;
54 return TypeSizeAndAlignment{llvm::TypeSize::getFixed(totalSize),
55 llvm::TypeSize::getFixed(alignment)};
56 }
57
58 // Sum of member sizes with no padding between members or tuple alignment
59 // rules applied. This is acceptable as per API documentation.
60 if (auto tupleTy = dyn_cast<TupleType>(ty)) {
61 if (tupleTy.size() == 0)
62 return std::nullopt;
63 auto sizeAndAlignment =
64 getTypeSizeAndAlignmentHelper(tupleTy.getType(0), module, dl, support);
65 if (!sizeAndAlignment)
66 return std::nullopt;
67 llvm::TypeSize size = sizeAndAlignment->first;
68 for (unsigned i = 1, e = tupleTy.size(); i < e; ++i) {
69 auto next = getTypeSizeAndAlignmentHelper(tupleTy.getType(i), module, dl,
70 support);
71 if (!next)
72 return std::nullopt;
73 size += next->first;
74 }
75 return TypeSizeAndAlignment{size, sizeAndAlignment->second};
76 }
77
78 if (isa<FunctionType>(ty))
80 LLVM::LLVMPointerType::get(ty.getContext()), module, dl, support);
81
82 // Mapped-object size for MappableType when a value is available.
83 if (var) {
84 if (auto mappableTy = dyn_cast<MappableType>(ty)) {
85 std::optional<llvm::TypeSize> size =
86 mappableTy.getSizeInBytes(var, /*accBounds=*/{}, dl);
87 if (!size || size->isScalable())
88 return std::nullopt;
89 llvm::TypeSize alignment = llvm::TypeSize::getFixed(1);
90 if (ty.isIntOrIndexOrFloat() || isa<DataLayoutTypeInterface>(ty))
91 alignment = llvm::TypeSize::getFixed(dl.getTypeABIAlignment(ty));
92 return TypeSizeAndAlignment{*size, alignment};
93 }
94 }
95
96 return std::nullopt;
97}
98
99std::optional<TypeSizeAndAlignment>
100getTypeSizeAndAlignment(Type ty, ModuleOp module, OpenACCSupport *support,
101 Value var) {
102 std::optional<DataLayout> dl = getDataLayout(module);
103 if (!dl)
104 return std::nullopt;
105 return getTypeSizeAndAlignment(ty, module, *dl, support, var);
106}
107
109 Type resultType) {
110 if (value.getType() == resultType)
111 return value;
112 if (PointerLikeType ptrLike = dyn_cast<PointerLikeType>(value.getType())) {
113 if (Value casted = ptrLike.genCast(builder, loc, value, resultType))
114 return casted;
115 }
116 if (PointerLikeType ptrLike = dyn_cast<PointerLikeType>(resultType)) {
117 if (Value casted = ptrLike.genCast(builder, loc, value, resultType))
118 return casted;
119 }
120 emitError(loc) << "unsupported pointer-like type cast from "
121 << value.getType() << " to " << resultType;
122 return value;
123}
124
125} // namespace acc
126} // namespace mlir
The main mechanism for performing data layout queries.
llvm::TypeSize getTypeSize(Type t) const
Returns the size of the given type in the current scope.
uint64_t getTypeABIAlignment(Type t) const
Returns the required alignment of the given type in the current scope.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
This class helps build Operations.
Definition Builders.h:210
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
Definition Types.cpp:35
bool isIntOrIndexOrFloat() const
Return true if this is an integer (of any signedness), index, or float type.
Definition Types.cpp:122
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Type getType() const
Return the type of this value.
Definition Value.h:105
std::optional< TypeSizeAndAlignment > getTypeSizeAndAlignment(Type ty, ModuleOp module)
Returns the size and ABI alignment in bytes for ty.
std::optional< DataLayout > getDataLayout(Operation *op, bool allowDefault=true)
Get the data layout for an operation.
static std::optional< TypeSizeAndAlignment > getTypeSizeAndAlignmentHelper(Type ty, ModuleOp module, const DataLayout &dl, OpenACCSupport *support)
Value castPointerLikeTypeIfNeeded(OpBuilder &builder, Location loc, Value value, Type resultType)
Cast value to resultType via PointerLikeType::genCast when needed.
std::pair< llvm::TypeSize, llvm::TypeSize > TypeSizeAndAlignment
std::optional< TypeSizeAndAlignment > getTypeSizeAndAlignment(Type ty, ModuleOp module, const DataLayout &dl, OpenACCSupport *support=nullptr, Value var={})
Returns the size and ABI alignment in bytes.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.