MLIR 24.0.0git
ACCDataRuntime.cpp
Go to the documentation of this file.
1//===- ACCDataRuntime.cpp - Emit OpenACC data runtime arguments -*- C++ -*-===//
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//
9// Builds the mapping argument arrays used by OpenACC data runtime entry points.
10//
11//===----------------------------------------------------------------------===//
12
15
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/Support/Debug.h"
24
25#include <algorithm>
26
27#define DEBUG_TYPE "acc-data-runtime"
28
29using namespace mlir;
30using namespace mlir::acc;
31
32static Value remap(Value value, ConversionPatternRewriter &rewriter) {
33 if (!value)
34 return {};
35 if (Value converted = rewriter.getRemappedValue(value))
36 return converted;
37 return value;
38}
39
41 ConversionPatternRewriter &rewriter) {
42 return LLVM::ConstantOp::create(rewriter, loc, rewriter.getI64Type(), value);
43}
44
45static Value getPointer(Location loc, Value value,
46 ConversionPatternRewriter &rewriter) {
47 Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
48 if (!value)
49 return LLVM::ZeroOp::create(rewriter, loc, ptrTy);
50 if (value.getType() == ptrTy)
51 return value;
52
53 if (isa<PointerLikeType>(value.getType()))
54 return castPointerLikeTypeIfNeeded(rewriter, loc, value, ptrTy);
55
56 Value one = LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(), 1);
57 Value storage =
58 LLVM::AllocaOp::create(rewriter, loc, ptrTy, value.getType(), one);
59 LLVM::StoreOp::create(rewriter, loc, value, storage);
60 return storage;
61}
62
63/// Returns the address of a slot holding \p value, so that the runtime reads
64/// the value from memory rather than receiving it directly.
66 ConversionPatternRewriter &rewriter) {
67 Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
68 Value one = LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(), 1);
69 Value storage =
70 LLVM::AllocaOp::create(rewriter, loc, ptrTy, value.getType(), one);
71 LLVM::StoreOp::create(rewriter, loc, value, storage);
72 return storage;
73}
74
76 ArrayRef<Value> values, RewriterBase &rewriter) {
77 Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
78 Type i32Ty = rewriter.getI32Type();
79 Value count = LLVM::ConstantOp::create(rewriter, loc, i32Ty, values.size());
80 Value array =
81 LLVM::AllocaOp::create(rewriter, loc, ptrTy, elementType, count);
82 for (auto [index, value] : llvm::enumerate(values)) {
83 Value indexValue = LLVM::ConstantOp::create(rewriter, loc, i32Ty, index);
84 Value element = LLVM::GEPOp::create(rewriter, loc, ptrTy, elementType,
85 array, ValueRange{indexValue});
86 LLVM::StoreOp::create(rewriter, loc, value, element);
87 }
88 return array;
89}
90
91/// The address of the mapped object, as the runtime expects to receive it.
92/// Privatized storage only ever exists on the device, so there is no host
93/// address to give. A device address names storage the runtime must not look
94/// up, and an object mapped by value has no address at all, so both are handed
95/// over in a slot the runtime reads them from.
97 Value converted, MapFlags mapFlags,
98 ConversionPatternRewriter &rewriter) {
99 Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
100 if (isa<PrivateType>(operand.getType()))
101 return LLVM::ZeroOp::create(rewriter, loc, ptrTy);
102 if (converted && converted.getType() == ptrTy &&
103 bitEnumContainsAny(mapFlags, MapFlags::devptr))
104 return getIndirectPointer(loc, converted, rewriter);
105 return getPointer(loc, converted, rewriter);
106}
107
108static std::optional<MapFlags> computePackedMapFlags(Operation *mapOp) {
109 if (auto mapInfo = dyn_cast<MapInfoOp>(mapOp))
110 return mapInfo.getMapFlags();
111 if (isa<ACC_DATA_ENTRY_OPS>(mapOp))
112 return computeDataClauseMapFlags(mapOp, hasAttachPoint(mapOp));
113 return std::nullopt;
114}
115
116static Value getMapSize(Operation *mapOp, Value converted, MapFlags mapFlags,
117 OpenACCSupport &accSupport,
118 ConversionPatternRewriter &rewriter) {
119 Location loc = mapOp->getLoc();
120 ModuleOp module = mapOp->getParentOfType<ModuleOp>();
121 // An object mapped by value is passed as the argument itself, so its size is
122 // the size of what is passed and not of the object it was read from. The two
123 // differ when the argument holds one field of a decomposed aggregate.
124 if (bitEnumContainsAny(mapFlags, MapFlags::literal) && converted) {
125 if (auto sizeAndAlignment = acc::getTypeSizeAndAlignment(
126 converted.getType(), module, &accSupport))
127 return constantI64(loc, sizeAndAlignment->first.getFixedValue(),
128 rewriter);
129 }
130 if (Value size = acc::getMapSize(mapOp))
131 return castToI64(loc, remap(size, rewriter), rewriter);
132
133 Value var = acc::getVar(mapOp);
134 if (!var)
135 return constantI64(loc, 0, rewriter);
136 Type varType = acc::getVarType(mapOp);
137 if (!varType)
138 varType = var.getType();
139 // A memref is handed over with a descriptor stating its extents and element
140 // size, which is what states the size of such a mapping.
141 if (isa<MemRefType>(var.getType()) || isa<MemRefType>(varType))
142 return constantI64(loc, 0, rewriter);
143
144 // A data clause operation that was not turned into an `acc.map_info` has no
145 // size of its own, so it is sized the way that operation would have been.
146 // A size that is not statically known is left to the runtime, as an unsized
147 // mapping is.
148 int64_t size =
150 acc::getBounds(mapOp), &accSupport);
151 return constantI64(loc, std::max<int64_t>(size, 0), rewriter);
152}
153
154static Value getElementSize(Operation *mapOp, OpenACCSupport &accSupport,
155 ConversionPatternRewriter &rewriter) {
156 Location loc = mapOp->getLoc();
157 ModuleOp module = mapOp->getParentOfType<ModuleOp>();
158 if (std::optional<int64_t> size = acc::getMapElementSize(mapOp))
159 return constantI64(loc, *size, rewriter);
160
161 Type type = acc::getVarType(mapOp);
162 if (auto shaped = dyn_cast<ShapedType>(type))
163 type = shaped.getElementType();
164 if (!type)
165 return constantI64(loc, 0, rewriter);
166 if (auto sizeAndAlignment =
167 acc::getTypeSizeAndAlignment(type, module, &accSupport))
168 return constantI64(loc, sizeAndAlignment->first.getFixedValue(), rewriter);
169 return constantI64(loc, 0, rewriter);
170}
171
173 ConversionPatternRewriter &rewriter) {
174 if (!value)
175 return constantI64(loc, 0, rewriter);
176 return castToI64(loc, remap(value, rewriter), rewriter);
177}
178
180 Type baseDescriptorType, uint32_t version,
181 ValueRange bounds, Value elementSize,
182 ConversionPatternRewriter &rewriter) {
183 MLIRContext *context = rewriter.getContext();
184 Type i8Ty = rewriter.getI8Type();
185 Type i32Ty = rewriter.getI32Type();
186 Type i64Ty = rewriter.getI64Type();
187 Type ptrTy = LLVM::LLVMPointerType::get(context);
188
189 Value versionValue = LLVM::ConstantOp::create(
190 rewriter, loc, i32Ty,
191 version | static_cast<uint32_t>(
192 getDataDescriptorKind(DataDescriptor::AccDataDescOpenACC)));
193 baseDescriptor = LLVM::InsertValueOp::create(
194 rewriter, loc, baseDescriptorType, baseDescriptor, versionValue,
196
197 Type descriptorType = getDataDescriptorType(
198 context, DataDescriptor::AccDataDescOpenACC, baseDescriptorType);
199 Value descriptor = LLVM::ZeroOp::create(rewriter, loc, descriptorType);
200 Value rank = LLVM::ConstantOp::create(rewriter, loc, i8Ty, bounds.size());
201
202 SmallVector<Value> lowerBounds;
203 SmallVector<Value> upperBounds;
204 SmallVector<Value> extents;
205 SmallVector<Value> strides;
206 SmallVector<Value> starts;
207 for (Value boundValue : bounds) {
208 auto bound = cast<DataBoundsOp>(boundValue.getDefiningOp());
209 lowerBounds.push_back(
210 getBoundValue(bound.getLowerbound(), bound.getLoc(), rewriter));
211 upperBounds.push_back(
212 getBoundValue(bound.getUpperbound(), bound.getLoc(), rewriter));
213 Value sourceExtent =
214 bound.getSourceExtent() ? bound.getSourceExtent() : bound.getExtent();
215 extents.push_back(getBoundValue(sourceExtent, bound.getLoc(), rewriter));
216 Value stride = getBoundValue(bound.getStride(), bound.getLoc(), rewriter);
217 if (!bound.getStrideInBytes())
218 stride =
219 LLVM::MulOp::create(rewriter, bound.getLoc(), stride, elementSize);
220 strides.push_back(stride);
221 starts.push_back(
222 getBoundValue(bound.getStartIdx(), bound.getLoc(), rewriter));
223 }
224
225 Value lowerBoundsArray =
226 createACCDataArray(loc, i64Ty, lowerBounds, rewriter);
227 Value upperBoundsArray =
228 createACCDataArray(loc, i64Ty, upperBounds, rewriter);
229 Value extentsArray = createACCDataArray(loc, i64Ty, extents, rewriter);
230 Value stridesArray = createACCDataArray(loc, i64Ty, strides, rewriter);
231 Value startsArray = createACCDataArray(loc, i64Ty, starts, rewriter);
232
233 using Field = AccDataDescOpenACCField;
234 auto insert = [&](Value value, Field field) {
235 descriptor = LLVM::InsertValueOp::create(
236 rewriter, loc, descriptorType, descriptor, value,
238 };
239 insert(baseDescriptor, Field::Base);
240 insert(rank, Field::Rank);
241 insert(elementSize, Field::ElementSize);
242 insert(lowerBoundsArray, Field::LowerBounds);
243 insert(upperBoundsArray, Field::UpperBounds);
244 insert(extentsArray, Field::Extents);
245 insert(stridesArray, Field::StridesInBytes);
246 insert(startsArray, Field::StartIndices);
247
248 Value one = LLVM::ConstantOp::create(rewriter, loc, i32Ty, 1);
249 Value storage =
250 LLVM::AllocaOp::create(rewriter, loc, ptrTy, descriptorType, one);
251 LLVM::StoreOp::create(rewriter, loc, descriptor, storage);
252 return storage;
253}
254
256 Location loc, MemRefType memrefType, Value convertedMemref,
257 ValueRange bounds, Value elementSize, ConversionPatternRewriter &rewriter) {
258 MLIRContext *context = rewriter.getContext();
259 Type i8Ty = rewriter.getI8Type();
260 Type i32Ty = rewriter.getI32Type();
261 Type ptrTy = LLVM::LLVMPointerType::get(context);
262 using Field = AccDataDescMemRefField;
263 Type descriptorType =
264 getDataDescriptorType(context, DataDescriptor::AccDataDescMemRef);
265 auto version = static_cast<uint32_t>(
266 getDataDescriptorKind(DataDescriptor::AccDataDescMemRef));
267 Value descriptor = LLVM::ZeroOp::create(rewriter, loc, descriptorType);
268 Value rank =
269 LLVM::ConstantOp::create(rewriter, loc, i8Ty, memrefType.getRank());
270 auto insert = [&](Value value, Field field) {
271 descriptor = LLVM::InsertValueOp::create(
272 rewriter, loc, descriptorType, descriptor, value,
274 };
275 insert(rank, Field::Rank);
276 insert(elementSize, Field::ElementSize);
277 insert(getPointer(loc, convertedMemref, rewriter), Field::MemRefDescriptor);
278 if (!bounds.empty())
279 return createACCDataDescriptor(loc, descriptor, descriptorType, version,
280 bounds, elementSize, rewriter);
281
282 insert(LLVM::ConstantOp::create(rewriter, loc, i32Ty, version),
283 Field::Version);
284 Value one = LLVM::ConstantOp::create(rewriter, loc, i32Ty, 1);
285 Value storage =
286 LLVM::AllocaOp::create(rewriter, loc, ptrTy, descriptorType, one);
287 LLVM::StoreOp::create(rewriter, loc, descriptor, storage);
288 return storage;
289}
290
292 Value convertedOperand,
293 OpenACCSupport &accSupport,
294 ConversionPatternRewriter &rewriter) {
295 Location loc = mapOp->getLoc();
296 MLIRContext *context = rewriter.getContext();
297 Type i32Ty = rewriter.getI32Type();
298 Type ptrTy = LLVM::LLVMPointerType::get(context);
299 SmallVector<Value> bounds = acc::getBounds(mapOp);
300 DataDescKind descKind = acc::getDataDescKind(mapOp);
301 // Only a descriptor stating bounds reads the element size, so it is
302 // materialized where it is used, leaving no constant behind for a mapping
303 // that needs no descriptor at all.
304 auto elementSize = [&] {
305 return getElementSize(mapOp, accSupport, rewriter);
306 };
307
308 Value var = acc::getVar(mapOp);
309 if (var && isa<MemRefType>(var.getType())) {
310 auto memrefType = cast<MemRefType>(var.getType());
312 loc, memrefType, convertedOperand, bounds, elementSize(), rewriter);
313 }
314
315 if (bitEnumContainsAny(descKind, DataDescKind::cfi)) {
316 using Field = AccDataDescCFIField;
317 Type descriptorType =
318 getDataDescriptorType(context, DataDescriptor::AccDataDescCFI);
319 auto version = static_cast<uint32_t>(
320 getDataDescriptorKind(DataDescriptor::AccDataDescCFI));
321 Value descriptor = LLVM::ZeroOp::create(rewriter, loc, descriptorType);
322 Value descriptorStorage = remap(acc::getDesc(mapOp), rewriter);
323 if (!descriptorStorage)
324 descriptorStorage = convertedOperand;
325 descriptor = LLVM::InsertValueOp::create(
326 rewriter, loc, descriptorType, descriptor,
327 getPointer(loc, descriptorStorage, rewriter),
328 ArrayRef<int64_t>{getDataDescriptorFieldIndex(Field::CFIDescriptor)});
329 if (!bounds.empty())
330 return createACCDataDescriptor(loc, descriptor, descriptorType, version,
331 bounds, elementSize(), rewriter);
332
333 Value versionValue =
334 LLVM::ConstantOp::create(rewriter, loc, i32Ty, version);
335 descriptor = LLVM::InsertValueOp::create(
336 rewriter, loc, descriptorType, descriptor, versionValue,
338 Value one = LLVM::ConstantOp::create(rewriter, loc, i32Ty, 1);
339 Value storage =
340 LLVM::AllocaOp::create(rewriter, loc, ptrTy, descriptorType, one);
341 LLVM::StoreOp::create(rewriter, loc, descriptor, storage);
342 return storage;
343 }
344
345 if (!bounds.empty()) {
346 Type descriptorType =
347 getDataDescriptorType(context, DataDescriptor::AccDataDescGeneric);
348 auto version = static_cast<uint32_t>(
349 getDataDescriptorKind(DataDescriptor::AccDataDescGeneric));
350 Value descriptor = LLVM::ZeroOp::create(rewriter, loc, descriptorType);
351 return createACCDataDescriptor(loc, descriptor, descriptorType, version,
352 bounds, elementSize(), rewriter);
353 }
354 return LLVM::ZeroOp::create(rewriter, loc, ptrTy);
355}
356
361
363 Location loc, ValueRange mappingOperands, ValueRange convertedOperands,
364 ConversionPatternRewriter &rewriter, Region &globalSymbolRegion,
365 acc::OpenACCSupport &accSupport, const acc::ACCRuntimeCallConfig &config,
366 ACCDataRuntimeArgs &runtimeArgs, ACCDataCallKind callKind,
367 SymbolTable *symbolTable) {
368 if (mappingOperands.size() != convertedOperands.size())
369 return failure();
370
371 Type i32Ty = rewriter.getI32Type();
372 Type i64Ty = rewriter.getI64Type();
373 Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
374
375 runtimeArgs.ident =
376 createIdent(loc, getParentFunctionName(mappingOperands), rewriter,
377 globalSymbolRegion, config, symbolTable);
378 runtimeArgs.flags = constantI64(loc, 0, rewriter);
379 runtimeArgs.deviceType = constantI64(
380 loc, config.getDeviceTypeRuntimeValue(DeviceType::None), rewriter);
381 runtimeArgs.argMappers = LLVM::ZeroOp::create(rewriter, loc, ptrTy);
382
383 // An aggregate passed by value is decomposed into one argument per field by
384 // the target ABI, so the runtime is told about one object per field as well.
385 // Each of them keeps the map entry of the aggregate it came from.
387 for (auto [operand, converted] :
388 llvm::zip_equal(mappingOperands, convertedOperands)) {
389 auto structType = dyn_cast<LLVM::LLVMStructType>(converted.getType());
390 if (structType && !structType.isIdentified() &&
391 structType.getBody().size() > 1) {
392 for (unsigned field = 0, fields = structType.getBody().size();
393 field != fields; ++field)
394 mappedObjects.emplace_back(
395 operand,
396 LLVM::ExtractValueOp::create(rewriter, loc, converted, field));
397 continue;
398 }
399 mappedObjects.emplace_back(operand, converted);
400 }
401
402 runtimeArgs.argNum =
403 LLVM::ConstantOp::create(rewriter, loc, i32Ty, mappedObjects.size());
404
405 SmallVector<Value> bases;
406 SmallVector<Value> pointers;
407 SmallVector<Value> sizes;
408 SmallVector<Value> types;
409 SmallVector<Value> names;
410 SmallVector<Value> descriptors;
411 for (auto [operand, converted] : mappedObjects) {
412 Operation *mapOp = operand.getDefiningOp();
413 if (!mapOp || !isa<MapInfoOp, ACC_DATA_ENTRY_OPS>(mapOp))
414 return failure();
415 std::optional<MapFlags> mapFlags = computePackedMapFlags(mapOp);
416 if (!mapFlags)
417 return failure();
418 *mapFlags = config.postProcessMapFlags(mapOp, *mapFlags);
419 LLVM_DEBUG(llvm::dbgs() << "mapping " << *mapOp << "\n as "
420 << config.formatMapFlags(*mapFlags) << "\n");
421
422 Location mapLoc = mapOp->getLoc();
423 pointers.push_back(getMappedObjectPointer(mapLoc, operand, converted,
424 *mapFlags, rewriter));
425
426 Value base;
427 if (Value attach = acc::getVarPtrPtr(mapOp))
428 base = remap(attach, rewriter);
429 else if (bitEnumContainsAny(*mapFlags, MapFlags::ptr_and_obj))
430 base = remap(acc::getDesc(mapOp), rewriter);
431 // An object that only lives on the device has no host address to state as
432 // its base.
433 if (bitEnumContainsAny(*mapFlags, MapFlags::device_resident))
434 base = {};
435 bases.push_back(getPointer(mapLoc, base, rewriter));
436
437 // A local object that lives on the device is torn down when the region
438 // that declared it ends, which the runtime only does for a mapping that
439 // states it is deleted.
440 if (callKind == ACCDataCallKind::DataExit &&
441 bitEnumContainsAny(*mapFlags, MapFlags::device_resident)) {
442 Value var = acc::getVar(mapOp);
443 if (var &&
444 !isa_and_nonnull<AddressOfGlobalOpInterface>(var.getDefiningOp()))
445 *mapFlags = *mapFlags | MapFlags::delete_;
446 }
447
448 sizes.push_back(
449 getMapSize(mapOp, converted, *mapFlags, accSupport, rewriter));
450 types.push_back(constantI64(
451 mapLoc, config.getMapFlagsRuntimeValue(*mapFlags), rewriter));
452
453 // The runtime resolves an object that lives on the device against the
454 // symbols of the binary by this name, so it is the name the object is
455 // emitted under rather than the one the source spells.
456 VariableNameConfig nameConfig;
457 nameConfig.preferDemangledName = false;
458 std::string name = accSupport.getVariableName(operand, nameConfig);
459 if (name.empty()) {
460 names.push_back(LLVM::ZeroOp::create(rewriter, mapLoc, ptrTy));
461 } else {
462 names.push_back(getOrCreateGlobalString(
463 mapLoc, rewriter, getInternalGlobalName("var_name", name), name,
464 globalSymbolRegion, symbolTable));
465 }
466 descriptors.push_back(
467 createACCArgumentDescriptor(mapOp, converted, accSupport, rewriter));
468 }
469
470 runtimeArgs.argBasePtrs = createACCDataArray(loc, ptrTy, bases, rewriter);
471 runtimeArgs.argPtrs = createACCDataArray(loc, ptrTy, pointers, rewriter);
472 runtimeArgs.argSizes = createACCDataArray(loc, i64Ty, sizes, rewriter);
473 runtimeArgs.argTypes = createACCDataArray(loc, i64Ty, types, rewriter);
474 runtimeArgs.argNames = createACCDataArray(loc, ptrTy, names, rewriter);
475 runtimeArgs.argDescs = createACCDataArray(loc, ptrTy, descriptors, rewriter);
476 return success();
477}
static std::optional< MapFlags > computePackedMapFlags(Operation *mapOp)
static Value getMappedObjectPointer(Location loc, Value operand, Value converted, MapFlags mapFlags, ConversionPatternRewriter &rewriter)
The address of the mapped object, as the runtime expects to receive it.
static Value getBoundValue(Value value, Location loc, ConversionPatternRewriter &rewriter)
static Value getElementSize(Operation *mapOp, OpenACCSupport &accSupport, ConversionPatternRewriter &rewriter)
static Value remap(Value value, ConversionPatternRewriter &rewriter)
static Value getPointer(Location loc, Value value, ConversionPatternRewriter &rewriter)
static Value constantI64(Location loc, int64_t value, ConversionPatternRewriter &rewriter)
static Value getIndirectPointer(Location loc, Value value, ConversionPatternRewriter &rewriter)
Returns the address of a slot holding value, so that the runtime reads the value from memory rather t...
return success()
IntegerType getI32Type()
Definition Builders.cpp:71
MLIRContext * getContext() const
Definition Builders.h:56
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
Location getLoc()
The source location the operation was defined or derived from.
Definition Operation.h:240
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition Operation.h:255
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition Region.h:26
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
Definition SymbolTable.h:24
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
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
Location getLoc() const
Return the location of this value.
Definition Value.cpp:24
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Definition Value.cpp:18
Configuration for OpenACC to LLVM runtime lowering.
std::string formatMapFlags(MapFlags flags) const
Renders flags for a diagnostic as the names of the set bits and the decimal and hexadecimal encoding ...
int64_t getDeviceTypeRuntimeValue(DeviceType type) const
int64_t getMapFlagsRuntimeValue(MapFlags flags) const
MapFlags postProcessMapFlags(Operation *mapOp, MapFlags flags) const
std::string getVariableName(Value v, VariableNameConfig config={})
Get the variable name for a given value.
std::optional< int64_t > getMapElementSize(Operation *mapEntryOp)
Returns element size in bytes from acc.map_info, if present.
mlir::Value getVar(mlir::Operation *accDataClauseOp)
Used to obtain the var from a data clause operation.
Definition OpenACC.cpp:5368
MapFlags computeDataClauseMapFlags(Operation *entryOp, bool ptrAndObj)
Fold enter (+ paired exit) data-clause semantics into offload map flags.
mlir::SmallVector< mlir::Value > getBounds(mlir::Operation *accDataClauseOp)
Used to obtain bounds from an acc data clause operation.
Definition OpenACC.cpp:5419
LLVM::LLVMStructType getDataDescriptorType(MLIRContext *ctx, DataDescriptor desc, Type baseType={})
Builds the LLVM type of desc in ctx.
Value getMapSize(Operation *mapEntryOp)
Returns the optional size operand from acc.map_info, or null.
DataDescKind getDataDescriptorKind(DataDescriptor desc)
Returns the descriptor kind the runtime reads from the version field of desc.
Value createIdent(Location loc, StringRef functionName, OpBuilder &builder, Region &globalSymbolRegion, const ACCRuntimeCallConfig &config, SymbolTable *symbolTable=nullptr)
Returns a pointer to a constant global holding an ident_t for OpenACC runtime calls.
Value castPointerLikeTypeIfNeeded(OpBuilder &builder, Location loc, Value value, Type resultType)
Cast value to resultType via PointerLikeType::genCast when needed.
DataDescKind getDataDescKind(Operation *mapEntryOp)
Returns descriptor kind from acc.map_info, or none for other ops.
Value getDesc(Operation *mapEntryOp)
Returns descriptor value from acc.map_info.
mlir::Value getVarPtrPtr(mlir::Operation *accDataClauseOp)
Used to obtain the varPtrPtr from a data clause operation.
Definition OpenACC.cpp:5409
std::string getInternalGlobalName(StringRef kind, StringRef detail)
Returns the name to give a global that the conversion creates to hold detail of kind,...
StringRef getParentFunctionName(Operation *op)
Returns the symbol name of the function op belongs to, or of op itself when it is a function.
int64_t getDataDescriptorFieldIndex(FieldEnum field)
The index an insert or extract of field addresses.
Value castToI64(Location loc, Value value, OpBuilder &builder)
Sign-extends or truncates value to the i64 the runtime entry points take for values like queue number...
mlir::Type getVarType(mlir::Operation *accDataClauseOp)
Used to obtains the varType from a data clause operation which records the type of variable.
Definition OpenACC.cpp:5376
Value getOrCreateGlobalString(Location loc, OpBuilder &builder, StringRef name, StringRef value, Region &globalSymbolRegion, SymbolTable *symbolTable=nullptr)
Creates or reuses a null-terminated string global in globalSymbolRegion.
int64_t computeMapInfoSizeBytes(Value var, Type varType, DataDescKind descKind, ValueRange bounds, const DataLayout &dataLayout, OpenACCSupport *support=nullptr)
Compute total mapped byte size for acc.map_info.
bool hasAttachPoint(Operation *mapEntryOp)
Returns true when mapEntryOp carries an attach point (varPtrPtr).
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.
Value createACCDataArray(Location loc, Type elementType, ArrayRef< Value > values, RewriterBase &rewriter)
Materialize values as a stack-allocated LLVM array.
Value createACCDataDescriptor(Location loc, Value baseDescriptor, Type baseDescriptorType, uint32_t version, ValueRange bounds, Value elementSize, ConversionPatternRewriter &rewriter)
Wrap baseDescriptor in the OpenACC overlay that carries bounds.
ACCDataCallKind
Identifies how data runtime arguments will be consumed.
Value createACCArgumentDescriptor(Operation *mapOp, Value convertedOperand, acc::OpenACCSupport &accSupport, ConversionPatternRewriter &rewriter)
Build the runtime argument descriptor for mapOp, or a null pointer when the mapping needs no descript...
LogicalResult emitACCDataRuntimeArgs(Location loc, ValueRange mappingOperands, ValueRange convertedOperands, ConversionPatternRewriter &rewriter, Region &globalSymbolRegion, acc::OpenACCSupport &accSupport, const acc::ACCRuntimeCallConfig &config, ACCDataRuntimeArgs &runtimeArgs, ACCDataCallKind callKind=ACCDataCallKind::DataEnter, SymbolTable *symbolTable=nullptr)
Emit the OpenACC data runtime arguments for data-clause operands.
Value createACCMemRefDescriptorWrapperArg(Location loc, MemRefType memrefType, Value convertedMemref, ValueRange bounds, Value elementSize, ConversionPatternRewriter &rewriter)
Build the runtime argument descriptor wrapping an already converted memref.
The arguments every mapping entry point of the OpenACC runtime takes, in the order they are passed.
Value argNames
Array of variable names for runtime diagnostics, null where unknown.
Value deviceType
Device type the directive applies to, in the runtime encoding.
Value argSizes
Array of object sizes in bytes; zero where the descriptor or the bounds state the extent instead.
Value argMappers
Array of user-defined mappers. OpenACC has none, so this is always null.
Value ident
Source position and enclosing function name of the directive.
Value argTypes
Array of map-type flags, in the runtime encoding of acc::MapFlags.
SmallVector< Value > getCallArgs() const
Returns the fields above in the order the entry points take them, so that a caller only appends the a...
Value argBasePtrs
Array of pointer slots to attach a mapped object to, null when the object is not attached to anything...
Value argNum
Number of mapped objects, that is, the length of each array below.
Value argDescs
Array of descriptors stating layout and bounds, null for whole objects of a known size.
Value flags
Reserved for per-call runtime flags; no flag is defined yet.
Value argPtrs
Array of addresses of the mapped objects themselves.
How the name of a variable is to be rendered.
bool preferDemangledName
Render the name the source language spells, which is the name a message to the user states.