172 lines · cpp
1//===-- lib/Support/Fortran.cpp ---------------------------------*- C++ -*-===//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#include "flang/Support/Fortran.h"10#include "flang/Support/Fortran-features.h"11 12namespace Fortran::common {13 14const char *AsFortran(NumericOperator opr) {15 switch (opr) {16 SWITCH_COVERS_ALL_CASES17 case NumericOperator::Power:18 return "**";19 case NumericOperator::Multiply:20 return "*";21 case NumericOperator::Divide:22 return "/";23 case NumericOperator::Add:24 return "+";25 case NumericOperator::Subtract:26 return "-";27 }28}29 30const char *AsFortran(LogicalOperator opr) {31 switch (opr) {32 SWITCH_COVERS_ALL_CASES33 case LogicalOperator::And:34 return ".and.";35 case LogicalOperator::Or:36 return ".or.";37 case LogicalOperator::Eqv:38 return ".eqv.";39 case LogicalOperator::Neqv:40 return ".neqv.";41 case LogicalOperator::Not:42 return ".not.";43 }44}45 46const char *AsFortran(RelationalOperator opr) {47 switch (opr) {48 SWITCH_COVERS_ALL_CASES49 case RelationalOperator::LT:50 return "<";51 case RelationalOperator::LE:52 return "<=";53 case RelationalOperator::EQ:54 return "==";55 case RelationalOperator::NE:56 return "/=";57 case RelationalOperator::GE:58 return ">=";59 case RelationalOperator::GT:60 return ">";61 }62}63 64const char *AsFortran(DefinedIo x) {65 switch (x) {66 SWITCH_COVERS_ALL_CASES67 case DefinedIo::ReadFormatted:68 return "read(formatted)";69 case DefinedIo::ReadUnformatted:70 return "read(unformatted)";71 case DefinedIo::WriteFormatted:72 return "write(formatted)";73 case DefinedIo::WriteUnformatted:74 return "write(unformatted)";75 }76}77 78std::string AsFortran(IgnoreTKRSet tkr) {79 std::string result;80 if (tkr.test(IgnoreTKR::Type)) {81 result += 'T';82 }83 if (tkr.test(IgnoreTKR::Kind)) {84 result += 'K';85 }86 if (tkr.test(IgnoreTKR::Rank)) {87 result += 'R';88 }89 if (tkr.test(IgnoreTKR::Device)) {90 result += 'D';91 }92 if (tkr.test(IgnoreTKR::Managed)) {93 result += 'M';94 }95 if (tkr.test(IgnoreTKR::Contiguous)) {96 result += 'C';97 }98 if (tkr.test(IgnoreTKR::Pointer)) {99 result += 'P';100 }101 return result;102}103 104/// Check compatibilty of CUDA attribute.105/// When `allowUnifiedMatchingRule` is enabled, argument `x` represents the106/// dummy argument attribute while `y` represents the actual argument attribute.107bool AreCompatibleCUDADataAttrs(std::optional<CUDADataAttr> x,108 std::optional<CUDADataAttr> y, IgnoreTKRSet ignoreTKR,109 bool allowUnifiedMatchingRule, bool isHostDeviceProcedure,110 const LanguageFeatureControl *features) {111 bool isCudaManaged{features112 ? features->IsEnabled(common::LanguageFeature::CudaManaged)113 : false};114 bool isCudaUnified{features115 ? features->IsEnabled(common::LanguageFeature::CudaUnified)116 : false};117 if (ignoreTKR.test(common::IgnoreTKR::Device)) {118 return true;119 }120 if (!y && isHostDeviceProcedure) {121 return true;122 }123 if (!x && !y) {124 return true;125 } else if (x && y && *x == *y) {126 return true;127 } else if ((!x && y && *y == CUDADataAttr::Pinned) ||128 (x && *x == CUDADataAttr::Pinned && !y)) {129 return true;130 } else if (ignoreTKR.test(IgnoreTKR::Device) &&131 x.value_or(CUDADataAttr::Device) == CUDADataAttr::Device &&132 y.value_or(CUDADataAttr::Device) == CUDADataAttr::Device) {133 return true;134 } else if (ignoreTKR.test(IgnoreTKR::Managed) &&135 x.value_or(CUDADataAttr::Managed) == CUDADataAttr::Managed &&136 y.value_or(CUDADataAttr::Managed) == CUDADataAttr::Managed) {137 return true;138 } else if (allowUnifiedMatchingRule) {139 if (!x) { // Dummy argument has no attribute -> host140 if ((y && (*y == CUDADataAttr::Managed || *y == CUDADataAttr::Unified)) ||141 (!y && (isCudaUnified || isCudaManaged))) {142 return true;143 }144 } else {145 if (*x == CUDADataAttr::Device) {146 if ((y &&147 (*y == CUDADataAttr::Managed || *y == CUDADataAttr::Unified ||148 *y == CUDADataAttr::Shared ||149 *y == CUDADataAttr::Constant)) ||150 (!y && (isCudaUnified || isCudaManaged))) {151 return true;152 }153 } else if (*x == CUDADataAttr::Managed) {154 if ((y && *y == CUDADataAttr::Unified) ||155 (!y && (isCudaUnified || isCudaManaged))) {156 return true;157 }158 } else if (*x == CUDADataAttr::Unified) {159 if ((y && *y == CUDADataAttr::Managed) ||160 (!y && (isCudaUnified || isCudaManaged))) {161 return true;162 }163 }164 }165 return false;166 } else {167 return false;168 }169}170 171} // namespace Fortran::common172