1//===- TestOpenACCInterfaces.cpp ------------------------------------------===//
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#include "mlir/Dialect/Arith/IR/Arith.h"
10#include "mlir/Dialect/DLTI/DLTI.h"
11#include "mlir/Dialect/OpenACC/OpenACC.h"
12#include "mlir/IR/Builders.h"
13#include "mlir/IR/BuiltinOps.h"
14#include "mlir/Pass/Pass.h"
15#include "mlir/Support/LLVM.h"
16#include "flang/Optimizer/Dialect/FIRDialect.h"
17#include "flang/Optimizer/HLFIR/HLFIRDialect.h"
18#include "flang/Optimizer/Support/DataLayout.h"
19
20using namespace mlir;
21
22namespace {
23
24struct TestFIROpenACCInterfaces
25 : public PassWrapper<TestFIROpenACCInterfaces, OperationPass<ModuleOp>> {
26 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestFIROpenACCInterfaces)
27
28 StringRef getArgument() const final { return "test-fir-openacc-interfaces"; }
29 StringRef getDescription() const final {
30 return "Test FIR implementation of the OpenACC interfaces.";
31 }
32 void getDependentDialects(::mlir::DialectRegistry &registry) const override {
33 registry.insert<fir::FIROpsDialect, hlfir::hlfirDialect,
34 mlir::arith::ArithDialect, mlir::acc::OpenACCDialect,
35 mlir::DLTIDialect>();
36 }
37 void runOnOperation() override {
38 mlir::ModuleOp mod = getOperation();
39 auto datalayout =
40 fir::support::getOrSetMLIRDataLayout(mod, /*allowDefaultLayout=*/true);
41 mlir::OpBuilder builder(mod);
42 getOperation().walk([&](Operation *op) {
43 if (isa<ACC_DATA_ENTRY_OPS>(op)) {
44 Value var = acc::getVar(op);
45 Type typeOfVar = var.getType();
46
47 // Attempt to determine if the variable is mappable-like or if
48 // the pointee itself is mappable-like. For example, if the variable is
49 // of type !fir.ref<!fir.box<>>, we want to print both the details about
50 // the !fir.ref since it is pointer-like, and about !fir.box since it
51 // is mappable.
52 auto mappableTy = dyn_cast_if_present<acc::MappableType>(typeOfVar);
53 if (!mappableTy) {
54 mappableTy =
55 dyn_cast_if_present<acc::MappableType>(acc::getVarType(op));
56 }
57
58 llvm::errs() << "Visiting: " << *op << "\n";
59 llvm::errs() << "\tVar: " << var << "\n";
60
61 if (mlir::isa<acc::PointerLikeType>(typeOfVar) &&
62 mlir::isa<acc::MappableType>(typeOfVar)) {
63 llvm::errs() << "\tPointer-like and Mappable: " << typeOfVar << "\n";
64 } else if (mlir::isa<acc::PointerLikeType>(typeOfVar)) {
65 llvm::errs() << "\tPointer-like: " << typeOfVar << "\n";
66 } else {
67 assert(
68 mlir::isa<acc::MappableType>(typeOfVar) && "expected mappable");
69 llvm::errs() << "\tMappable: " << typeOfVar << "\n";
70 }
71
72 if (auto ptrTy = dyn_cast_if_present<acc::PointerLikeType>(typeOfVar)) {
73 // If the pointee is not mappable, print details about it. Otherwise,
74 // we defer to the mappable printing below to print those details.
75 if (!mappableTy) {
76 acc::VariableTypeCategory typeCategory =
77 ptrTy.getPointeeTypeCategory(
78 cast<TypedValue<acc::PointerLikeType>>(var),
79 acc::getVarType(op));
80 llvm::errs() << "\t\tType category: " << typeCategory << "\n";
81 }
82 }
83
84 if (mappableTy) {
85 acc::VariableTypeCategory typeCategory =
86 mappableTy.getTypeCategory(var);
87 llvm::errs() << "\t\tType category: " << typeCategory << "\n";
88
89 if (datalayout.has_value()) {
90 auto size = mappableTy.getSizeInBytes(
91 acc::getVar(op), acc::getBounds(op), datalayout.value());
92 if (size) {
93 llvm::errs() << "\t\tSize: " << size.value() << "\n";
94 }
95 auto offset = mappableTy.getOffsetInBytes(
96 acc::getVar(op), acc::getBounds(op), datalayout.value());
97 if (offset) {
98 llvm::errs() << "\t\tOffset: " << offset.value() << "\n";
99 }
100 }
101
102 builder.setInsertionPoint(op);
103 auto bounds = mappableTy.generateAccBounds(acc::getVar(op), builder);
104 if (!bounds.empty()) {
105 for (auto [idx, bound] : llvm::enumerate(bounds)) {
106 llvm::errs() << "\t\tBound[" << idx << "]: " << bound << "\n";
107 }
108 }
109 }
110 }
111 });
112 }
113};
114} // namespace
115
116//===----------------------------------------------------------------------===//
117// Pass Registration
118//===----------------------------------------------------------------------===//
119
120namespace fir {
121namespace test {
122void registerTestFIROpenACCInterfacesPass() {
123 PassRegistration<TestFIROpenACCInterfaces>();
124}
125} // namespace test
126} // namespace fir
127

source code of flang/test/lib/OpenACC/TestOpenACCInterfaces.cpp