94 lines · cpp
1//===-- CUDA.cpp -- CUDA Fortran specific lowering ------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/10//11//===----------------------------------------------------------------------===//12 13#include "flang/Lower/CUDA.h"14#include "flang/Lower/AbstractConverter.h"15#include "flang/Optimizer/Builder/Todo.h"16#include "flang/Optimizer/HLFIR/HLFIROps.h"17 18#define DEBUG_TYPE "flang-lower-cuda"19 20mlir::Type Fortran::lower::gatherDeviceComponentCoordinatesAndType(21 fir::FirOpBuilder &builder, mlir::Location loc,22 const Fortran::semantics::Symbol &sym, fir::RecordType recTy,23 llvm::SmallVector<mlir::Value> &coordinates) {24 unsigned fieldIdx = recTy.getFieldIndex(sym.name().ToString());25 mlir::Type fieldTy;26 if (fieldIdx != std::numeric_limits<unsigned>::max()) {27 // Field found in the base record type.28 auto fieldName = recTy.getTypeList()[fieldIdx].first;29 fieldTy = recTy.getTypeList()[fieldIdx].second;30 mlir::Value fieldIndex = fir::FieldIndexOp::create(31 builder, loc, fir::FieldType::get(fieldTy.getContext()), fieldName,32 recTy,33 /*typeParams=*/mlir::ValueRange{});34 coordinates.push_back(fieldIndex);35 } else {36 // Field not found in base record type, search in potential37 // record type components.38 for (auto component : recTy.getTypeList()) {39 if (auto childRecTy = mlir::dyn_cast<fir::RecordType>(component.second)) {40 fieldIdx = childRecTy.getFieldIndex(sym.name().ToString());41 if (fieldIdx != std::numeric_limits<unsigned>::max()) {42 mlir::Value parentFieldIndex = fir::FieldIndexOp::create(43 builder, loc, fir::FieldType::get(childRecTy.getContext()),44 component.first, recTy,45 /*typeParams=*/mlir::ValueRange{});46 coordinates.push_back(parentFieldIndex);47 auto fieldName = childRecTy.getTypeList()[fieldIdx].first;48 fieldTy = childRecTy.getTypeList()[fieldIdx].second;49 mlir::Value childFieldIndex = fir::FieldIndexOp::create(50 builder, loc, fir::FieldType::get(fieldTy.getContext()),51 fieldName, childRecTy,52 /*typeParams=*/mlir::ValueRange{});53 coordinates.push_back(childFieldIndex);54 break;55 }56 }57 }58 }59 if (coordinates.empty())60 TODO(loc, "device resident component in complex derived-type hierarchy");61 return fieldTy;62}63 64cuf::DataAttributeAttr Fortran::lower::translateSymbolCUFDataAttribute(65 mlir::MLIRContext *mlirContext, const Fortran::semantics::Symbol &sym) {66 std::optional<Fortran::common::CUDADataAttr> cudaAttr =67 Fortran::semantics::GetCUDADataAttr(&sym.GetUltimate());68 return cuf::getDataAttribute(mlirContext, cudaAttr);69}70 71hlfir::ElementalOp Fortran::lower::isTransferWithConversion(mlir::Value rhs) {72 auto isConversionElementalOp = [](hlfir::ElementalOp elOp) {73 return llvm::hasSingleElement(74 elOp.getBody()->getOps<hlfir::DesignateOp>()) &&75 llvm::hasSingleElement(elOp.getBody()->getOps<fir::LoadOp>()) == 1 &&76 llvm::hasSingleElement(elOp.getBody()->getOps<fir::ConvertOp>()) ==77 1;78 };79 if (auto declOp = mlir::dyn_cast<hlfir::DeclareOp>(rhs.getDefiningOp())) {80 if (!declOp.getMemref().getDefiningOp())81 return {};82 if (auto associateOp = mlir::dyn_cast<hlfir::AssociateOp>(83 declOp.getMemref().getDefiningOp()))84 if (auto elOp = mlir::dyn_cast<hlfir::ElementalOp>(85 associateOp.getSource().getDefiningOp()))86 if (isConversionElementalOp(elOp))87 return elOp;88 }89 if (auto elOp = mlir::dyn_cast<hlfir::ElementalOp>(rhs.getDefiningOp()))90 if (isConversionElementalOp(elOp))91 return elOp;92 return {};93}94