21static bool isScalarLikeType(
Type type) {
29 if (!varName.empty()) {
30 auto varNameAttr = acc::VarNameAttr::get(builder.
getContext(), varName);
36struct MemRefPointerLikeModel
37 :
public PointerLikeType::ExternalModel<MemRefPointerLikeModel<T>, T> {
39 return cast<T>(pointer).getElementType();
42 mlir::acc::VariableTypeCategory
45 if (
auto mappableTy = dyn_cast<MappableType>(varType)) {
46 return mappableTy.getTypeCategory(varPtr);
48 auto memrefTy = cast<T>(pointer);
49 if (!memrefTy.hasRank()) {
52 return mlir::acc::VariableTypeCategory::uncategorized;
55 if (memrefTy.getRank() == 0) {
56 if (isScalarLikeType(memrefTy.getElementType())) {
57 return mlir::acc::VariableTypeCategory::scalar;
61 return mlir::acc::VariableTypeCategory::uncategorized;
65 assert(memrefTy.getRank() > 0 &&
"rank expected to be positive");
66 return mlir::acc::VariableTypeCategory::array;
69 mlir::Value genAllocate(Type pointer, OpBuilder &builder, Location loc,
70 StringRef varName, Type varType, Value originalVar,
71 bool &needsFree)
const {
72 auto memrefTy = cast<MemRefType>(pointer);
76 if (memrefTy.hasStaticShape()) {
78 auto allocaOp = memref::AllocaOp::create(builder, loc, memrefTy);
79 attachVarNameAttr(allocaOp, builder, varName);
80 return allocaOp.getResult();
85 if (originalVar && originalVar.
getType() == memrefTy &&
87 SmallVector<Value> dynamicSizes;
88 for (int64_t i = 0; i < memrefTy.getRank(); ++i) {
89 if (memrefTy.isDynamicDim(i)) {
93 memref::DimOp::create(builder, loc, originalVar, indexValue);
94 dynamicSizes.push_back(dimSize);
101 memref::AllocOp::create(builder, loc, memrefTy, dynamicSizes);
102 attachVarNameAttr(allocOp, builder, varName);
103 return allocOp.getResult();
110 bool genFree(Type pointer, OpBuilder &builder, Location loc,
112 Type varType)
const {
115 Value valueToInspect = allocRes ? allocRes : memrefValue;
118 Value currentValue = valueToInspect;
119 Operation *originalAlloc =
nullptr;
123 while (currentValue) {
126 if (isa<memref::AllocOp, memref::AllocaOp>(definingOp)) {
127 originalAlloc = definingOp;
132 if (
auto castOp = dyn_cast<memref::CastOp>(definingOp)) {
133 currentValue = castOp.getSource();
138 if (
auto reinterpretCastOp =
139 dyn_cast<memref::ReinterpretCastOp>(definingOp)) {
140 currentValue = reinterpretCastOp.getSource();
152 if (isa<memref::AllocaOp>(originalAlloc)) {
156 if (isa<memref::AllocOp>(originalAlloc)) {
158 memref::DeallocOp::create(builder, loc, memrefValue);
167 bool genCopy(Type pointer, OpBuilder &builder, Location loc,
171 auto destMemref = dyn_cast_if_present<TypedValue<MemRefType>>(destination);
172 auto srcMemref = dyn_cast_if_present<TypedValue<MemRefType>>(source);
178 if (destMemref && srcMemref &&
179 destMemref.getType().getElementType() ==
180 srcMemref.getType().getElementType() &&
181 destMemref.getType().getShape() == srcMemref.getType().getShape()) {
182 memref::CopyOp::create(builder, loc, srcMemref, destMemref);
189 mlir::Value
genLoad(Type pointer, OpBuilder &builder, Location loc,
191 Type valueType)
const {
196 auto memrefValue = dyn_cast_if_present<TypedValue<MemRefType>>(srcPtr);
200 auto memrefTy = memrefValue.
getType();
203 if (memrefTy.getRank() != 0)
206 return memref::LoadOp::create(builder, loc, memrefValue,
ValueRange{});
209 bool genStore(Type pointer, OpBuilder &builder, Location loc,
215 auto memrefValue = dyn_cast_if_present<TypedValue<MemRefType>>(destPtr);
219 auto memrefTy = memrefValue.getType();
222 if (memrefTy.getRank() != 0)
225 memref::StoreOp::create(builder, loc, valueToStore, memrefValue);
229 Value
genCast(Type, OpBuilder &builder, Location loc, Value value,
230 Type resultType)
const {
231 if (value.
getType() == resultType)
234 if (isa<BaseMemRefType>(value.
getType()) &&
235 isa<BaseMemRefType>(resultType)) {
238 return memref::CastOp::create(builder, loc, resultType, value);
239 if (memref::MemorySpaceCastOp::areCastCompatible(
241 return memref::MemorySpaceCastOp::create(builder, loc, resultType,
248 if (
auto resPtrLike = dyn_cast<PointerLikeType>(resultType))
249 if (!isa<BaseMemRefType>(resPtrLike))
250 if (Value v = resPtrLike.genCast(builder, loc, value, resultType))
252 if (
auto valPtrLike = dyn_cast<PointerLikeType>(value.
getType()))
253 if (!isa<BaseMemRefType>(valPtrLike))
254 if (Value v = valPtrLike.genCast(builder, loc, value, resultType))
260 bool isDeviceAccessible(Type pointer, Value var,
261 SymbolTableCollection *symbolTables)
const {
262 auto memrefTy = cast<T>(pointer);
263 Attribute memSpace = memrefTy.getMemorySpace();
264 return isa_and_nonnull<gpu::AddressSpaceAttr>(memSpace);
267 MemRefType getAsMemRefType(Type pointer, ModuleOp module)
const {
269 return dyn_cast<MemRefType>(pointer);
273struct MemrefAddressOfGlobalModel
274 :
public AddressOfGlobalOpInterface::ExternalModel<
275 MemrefAddressOfGlobalModel, memref::GetGlobalOp> {
276 SymbolRefAttr getSymbol(Operation *op)
const {
277 auto getGlobalOp = cast<memref::GetGlobalOp>(op);
278 return getGlobalOp.getNameAttr();
282struct MemrefGlobalVariableModel
283 :
public GlobalVariableOpInterface::ExternalModel<MemrefGlobalVariableModel,
285 bool isConstant(Operation *op)
const {
286 auto globalOp = cast<memref::GlobalOp>(op);
287 return globalOp.getConstant();
290 bool hasInitializer(Operation *op)
const {
291 auto globalOp = cast<memref::GlobalOp>(op);
292 return globalOp.getInitialValue().has_value();
295 Region *getInitRegion(Operation *op)
const {
300 bool isDeviceAccessible(Operation *op)
const {
301 auto globalOp = cast<memref::GlobalOp>(op);
302 Attribute memSpace = globalOp.getType().getMemorySpace();
303 return isa_and_nonnull<gpu::AddressSpaceAttr>(memSpace);
306 bool isInDeviceMemory(Operation *op)
const {
310 return isDeviceAccessible(op);
313 bool isCompilerGenerated(Operation *op)
const {
return false; }
323 MemRefType::attachInterface<MemRefPointerLikeModel<MemRefType>>(*ctx);
324 UnrankedMemRefType::attachInterface<
325 MemRefPointerLikeModel<UnrankedMemRefType>>(*ctx);
326 memref::GetGlobalOp::attachInterface<MemrefAddressOfGlobalModel>(*ctx);
327 memref::GlobalOp::attachInterface<MemrefGlobalVariableModel>(*ctx);
static Type getElementType(Type type, ArrayRef< int32_t > indices, function_ref< InFlightDiagnostic(StringRef)> emitErrorFn)
Walks the given type hierarchy with the given indices, potentially down to component granularity,...
static void genStore(OpBuilder &builder, Location loc, Value val, Value mem, Value idx)
Generates a store with proper index typing and proper value.
static Value genLoad(OpBuilder &builder, Location loc, Value mem, Value idx)
Generates a load with proper index typing.
MLIRContext * getContext() const
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
MLIRContext is the top-level object for a collection of MLIR operations.
T * getOrLoadDialect()
Get (or create) a dialect for the given derived dialect type.
This class helps build Operations.
Operation is the basic unit of execution within MLIR.
void setDiscardableAttr(StringAttr name, Attribute value)
Set a discardable attribute by name.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool isIntOrIndexOrFloat() const
Return true if this is an integer (of any signedness), index, or float type.
Type getType() const
Return the type of this value.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
static ConstantIndexOp create(OpBuilder &builder, Location location, int64_t value)
void registerMemRefInterfaces(DialectRegistry ®istry)
Register OpenACC interfaces for MemRef IR.
static constexpr StringLiteral getVarNameAttrName()
Value genCast(OpBuilder &builder, Location loc, Value value, Type dstTy)
Add type casting between arith and index types when needed.
Include the generated interface declarations.
std::conditional_t< std::is_same_v< Ty, mlir::Type >, mlir::Value, detail::TypedValue< Ty > > TypedValue
If Ty is mlir::Type this will select Value instead of having a wrapper around it.