brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 9501b0e Raw
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