//===- OpenACCUtils.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "mlir/Dialect/OpenACC/OpenACCUtils.h" #include "mlir/Dialect/OpenACC/OpenACC.h" #include "llvm/ADT/TypeSwitch.h" mlir::Operation *mlir::acc::getEnclosingComputeOp(mlir::Region ®ion) { mlir::Operation *parentOp = region.getParentOp(); while (parentOp) { if (mlir::isa(parentOp)) return parentOp; parentOp = parentOp->getParentOp(); } return nullptr; } template static bool isOnlyUsedByOpClauses(mlir::Value val, mlir::Region ®ion) { auto checkIfUsedOnlyByOpInside = [&](mlir::Operation *user) { // For any users which are not in the current acc region, we can ignore. // Return true so that it can be used in a `all_of` check. if (!region.isAncestor(user->getParentRegion())) return true; return mlir::isa(user); }; return llvm::all_of(val.getUsers(), checkIfUsedOnlyByOpInside); } bool mlir::acc::isOnlyUsedByPrivateClauses(mlir::Value val, mlir::Region ®ion) { return isOnlyUsedByOpClauses(val, region); } bool mlir::acc::isOnlyUsedByReductionClauses(mlir::Value val, mlir::Region ®ion) { return isOnlyUsedByOpClauses(val, region); } std::optional mlir::acc::getDefaultAttr(Operation *op) { std::optional defaultAttr; Operation *currOp = op; // Iterate outwards until a default clause is found (since OpenACC // specification notes that a visible default clause is the nearest default // clause appearing on the compute construct or a lexically containing data // construct. while (!defaultAttr.has_value() && currOp) { defaultAttr = llvm::TypeSwitch>(currOp) .Case( [&](auto op) { return op.getDefaultAttr(); }) .Default([&](Operation *) { return std::nullopt; }); currOp = currOp->getParentOp(); } return defaultAttr; } mlir::acc::VariableTypeCategory mlir::acc::getTypeCategory(mlir::Value var) { mlir::acc::VariableTypeCategory typeCategory = mlir::acc::VariableTypeCategory::uncategorized; if (auto mappableTy = dyn_cast(var.getType())) typeCategory = mappableTy.getTypeCategory(var); else if (auto pointerLikeTy = dyn_cast(var.getType())) typeCategory = pointerLikeTy.getPointeeTypeCategory( cast>(var), pointerLikeTy.getElementType()); return typeCategory; }