1 //===- OpenACC.h - MLIR OpenACC Dialect -------------------------*- C++ -*-===// 2 // 3 // Part of the MLIR 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 // This file declares the OpenACC dialect in MLIR. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef MLIR_DIALECT_OPENACC_OPENACC_H_ 14 #define MLIR_DIALECT_OPENACC_OPENACC_H_ 15 16 #include "mlir/IR/BuiltinTypes.h" 17 #include "mlir/IR/Dialect.h" 18 #include "mlir/IR/OpDefinition.h" 19 #include "mlir/IR/PatternMatch.h" 20 #include "mlir/IR/SymbolTable.h" 21 22 #include "mlir/Bytecode/BytecodeOpInterface.h" 23 #include "mlir/Dialect/OpenACC/OpenACCOpsDialect.h.inc" 24 #include "mlir/Dialect/OpenACC/OpenACCOpsEnums.h.inc" 25 #include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.h.inc" 26 #include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.h.inc" 27 #include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.h" 28 #include "mlir/IR/Value.h" 29 #include "mlir/Interfaces/ControlFlowInterfaces.h" 30 #include "mlir/Interfaces/LoopLikeInterface.h" 31 #include "mlir/Interfaces/SideEffectInterfaces.h" 32 33 #define GET_TYPEDEF_CLASSES 34 #include "mlir/Dialect/OpenACC/OpenACCOpsTypes.h.inc" 35 36 #define GET_ATTRDEF_CLASSES 37 #include "mlir/Dialect/OpenACC/OpenACCOpsAttributes.h.inc" 38 39 #include "mlir/Dialect/OpenACCMPCommon/Interfaces/OpenACCMPOpsInterfaces.h" 40 41 #define GET_OP_CLASSES 42 #include "mlir/Dialect/OpenACC/OpenACCOps.h.inc" 43 44 #define ACC_DATA_ENTRY_OPS \ 45 mlir::acc::CopyinOp, mlir::acc::CreateOp, mlir::acc::PresentOp, \ 46 mlir::acc::NoCreateOp, mlir::acc::AttachOp, mlir::acc::DevicePtrOp, \ 47 mlir::acc::GetDevicePtrOp, mlir::acc::PrivateOp, \ 48 mlir::acc::FirstprivateOp, mlir::acc::UpdateDeviceOp, \ 49 mlir::acc::UseDeviceOp, mlir::acc::ReductionOp, \ 50 mlir::acc::DeclareDeviceResidentOp, mlir::acc::DeclareLinkOp, \ 51 mlir::acc::CacheOp 52 #define ACC_DATA_EXIT_OPS \ 53 mlir::acc::CopyoutOp, mlir::acc::DeleteOp, mlir::acc::DetachOp, \ 54 mlir::acc::UpdateHostOp 55 #define ACC_DATA_CLAUSE_OPS ACC_DATA_ENTRY_OPS, ACC_DATA_EXIT_OPS 56 #define ACC_COMPUTE_CONSTRUCT_OPS \ 57 mlir::acc::ParallelOp, mlir::acc::KernelsOp, mlir::acc::SerialOp 58 #define ACC_COMPUTE_CONSTRUCT_AND_LOOP_OPS \ 59 ACC_COMPUTE_CONSTRUCT_OPS, mlir::acc::LoopOp 60 #define ACC_DATA_CONSTRUCT_STRUCTURED_OPS \ 61 mlir::acc::DataOp, mlir::acc::DeclareOp 62 #define ACC_DATA_CONSTRUCT_UNSTRUCTURED_OPS \ 63 mlir::acc::EnterDataOp, mlir::acc::ExitDataOp, mlir::acc::UpdateOp, \ 64 mlir::acc::HostDataOp, mlir::acc::DeclareEnterOp, \ 65 mlir::acc::DeclareExitOp 66 #define ACC_DATA_CONSTRUCT_OPS \ 67 ACC_DATA_CONSTRUCT_STRUCTURED_OPS, ACC_DATA_CONSTRUCT_UNSTRUCTURED_OPS 68 #define ACC_COMPUTE_AND_DATA_CONSTRUCT_OPS \ 69 ACC_COMPUTE_CONSTRUCT_OPS, ACC_DATA_CONSTRUCT_OPS 70 #define ACC_COMPUTE_LOOP_AND_DATA_CONSTRUCT_OPS \ 71 ACC_COMPUTE_CONSTRUCT_AND_LOOP_OPS, ACC_DATA_CONSTRUCT_OPS 72 73 namespace mlir { 74 namespace acc { 75 76 /// Enumeration used to encode the execution mapping on a loop construct. 77 /// They refer directly to the OpenACC 3.3 standard: 78 /// 2.9.2. gang 79 /// 2.9.3. worker 80 /// 2.9.4. vector 81 /// 82 /// Value can be combined bitwise to reflect the mapping applied to the 83 /// construct. e.g. `acc.loop gang vector`, the `gang` and `vector` could be 84 /// combined and the final mapping value would be 5 (4 | 1). 85 enum OpenACCExecMapping { NONE = 0, VECTOR = 1, WORKER = 2, GANG = 4 }; 86 87 /// Used to obtain the `var` from a data clause operation. 88 /// Returns empty value if not a data clause operation or is a data exit 89 /// operation with no `var`. 90 mlir::Value getVar(mlir::Operation *accDataClauseOp); 91 92 /// Used to obtain the `var` from a data clause operation if it implements 93 /// `PointerLikeType`. 94 mlir::TypedValue<mlir::acc::PointerLikeType> 95 getVarPtr(mlir::Operation *accDataClauseOp); 96 97 /// Used to obtains the `varType` from a data clause operation which records 98 /// the type of variable. When `var` is `PointerLikeType`, this returns 99 /// the type of the pointer target. 100 mlir::Type getVarType(mlir::Operation *accDataClauseOp); 101 102 /// Used to obtain the `accVar` from a data clause operation. 103 /// When a data entry operation, it obtains its result `accVar` value. 104 /// If a data exit operation, it obtains its operand `accVar` value. 105 /// Returns empty value if not a data clause operation. 106 mlir::Value getAccVar(mlir::Operation *accDataClauseOp); 107 108 /// Used to obtain the `accVar` from a data clause operation if it implements 109 /// `PointerLikeType`. 110 mlir::TypedValue<mlir::acc::PointerLikeType> 111 getAccPtr(mlir::Operation *accDataClauseOp); 112 113 /// Used to obtain the `varPtrPtr` from a data clause operation. 114 /// Returns empty value if not a data clause operation. 115 mlir::Value getVarPtrPtr(mlir::Operation *accDataClauseOp); 116 117 /// Used to obtain `bounds` from an acc data clause operation. 118 /// Returns an empty vector if there are no bounds. 119 mlir::SmallVector<mlir::Value> getBounds(mlir::Operation *accDataClauseOp); 120 121 /// Used to obtain `async` operands from an acc data clause operation. 122 /// Returns an empty vector if there are no such operands. 123 mlir::SmallVector<mlir::Value> 124 getAsyncOperands(mlir::Operation *accDataClauseOp); 125 126 /// Returns an array of acc:DeviceTypeAttr attributes attached to 127 /// an acc data clause operation, that correspond to the device types 128 /// associated with the async clauses with an async-value. 129 mlir::ArrayAttr getAsyncOperandsDeviceType(mlir::Operation *accDataClauseOp); 130 131 /// Returns an array of acc:DeviceTypeAttr attributes attached to 132 /// an acc data clause operation, that correspond to the device types 133 /// associated with the async clauses without an async-value. 134 mlir::ArrayAttr getAsyncOnly(mlir::Operation *accDataClauseOp); 135 136 /// Used to obtain the `name` from an acc operation. 137 std::optional<llvm::StringRef> getVarName(mlir::Operation *accOp); 138 139 /// Used to obtain the `dataClause` from a data entry operation. 140 /// Returns empty optional if not a data entry operation. 141 std::optional<mlir::acc::DataClause> 142 getDataClause(mlir::Operation *accDataEntryOp); 143 144 /// Used to find out whether data operation is implicit. 145 /// Returns false if not a data operation or if it is a data operation without 146 /// implicit flag. 147 bool getImplicitFlag(mlir::Operation *accDataEntryOp); 148 149 /// Used to get an immutable range iterating over the data operands. 150 mlir::ValueRange getDataOperands(mlir::Operation *accOp); 151 152 /// Used to get a mutable range iterating over the data operands. 153 mlir::MutableOperandRange getMutableDataOperands(mlir::Operation *accOp); 154 155 /// Used to check whether the provided `type` implements the `PointerLikeType` 156 /// interface. 157 inline bool isPointerLikeType(mlir::Type type) { 158 return mlir::isa<mlir::acc::PointerLikeType>(type); 159 } 160 161 /// Used to check whether the provided `type` implements the `MappableType` 162 /// interface. 163 inline bool isMappableType(mlir::Type type) { 164 return mlir::isa<mlir::acc::MappableType>(type); 165 } 166 167 /// Used to obtain the attribute name for declare. 168 static constexpr StringLiteral getDeclareAttrName() { 169 return StringLiteral("acc.declare"); 170 } 171 172 static constexpr StringLiteral getDeclareActionAttrName() { 173 return StringLiteral("acc.declare_action"); 174 } 175 176 static constexpr StringLiteral getRoutineInfoAttrName() { 177 return StringLiteral("acc.routine_info"); 178 } 179 180 static constexpr StringLiteral getCombinedConstructsAttrName() { 181 return CombinedConstructsTypeAttr::name; 182 } 183 184 struct RuntimeCounters 185 : public mlir::SideEffects::Resource::Base<RuntimeCounters> { 186 mlir::StringRef getName() final { return "AccRuntimeCounters"; } 187 }; 188 189 struct ConstructResource 190 : public mlir::SideEffects::Resource::Base<ConstructResource> { 191 mlir::StringRef getName() final { return "AccConstructResource"; } 192 }; 193 194 struct CurrentDeviceIdResource 195 : public mlir::SideEffects::Resource::Base<CurrentDeviceIdResource> { 196 mlir::StringRef getName() final { return "AccCurrentDeviceIdResource"; } 197 }; 198 199 } // namespace acc 200 } // namespace mlir 201 202 #endif // MLIR_DIALECT_OPENACC_OPENACC_H_ 203