xref: /llvm-project/flang/lib/Common/Fortran.cpp (revision 3874c64418d2a7e36eab9af9253d905b48b36078)
164ab3302SCarolineConcatto //===-- lib/Common/Fortran.cpp --------------------------------------------===//
264ab3302SCarolineConcatto //
364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information.
564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
664ab3302SCarolineConcatto //
764ab3302SCarolineConcatto //===----------------------------------------------------------------------===//
864ab3302SCarolineConcatto 
964ab3302SCarolineConcatto #include "flang/Common/Fortran.h"
10e8eb52d1SValentin Clement (バレンタイン クレメン) #include "flang/Common/Fortran-features.h"
1164ab3302SCarolineConcatto 
1264ab3302SCarolineConcatto namespace Fortran::common {
1364ab3302SCarolineConcatto 
1464ab3302SCarolineConcatto const char *AsFortran(NumericOperator opr) {
1564ab3302SCarolineConcatto   switch (opr) {
1664ab3302SCarolineConcatto     SWITCH_COVERS_ALL_CASES
171f879005STim Keith   case NumericOperator::Power:
181f879005STim Keith     return "**";
191f879005STim Keith   case NumericOperator::Multiply:
201f879005STim Keith     return "*";
211f879005STim Keith   case NumericOperator::Divide:
221f879005STim Keith     return "/";
231f879005STim Keith   case NumericOperator::Add:
241f879005STim Keith     return "+";
251f879005STim Keith   case NumericOperator::Subtract:
261f879005STim Keith     return "-";
2764ab3302SCarolineConcatto   }
2864ab3302SCarolineConcatto }
2964ab3302SCarolineConcatto 
3064ab3302SCarolineConcatto const char *AsFortran(LogicalOperator opr) {
3164ab3302SCarolineConcatto   switch (opr) {
3264ab3302SCarolineConcatto     SWITCH_COVERS_ALL_CASES
331f879005STim Keith   case LogicalOperator::And:
341f879005STim Keith     return ".and.";
351f879005STim Keith   case LogicalOperator::Or:
361f879005STim Keith     return ".or.";
371f879005STim Keith   case LogicalOperator::Eqv:
381f879005STim Keith     return ".eqv.";
391f879005STim Keith   case LogicalOperator::Neqv:
401f879005STim Keith     return ".neqv.";
411f879005STim Keith   case LogicalOperator::Not:
421f879005STim Keith     return ".not.";
4364ab3302SCarolineConcatto   }
4464ab3302SCarolineConcatto }
4564ab3302SCarolineConcatto 
4664ab3302SCarolineConcatto const char *AsFortran(RelationalOperator opr) {
4764ab3302SCarolineConcatto   switch (opr) {
4864ab3302SCarolineConcatto     SWITCH_COVERS_ALL_CASES
491f879005STim Keith   case RelationalOperator::LT:
501f879005STim Keith     return "<";
511f879005STim Keith   case RelationalOperator::LE:
521f879005STim Keith     return "<=";
531f879005STim Keith   case RelationalOperator::EQ:
541f879005STim Keith     return "==";
551f879005STim Keith   case RelationalOperator::NE:
561f879005STim Keith     return "/=";
571f879005STim Keith   case RelationalOperator::GE:
581f879005STim Keith     return ">=";
591f879005STim Keith   case RelationalOperator::GT:
601f879005STim Keith     return ">";
6164ab3302SCarolineConcatto   }
6264ab3302SCarolineConcatto }
6364ab3302SCarolineConcatto 
647cf1608bSPeter Klausler const char *AsFortran(DefinedIo x) {
657cf1608bSPeter Klausler   switch (x) {
667cf1608bSPeter Klausler     SWITCH_COVERS_ALL_CASES
677cf1608bSPeter Klausler   case DefinedIo::ReadFormatted:
687cf1608bSPeter Klausler     return "read(formatted)";
697cf1608bSPeter Klausler   case DefinedIo::ReadUnformatted:
707cf1608bSPeter Klausler     return "read(unformatted)";
717cf1608bSPeter Klausler   case DefinedIo::WriteFormatted:
727cf1608bSPeter Klausler     return "write(formatted)";
737cf1608bSPeter Klausler   case DefinedIo::WriteUnformatted:
747cf1608bSPeter Klausler     return "write(unformatted)";
757cf1608bSPeter Klausler   }
767cf1608bSPeter Klausler }
777cf1608bSPeter Klausler 
78864cb2aaSPeter Klausler std::string AsFortran(IgnoreTKRSet tkr) {
79864cb2aaSPeter Klausler   std::string result;
80864cb2aaSPeter Klausler   if (tkr.test(IgnoreTKR::Type)) {
81864cb2aaSPeter Klausler     result += 'T';
82864cb2aaSPeter Klausler   }
83864cb2aaSPeter Klausler   if (tkr.test(IgnoreTKR::Kind)) {
84864cb2aaSPeter Klausler     result += 'K';
85864cb2aaSPeter Klausler   }
86864cb2aaSPeter Klausler   if (tkr.test(IgnoreTKR::Rank)) {
87864cb2aaSPeter Klausler     result += 'R';
88864cb2aaSPeter Klausler   }
89864cb2aaSPeter Klausler   if (tkr.test(IgnoreTKR::Device)) {
90864cb2aaSPeter Klausler     result += 'D';
91864cb2aaSPeter Klausler   }
92864cb2aaSPeter Klausler   if (tkr.test(IgnoreTKR::Managed)) {
93864cb2aaSPeter Klausler     result += 'M';
94864cb2aaSPeter Klausler   }
95864cb2aaSPeter Klausler   if (tkr.test(IgnoreTKR::Contiguous)) {
96864cb2aaSPeter Klausler     result += 'C';
97864cb2aaSPeter Klausler   }
98864cb2aaSPeter Klausler   return result;
99864cb2aaSPeter Klausler }
100864cb2aaSPeter Klausler 
1013e930864SValentin Clement /// Check compatibilty of CUDA attribute.
1023e930864SValentin Clement /// When `allowUnifiedMatchingRule` is enabled, argument `x` represents the
1033e930864SValentin Clement /// dummy argument attribute while `y` represents the actual argument attribute.
1044ad72793SPeter Klausler bool AreCompatibleCUDADataAttrs(std::optional<CUDADataAttr> x,
1053e930864SValentin Clement     std::optional<CUDADataAttr> y, IgnoreTKRSet ignoreTKR,
10630d80009SValentin Clement (バレンタイン クレメン)     std::optional<std::string> *warning, bool allowUnifiedMatchingRule,
10730d80009SValentin Clement (バレンタイン クレメン)     const LanguageFeatureControl *features) {
108e8eb52d1SValentin Clement (バレンタイン クレメン)   bool isCudaManaged{features
109e8eb52d1SValentin Clement (バレンタイン クレメン)           ? features->IsEnabled(common::LanguageFeature::CudaManaged)
110e8eb52d1SValentin Clement (バレンタイン クレメン)           : false};
111e8eb52d1SValentin Clement (バレンタイン クレメン)   bool isCudaUnified{features
112e8eb52d1SValentin Clement (バレンタイン クレメン)           ? features->IsEnabled(common::LanguageFeature::CudaUnified)
113e8eb52d1SValentin Clement (バレンタイン クレメン)           : false};
1144ad72793SPeter Klausler   if (!x && !y) {
1154ad72793SPeter Klausler     return true;
1164ad72793SPeter Klausler   } else if (x && y && *x == *y) {
1174ad72793SPeter Klausler     return true;
11889f83358SValentin Clement (バレンタイン クレメン)   } else if ((!x && y && *y == CUDADataAttr::Pinned) ||
11989f83358SValentin Clement (バレンタイン クレメン)       (x && *x == CUDADataAttr::Pinned && !y)) {
12089f83358SValentin Clement (バレンタイン クレメン)     return true;
1214ad72793SPeter Klausler   } else if (ignoreTKR.test(IgnoreTKR::Device) &&
1224ad72793SPeter Klausler       x.value_or(CUDADataAttr::Device) == CUDADataAttr::Device &&
1234ad72793SPeter Klausler       y.value_or(CUDADataAttr::Device) == CUDADataAttr::Device) {
1244ad72793SPeter Klausler     return true;
1254ad72793SPeter Klausler   } else if (ignoreTKR.test(IgnoreTKR::Managed) &&
1264ad72793SPeter Klausler       x.value_or(CUDADataAttr::Managed) == CUDADataAttr::Managed &&
1274ad72793SPeter Klausler       y.value_or(CUDADataAttr::Managed) == CUDADataAttr::Managed) {
1284ad72793SPeter Klausler     return true;
1293e930864SValentin Clement   } else if (allowUnifiedMatchingRule) {
1303e930864SValentin Clement     if (!x) { // Dummy argument has no attribute -> host
131e8eb52d1SValentin Clement (バレンタイン クレメン)       if ((y && (*y == CUDADataAttr::Managed || *y == CUDADataAttr::Unified)) ||
132e8eb52d1SValentin Clement (バレンタイン クレメン)           (!y && (isCudaUnified || isCudaManaged))) {
1333e930864SValentin Clement         return true;
1343e930864SValentin Clement       }
1353e930864SValentin Clement     } else {
136e8eb52d1SValentin Clement (バレンタイン クレメン)       if (*x == CUDADataAttr::Device) {
137e8eb52d1SValentin Clement (バレンタイン クレメン)         if ((y &&
13830d80009SValentin Clement (バレンタイン クレメン)                 (*y == CUDADataAttr::Managed || *y == CUDADataAttr::Unified ||
139*3874c644SValentin Clement (バレンタイン クレメン)                     *y == CUDADataAttr::Shared ||
140*3874c644SValentin Clement (バレンタイン クレメン)                     *y == CUDADataAttr::Constant)) ||
141e8eb52d1SValentin Clement (バレンタイン クレメン)             (!y && (isCudaUnified || isCudaManaged))) {
14230d80009SValentin Clement (バレンタイン クレメン)           if (y && *y == CUDADataAttr::Shared && warning) {
14330d80009SValentin Clement (バレンタイン クレメン)             *warning = "SHARED attribute ignored"s;
14430d80009SValentin Clement (バレンタイン クレメン)           }
1453e930864SValentin Clement           return true;
146e8eb52d1SValentin Clement (バレンタイン クレメン)         }
147e8eb52d1SValentin Clement (バレンタイン クレメン)       } else if (*x == CUDADataAttr::Managed) {
148e8eb52d1SValentin Clement (バレンタイン クレメン)         if ((y && *y == CUDADataAttr::Unified) ||
149e8eb52d1SValentin Clement (バレンタイン クレメン)             (!y && (isCudaUnified || isCudaManaged))) {
1503e930864SValentin Clement           return true;
151e8eb52d1SValentin Clement (バレンタイン クレメン)         }
152e8eb52d1SValentin Clement (バレンタイン クレメン)       } else if (*x == CUDADataAttr::Unified) {
153e8eb52d1SValentin Clement (バレンタイン クレメン)         if ((y && *y == CUDADataAttr::Managed) ||
154e8eb52d1SValentin Clement (バレンタイン クレメン)             (!y && (isCudaUnified || isCudaManaged))) {
1553e930864SValentin Clement           return true;
1563e930864SValentin Clement         }
1573e930864SValentin Clement       }
158e8eb52d1SValentin Clement (バレンタイン クレメン)     }
1593e930864SValentin Clement     return false;
1604ad72793SPeter Klausler   } else {
1614ad72793SPeter Klausler     return false;
1624ad72793SPeter Klausler   }
1634ad72793SPeter Klausler }
1644ad72793SPeter Klausler 
1651f879005STim Keith } // namespace Fortran::common
166